diff options
author | no author <devnull@mit.edu> | 2000-04-25 21:05:56 +0000 |
---|---|---|
committer | no author <devnull@mit.edu> | 2000-04-25 21:05:56 +0000 |
commit | 1a8cf6a0c0e97153a6951be2aac5700e17cb66b6 (patch) | |
tree | 2657a81f311ad15f55b7cea512159a4daaf082c9 | |
parent | 4a2449d55d3527a8ed9ef73de83cba2ae149094b (diff) | |
download | krb5-krb5-1.2-beta1.zip krb5-krb5-1.2-beta1.tar.gz krb5-krb5-1.2-beta1.tar.bz2 |
This commit was manufactured by cvs2svn to create tagkrb5-1.2-beta1
'krb5-1-2-beta1'.
git-svn-id: svn://anonsvn.mit.edu/krb5/tags/krb5-1-2-beta1@12195 dc483132-0cff-0310-8789-dd5450dbe970
55 files changed, 1519 insertions, 2273 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 25737d4..f4b1ace 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,30 @@ +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_AC_ENABLE_DNS): Set RESOLV_LIB, and substitute + it into the Makefile. + (AC_LIBRARY_NET): Set RESOLV_LIB. + +2000-04-18 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in (clean-windows): Actually clean gss-sample on Windows. + +2000-04-11 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in (clean-windows): Clean gss-sample on Windows. + +2000-04-04 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_AC_ENABLE_DNS): Check for dns, dns-for-kdc, and + dns-for-realm separately. Define KRB5_DNS_LOOKUP if either mode + is enabled. Define KRB5_DNS_LOOKUP_KDC and KRB5_DNS_LOOKUP_REALM + if the appropriate modes are enabled. + * acconfig.h (KRB5_DNS_LOOKUP_KDC, KRB5_DNS_LOOKUP_REALM): Undef. + +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_LIB_PARAMS): Check for alpha*-dec-osf* instead + of alpha-dec-osf*. + 2000-03-15 Ken Raeburn <raeburn@mit.edu> * aclocal.m4 (KRB5_AC_ENABLE_DNS): Fix typo that caused the DNS diff --git a/src/Makefile.in b/src/Makefile.in index 57efe5e..771be6a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -290,7 +290,10 @@ clean-windows:: Makefile-windows @echo Making clean in clients cd ..\clients $(MAKE) -$(MFLAGS) clean - cd .. + @echo Making in appl\gss-sample + cd ..\appl\gss-sample + $(MAKE) -$(MFLAGS) clean + cd ..\.. @echo Making clean in root # diff --git a/src/acconfig.h b/src/acconfig.h index e6f00c7..7ac14f0 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -32,6 +32,8 @@ /* Define if DNS support for finding realms and KDC locations should be compiled in. */ #undef KRB5_DNS_LOOKUP +#undef KRB5_DNS_LOOKUP_KDC +#undef KRB5_DNS_LOOKUP_REALM /* Define to `long' if <sys/types.h> doesn't define. */ #undef time_t diff --git a/src/aclocal.m4 b/src/aclocal.m4 index 3228610..c076180 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -1119,7 +1119,7 @@ CC_LINK_STATIC='$(CC) $(PROG_LIBPATH)' # Set up architecture-specific variables. case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so @@ -1396,7 +1396,8 @@ AC_DEFUN(AC_LIBRARY_NET, [ # ugliness is necessary: AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", - AC_CHECK_LIB(resolv, gethostbyname), + AC_CHECK_LIB(resolv, gethostbyname, + LIBS="-lresolv $LIBS" ; RESOLV_LIB=-lresolv), -lnsl) ) ) @@ -1406,20 +1407,43 @@ AC_DEFUN(AC_LIBRARY_NET, [ KRB5_AC_ENABLE_DNS if test "$enable_dns" = yes ; then AC_CHECK_FUNC(res_search, , AC_CHECK_LIB(resolv, res_search, - LIBS="$LIBS -lresolv", + LIBS="$LIBS -lresolv" ; RESOLV_LIB=-lresolv, AC_ERROR(Cannot find resolver support routine res_search in -lresolv.) )) fi + AC_SUBST(RESOLV_LIB) ]) dnl dnl dnl KRB5_AC_ENABLE_DNS dnl AC_DEFUN(KRB5_AC_ENABLE_DNS, [ + enable_dns_for_kdc=yes + enable_dns_for_realm=no + AC_ARG_ENABLE([dns], -[ --enable-dns enable DNS lookups of Kerberos realm and servers], , +[ --enable-dns enable DNS lookups of Kerberos realm and servers], +[enable_dns_for_kdc="$enable_dns" +enable_dns_for_realm="$enable_dns"], [enable_dns=no]) if test "$enable_dns" = yes; then AC_DEFINE(KRB5_DNS_LOOKUP) fi + + AC_ARG_ENABLE([dns-for-kdc], +[ --enable-dns-for-kdc enable DNS lookups of Kerberos servers only]) + if test "$enable_dns_for_kdc" = yes; then + AC_DEFINE(KRB5_DNS_LOOKUP_KDC) + fi + + AC_ARG_ENABLE([dns-for-realm], +[ --enable-dns-for-realm enable DNS lookups of Kerberos realm names only]) + if test "$enable_dns_for_realm" = yes; then + AC_DEFINE(KRB5_DNS_LOOKUP_REALM) + fi + + if test "$enable_dns_for_kdc" = yes || test "$enable_dns_for_realm" = yes ; then + enable_dns=yes + AC_DEFINE(KRB5_DNS_LOOKUP) + fi ]) diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index d3314b0..7ce19d3 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 2000-03-15 Ken Raeburn <raeburn@mit.edu> Mark D. Roth <roth@uiuc.edu> diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in index 6d31f48..cf65476 100644 --- a/src/appl/bsd/configure.in +++ b/src/appl/bsd/configure.in @@ -25,11 +25,12 @@ dnl Make our operating system-specific security checks and definitions for dnl login. dnl case $krb5_cv_host in -*-*-aix3*) # AIX has streams include files but not streams TTY -# Moreover, strops.h trashes sys/ioctl.h -krb5_cv_has_streams=no -;; -alpha-dec-osf*) +*-*-aix3*) + # AIX has streams include files but not streams TTY + # Moreover, strops.h trashes sys/ioctl.h + krb5_cv_has_streams=no + ;; +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) LOGINLIBS="$LOGINLIBS -lsecurity" diff --git a/src/appl/gssftp/ChangeLog b/src/appl/gssftp/ChangeLog index 691a2e9..849c962 100644 --- a/src/appl/gssftp/ChangeLog +++ b/src/appl/gssftp/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/appl/gssftp/configure.in b/src/appl/gssftp/configure.in index f0c2bff..349cc04 100644 --- a/src/appl/gssftp/configure.in +++ b/src/appl/gssftp/configure.in @@ -67,7 +67,7 @@ else FTPD_LIBS="../../../krb524/libkrb524.a" fi case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) FTPD_LIBS="$FTPD_LIBS -lsecurity" diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog index 040a9af..1211161 100644 --- a/src/appl/telnet/telnetd/ChangeLog +++ b/src/appl/telnet/telnetd/ChangeLog @@ -1,3 +1,9 @@ +2000-03-20 Ken Raeburn <raeburn@mit.edu> + Jeffrey Altman <jaltman@watsun.cc.columbia.edu> + + * state.c (telrcv): Fix off-by-one error dealing with full + buffer. + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Remove dependency on libdes425 when krb4 support diff --git a/src/appl/telnet/telnetd/state.c b/src/appl/telnet/telnetd/state.c index 0f3b161..83e1840 100644 --- a/src/appl/telnet/telnetd/state.c +++ b/src/appl/telnet/telnetd/state.c @@ -102,7 +102,7 @@ telrcv() #endif while (ncc > 0) { - if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) + if ((&ptyobuf[BUFSIZ] - pfrontp) < 1) break; c = *netip++ & 0377, ncc--; #ifdef ENCRYPTION diff --git a/src/clients/ChangeLog b/src/clients/ChangeLog index 2ab67bd..b70201b 100644 --- a/src/clients/ChangeLog +++ b/src/clients/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Test for <arpa/inet.h> include file for inet_ntop diff --git a/src/clients/configure.in b/src/clients/configure.in index bd2046d..a2de914 100644 --- a/src/clients/configure.in +++ b/src/clients/configure.in @@ -12,7 +12,7 @@ fi AC_SUBST(SETENVOBJ) AC_CHECK_HEADERS(unistd.h pwd.h arpa/inet.h) case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) KSU_LIBS="$KSU_LIBS -lsecurity" diff --git a/src/clients/klist/ChangeLog b/src/clients/klist/ChangeLog index 86686bb..31afc38 100644 --- a/src/clients/klist/ChangeLog +++ b/src/clients/klist/ChangeLog @@ -1,3 +1,10 @@ +2000-04-19 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in: Link in getopt library on Windows. + + * klist.c: Use getopt so that we can parse combined options (e.g., + -an or -45). + 2000-03-07 Danilo Almeida <dalmeida@mit.edu> * klist.M: Get man page up-to-date. diff --git a/src/clients/klist/Makefile.in b/src/clients/klist/Makefile.in index c33a4d0..4e067ea 100644 --- a/src/clients/klist/Makefile.in +++ b/src/clients/klist/Makefile.in @@ -14,7 +14,7 @@ all-mac:: klist: klist.o $(KRB4COMPAT_DEPLIBS) $(CC_LINK) -o $@ klist.o $(KRB4COMPAT_LIBS) -$(OUTPRE)klist.exe: $(OUTPRE)klist.obj $(KLIB) $(CLIB) +$(OUTPRE)klist.exe: $(OUTPRE)klist.obj $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib $(KLIB) $(CLIB) link $(EXE_LINKOPTS) -out:$@ $** wsock32.lib clean-unix:: diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c index de435c4..ecf0be6 100644 --- a/src/clients/klist/klist.c +++ b/src/clients/klist/klist.c @@ -53,6 +53,8 @@ #include <netdb.h> #endif +extern int optind; + int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0; int show_etype = 0, show_addresses = 0, no_resolve = 0; char *defname; @@ -130,6 +132,7 @@ main(argc, argv) int argc; char **argv; { + int c; char *name; int mode; int use_k5 = 0, use_k4 = 0; @@ -141,14 +144,10 @@ main(argc, argv) progname = GET_PROGNAME(argv[0]); - argv++; name = NULL; mode = DEFAULT; - while (*argv) { - if ((*argv)[0] != '-') { - if (name) usage(); - name = *argv; - } else switch ((*argv)[1]) { + while ((c = getopt(argc, argv, "fetKsnack45")) != -1) { + switch (c) { case 'f': show_flags = 1; break; @@ -202,7 +201,6 @@ main(argc, argv) usage(); break; } - argv++; } if (no_resolve && !show_addresses) { @@ -217,6 +215,14 @@ main(argc, argv) usage(); } + if (argc - optind > 1) { + fprintf(stderr, "Extra arguments (starting with \"%s\").\n", + argv[optind+1]); + usage(); + } + + name = (optind == argc-1) ? argv[optind] : 0; + if (!use_k5 && !use_k4) { use_k5 = default_k5; diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 928ecb1..6e44dcc 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,11 @@ +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * krb5.hin: Declare krb5_free_ktypes. + +2000-03-25 Miro Jurisic <meeroh@mit.edu> + + * k5-int.h: Fixed protos for krb5_locate_srv_* (naddrs is int*) + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * krb5.hin: Add krb5_get_prompt_types() and related defs.. diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 1c48809..4f37850 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -511,7 +511,7 @@ krb5_error_code krb5_sendto_kdc const krb5_data *, const krb5_data *, krb5_data *, - int *)); + int)); krb5_error_code krb5_get_krbhst KRB5_PROTOTYPE((krb5_context, const krb5_data *, @@ -555,9 +555,8 @@ krb5_error_code krb5_locate_srv_conf const krb5_data *, const char *, struct sockaddr **, - int *, - int *, - int *)); + int*, + int)); /* no context? */ krb5_error_code krb5_locate_srv_dns @@ -565,7 +564,7 @@ krb5_error_code krb5_locate_srv_dns const char *, const char *, struct sockaddr **, - int *)); + int*)); #endif /* KRB5_LIBOS_PROTO__ */ @@ -965,7 +964,7 @@ KRB5_PROTOTYPE((krb5_context context, krb5_get_init_creds_opt *options, krb5_gic_get_as_key_fct gak, void *gak_data, - int *master, + int master, krb5_kdc_rep **as_reply)); diff --git a/src/include/krb5.hin b/src/include/krb5.hin index ea8f93e..84d2c00 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -1401,6 +1401,7 @@ krb5_error_code krb5_get_tgs_ktypes krb5_error_code krb5_get_permitted_enctypes KRB5_PROTOTYPE((krb5_context, krb5_enctype **)); +void krb5_free_ktypes KRB5_PROTOTYPE ((krb5_context, krb5_enctype *)); krb5_boolean krb5_is_permitted_enctype KRB5_PROTOTYPE((krb5_context, krb5_enctype)); diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index d0bbda2..6eb650c 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,15 @@ +2000-04-22 Ken Raeburn <raeburn@mit.edu> + + * network.c: Include stddef.h. + (foreach_localaddr): Check each address against previously used + addresses, and skip duplicates, in case multiple interfaces have + the same address. + +2000-04-21 Ken Raeburn <raeburn@mit.edu> + + * network.c (foreach_localaddr): If called functions fail, drop + out of loop and return nonzero. + 2000-03-14 Ken Raeburn <raeburn@mit.edu> * sock2p.c: New file. diff --git a/src/kdc/network.c b/src/kdc/network.c index 502682a..a91fc95 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -1,7 +1,7 @@ /* * kdc/network.c * - * Copyright 1990 by the Massachusetts Institute of Technology. + * Copyright 1990,2000 by the Massachusetts Institute of Technology. * * Export of this software from the United States of America may * require a specific license from the United States Government. @@ -35,6 +35,7 @@ #include <sys/ioctl.h> #include <syslog.h> +#include <stddef.h> #include <ctype.h> #ifdef HAVE_NETINET_IN_H #include <sys/types.h> @@ -120,13 +121,14 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) int (*betweenfn) (void *); int (*pass2fn) (void *, struct sockaddr *); { - struct ifreq *ifr, ifreq; + struct ifreq *ifr, ifreq, *ifr2; struct ifconf ifc; - int s, code, n, i; + int s, code, n, i, j; int est_if_count = 8, est_ifreq_size; char *buf = 0; size_t current_buf_size = 0; - + int fail = 0; + s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) return SOCKET_ERRNO; @@ -184,6 +186,7 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; } + #ifdef IFF_LOOPBACK /* None of the current callers want loopback addresses. */ if (ifreq.ifr_flags & IFF_LOOPBACK) @@ -193,13 +196,32 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) if (!(ifreq.ifr_flags & IFF_UP)) goto skip; + /* Make sure we didn't process this address already. */ + for (j = 0; j < i; j += ifreq_size(*ifr2)) { + ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j); + if (ifr2->ifr_name[0] == 0) + continue; + if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family + && ifreq_size (*ifr) == ifreq_size (*ifr2) + /* Compare address info. If this isn't good enough -- + i.e., if random padding bytes turn out to differ + when the addresses are the same -- then we'll have + to do it on a per address family basis. */ + && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data, + (ifreq_size (*ifr) + - offsetof (struct ifreq, ifr_addr.sa_data)))) + goto skip; + } + if ((*pass1fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } if (betweenfn && (*betweenfn)(data)) { - abort (); + fail = 1; + goto punt; } if (pass2fn) @@ -211,13 +233,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; if ((*pass2fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } + punt: closesocket(s); free (buf); - return 0; + return fail; } struct socksetup { diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index 06639d4..c69296a 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,4 +1,52 @@ -2000-01-27 Ken Raeburn <raeburn@raeburn.org> +2000-04-21 Ken Raeburn <raeburn@mit.edu> + + * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field + gsskrb5_version. + (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech. + * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c, + k5seal.c, k5unseal.c, ser_ctx.c: + Delete krb5-mech2 support. + + * init_sec_context.c (get_credentials): Enctype argument is now a + pointer to a list of enctypes. Explicitly try each in order until + success or an error other than cryptosystem not being supported. + (krb5_gss_init_sec_context): Pass list of cryptosystems, starting + with 3DES. + + * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types, + giving symbolic names for values from RFC 1964, a Microsoft win2k + I-D, and our proposed 3des-sha1 values. + (KG_USAGE_SEAL, KG_USAGE_SIGN): New macros. + + * accept_sec_context.c (rd_req_keyproc): Already-disabled routine + deleted. + (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic + names. Add a case for des3-hmac-sha1. + * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for + checksums. + * k5unseal.c (kg_unseal_v1): Likewise. + * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for + encryption. + + * util_crypt.c (zeros): Unused variable deleted. + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * wrap_size_limit.c: Remove mech2 support. Add MIT copyright. + +2000-04-08 Tom Yu <tlyu@mit.edu> + + * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix up + wrap_size_limit() to deal with integrity wrap tokens properly. + The rfc1964 mech always pads and confounds regardless of whether + confidentiality is requested. + +2000-03-20 Ken Raeburn <raeburn@mit.edu> + + * accept_sec_context.c, init_sec_context.c: Disable krb5-mech2 + stuff for now. (Tom Yu's krb5-1.1 patch.) + +2000-01-27 Ken Raeburn <raeburn@mit.edu> * init_sec_context.c (krb5_gss_init_sec_context): Default to des-cbc-crc. diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index fc920ec..1f56159 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -49,39 +73,12 @@ #include "k5-int.h" #include "gssapiP_krb5.h" #include <memory.h> +#include <assert.h> /* * $Id$ */ -#if 0 - -/* XXXX This widen/narrow stuff is bletcherous, but it seems to be - necessary. Perhaps there is a "better" way, but I don't know what it - is */ - -#include <krb5/widen.h> -static krb5_error_code -rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, - krb5_kvno kvno, krb5_keyblock **keyblock) -#include <krb5/narrow.h> -{ - krb5_error_code code; - krb5_keytab_entry ktentry; - - if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno, - &ktentry)) - return(code); - - code = krb5_copy_keyblock(&ktentry.key, keyblock); - - (void) krb5_kt_free_entry(&ktentry); - - return(code); -} - -#endif - /* Decode, decrypt and store the forwarded creds in the local ccache. */ static krb5_error_code rd_and_store_for_creds(context, inbuf, out_cred) @@ -145,7 +142,6 @@ rd_and_store_for_creds(context, inbuf, out_cred) /* cred->princ already set */ cred->prerfc_mech = 1; /* this cred will work with all three mechs */ cred->rfc_mech = 1; - cred->rfcv2_mech = 1; cred->keytab = NULL; /* no keytab associated with this... */ cred->ccache = ccache; /* but there is a credential cache */ cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ @@ -206,11 +202,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_ui_4 gss_flags = 0; int decode_req_message = 0; krb5_gss_ctx_id_rec *ctx = 0; -#if 0 krb5_enctype enctype; -#endif krb5_timestamp now; gss_buffer_desc token; + int err; krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; int option_id; @@ -222,7 +217,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, gss_cred_id_t cred_handle = NULL; krb5_gss_cred_id_t deleg_cred = NULL; int token_length; - int gsskrb5_vers; int nctypes; krb5_cksumtype *ctypes = 0; struct kg2_option fwcred; @@ -302,7 +296,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } mech_used = gss_mech_krb5; - gsskrb5_vers = 1000; } else if ((code == G_WRONG_MECH) && !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old, &(ap_req.length), @@ -321,50 +314,14 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } mech_used = gss_mech_krb5_old; - gsskrb5_vers = 1000; - } else if ((code == G_WRONG_MECH) && - !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2, - &token_length, - &ptr, KG2_TOK_INITIAL, - input_token->length))) { - if (! cred->rfcv2_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } - mech_used = gss_mech_krb5_v2; - gsskrb5_vers = 2000; } else { major_status = GSS_S_DEFECTIVE_TOKEN; goto fail; } - if (gsskrb5_vers == 2000) { - /* gss krb5 v2 */ - - fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION; - fwcred.data = NULL; - - if (GSS_ERROR(major_status = - kg2_parse_token(&code, ptr, token_length, - &gss_flags, &nctypes, &ctypes, - delegated_cred_handle?1:0, - &fwcred, &ap_req, NULL))) { - goto fail; - } - - gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; - - gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; - if there's a delegation, we'll - set it below */ - } else { - /* gss krb5 v1 */ - - sptr = (char *) ptr; - TREAD_STR(sptr, ap_req.data, ap_req.length); - decode_req_message = 1; - } + sptr = (char *) ptr; + TREAD_STR(sptr, ap_req.data, ap_req.length); + decode_req_message = 1; /* construct the sender_addr */ @@ -416,9 +373,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, } #endif - if (gsskrb5_vers == 2000) { - bigend = 1; - } else { + { /* gss krb5 v1 */ /* stash this now, for later. */ @@ -557,7 +512,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ctx->gss_flags = KG_IMPLFLAGS(gss_flags); ctx->seed_init = 0; ctx->big_endian = bigend; - ctx->gsskrb5_version = gsskrb5_vers; /* Intern the ctx pointer so that delete_sec_context works */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { @@ -603,114 +557,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - if (gsskrb5_vers == 2000) { - int cblen; - krb5_boolean valid; - - /* intersect the token ctypes with the local ctypes */ - - if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype, - &ctx->nctypes, &ctx->ctypes)) - goto fail; - - if (nctypes == 0) { - code = KRB5_CRYPTO_INTERNAL; - goto fail; - } - - kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); - - if (nctypes == 0) { - code = KG_NO_CTYPES; - goto fail; - } - - /* process the delegated cred, if any */ - - if (fwcred.data) { - krb5_data option; - - option.length = fwcred.length; - option.data = fwcred.data; - - if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) { - major_status = GSS_S_FAILURE; - goto fail; - } - - gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ - } - - /* construct the checksum buffer */ - - cblen = 4*5; - if (input_chan_bindings) - cblen += (input_chan_bindings->initiator_address.length+ - input_chan_bindings->acceptor_address.length+ - input_chan_bindings->application_data.length); + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = SGN_ALG_DES_MAC_MD5; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_DES; - cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2)); + /* fill in the encryption descriptors */ - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { - code = ENOMEM; + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { major_status = GSS_S_FAILURE; goto fail; } - ptr2 = cksumdata.data; - - if (input_chan_bindings) { - TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1); - TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1); - TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1); - TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1); - TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1); - } else { - memset(ptr2, 0, cblen); - ptr2 += cblen; - } - - memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2))); + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, - &cksumdata, authdat->checksum, - &valid)) { + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { major_status = GSS_S_FAILURE; goto fail; } - free(cksumdata.data); - cksumdata.data = 0; + break; - if (!valid) { - code = 0; - major_status = GSS_S_BAD_SIG; - goto fail; - } - } else { - /* gss krb5 v1 */ - - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; -#if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; -#endif - default: - code = KRB5_BAD_ENCTYPE; - goto fail; - } + case ENCTYPE_DES3_CBC_SHA1: + ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; /* fill in the encryption descriptors */ @@ -719,14 +596,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - for (i=0; i<ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xf0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { major_status = GSS_S_FAILURE; goto fail; } + + break; + + default: + code = KRB5_BAD_ENCTYPE; + goto fail; } ctx->endtime = ticket->enc_part2->times.endtime; @@ -769,122 +648,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* the reply token hasn't been sent yet, but that's ok. */ ctx->established = 1; - if (ctx->gsskrb5_version == 2000) { - krb5_ui_4 tok_flags; - - tok_flags = - (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0; - - cksumdata.length = 8 + 4*ctx->nctypes + 4; - - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - - /* construct the token fields */ - - ptr = cksumdata.data; - - ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff; - ptr[1] = KG2_TOK_RESPONSE & 0xff; - - ptr[2] = (tok_flags >> 24) & 0xff; - ptr[3] = (tok_flags >> 16) & 0xff; - ptr[4] = (tok_flags >> 8) & 0xff; - ptr[5] = tok_flags & 0xff; - - ptr[6] = (ctx->nctypes >> 8) & 0xff; - ptr[7] = ctx->nctypes & 0xff; - - ptr += 8; - - for (i=0; i<ctx->nctypes; i++) { - ptr[i] = (ctx->ctypes[i] >> 24) & 0xff; - ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff; - ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff; - ptr[i+3] = ctx->ctypes[i] & 0xff; - - ptr += 4; - } - - memset(ptr, 0, 4); - - /* make the MIC token */ - - { - gss_buffer_desc text, token; + token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - text.length = cksumdata.length; - text.value = cksumdata.data; - - /* ctx->seq_send must be set before this call */ - - if (GSS_ERROR(major_status = - krb5_gss_get_mic(&code, ctx, - GSS_C_QOP_DEFAULT, - &text, &token))) - goto fail; - - mic.length = token.length; - mic.data = token.value; - } - - token.length = g_token_size((gss_OID) mech_used, - (cksumdata.length-2)+4+ap_rep.length+ - mic.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) - == NULL) { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, - (cksumdata.length-2)+4+ap_rep.length+mic.length, - &ptr, KG2_TOK_RESPONSE); - - memcpy(ptr, cksumdata.data+2, cksumdata.length-2); - ptr += cksumdata.length-2; - - ptr[0] = (ap_rep.length >> 8) & 0xff; - ptr[1] = ap_rep.length & 0xff; - memcpy(ptr+2, ap_rep.data, ap_rep.length); - - ptr += (2+ap_rep.length); - - ptr[0] = (mic.length >> 8) & 0xff; - ptr[1] = mic.length & 0xff; - memcpy(ptr+2, mic.data, mic.length); - - ptr += (2+mic.length); - - free(cksumdata.data); - cksumdata.data = 0; - - /* gss krb5 v2 */ - } else { - /* gss krb5 v1 */ - - token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) - == NULL) { - major_status = GSS_S_FAILURE; - code = ENOMEM; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, ap_rep.length, - &ptr, KG_TOK_CTX_AP_REP); + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + major_status = GSS_S_FAILURE; + code = ENOMEM; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); - TWRITE_STR(ptr, ap_rep.data, ap_rep.length); + TWRITE_STR(ptr, ap_rep.data, ap_rep.length); - ctx->established = 1; + ctx->established = 1; - } } else { token.length = 0; token.value = NULL; @@ -1014,13 +793,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (code) return (major_status); - if (gsskrb5_vers == 2000) { - tmsglen = 12+scratch.length; - toktype = KG2_TOK_RESPONSE; - } else { - tmsglen = scratch.length; - toktype = KG_TOK_CTX_ERROR; - } + tmsglen = scratch.length; + toktype = KG_TOK_CTX_ERROR; token.length = g_token_size((gss_OID) mech_used, tmsglen); token.value = (unsigned char *) xmalloc(token.length); @@ -1030,24 +804,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ptr = token.value; g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); - if (gsskrb5_vers == 2000) { - krb5_ui_4 flags; - - flags = KG2_RESP_FLAG_ERROR; - - ptr[0] = (flags << 24) & 0xff; - ptr[1] = (flags << 16) & 0xff; - ptr[2] = (flags << 8) & 0xff; - ptr[3] = flags & 0xff; - - memset(ptr+4, 0, 6); - - ptr[10] = (scratch.length << 8) & 0xff; - ptr[11] = scratch.length & 0xff; - - ptr += 12; - } - TWRITE_STR(ptr, scratch.data, scratch.length); xfree(scratch.data); diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index b67eb4f..1fb2b2f 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -283,7 +307,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, size_t i; krb5_gss_cred_id_t cred; gss_OID_set ret_mechs; - int req_old, req_new, req_v2; + int req_old, req_new; OM_uint32 ret; krb5_error_code code; @@ -313,22 +337,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, if (desired_mechs == GSS_C_NULL_OID_SET) { req_old = 1; req_new = 1; - req_v2 = 1; } else { req_old = 0; req_new = 0; - req_v2 = 0; for (i=0; i<desired_mechs->count; i++) { if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) req_new++; - if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i]))) - req_v2++; } - if (!req_old && !req_new && !req_v2) { + if (!req_old && !req_new) { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -347,7 +367,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, cred->princ = NULL; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; - cred->rfcv2_mech = req_v2; cred->keytab = NULL; cred->ccache = NULL; @@ -447,10 +466,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, (cred->rfc_mech && GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, gss_mech_krb5, - &ret_mechs))) || - (cred->rfcv2_mech && - GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, - gss_mech_krb5_v2, &ret_mechs)))) { if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c index 2a6fdb4..459b415 100644 --- a/src/lib/gssapi/krb5/add_cred.c +++ b/src/lib/gssapi/krb5/add_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. @@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle, /* check that desired_mech isn't already in the credential */ if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) || - (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) || - (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) { + (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) { *minor_status = 0; return(GSS_S_DUPLICATE_ELEMENT); } @@ -156,7 +179,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle, new_cred->usage = cred_usage; new_cred->prerfc_mech = cred->prerfc_mech; new_cred->rfc_mech = cred->rfc_mech; - new_cred->rfcv2_mech = cred->rfcv2_mech; new_cred->tgt_expire = cred->tgt_expire; if (code = krb5_copy_principal(context, cred->princ, @@ -280,8 +302,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle, cred->prerfc_mech = 1; else if (g_OID_equal(desired_mech, gss_mech_krb5)) cred->rfc_mech = 1; - else if (g_OID_equal(desired_mech, gss_mech_krb5_v2)) - cred->rfcv2_mech = 1; /* set the outputs */ diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index e344b4f..2e29844 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -79,6 +103,27 @@ #define KG2_RESP_FLAG_ERROR 0x0001 #define KG2_RESP_FLAG_DELEG_OK 0x0002 +/* These are to be stored in little-endian order, i.e., des-mac is + stored as 02 00. */ +enum sgn_alg { + SGN_ALG_DES_MAC_MD5 = 0x0000, + SGN_ALG_MD2_5 = 0x0001, + SGN_ALG_DES_MAC = 0x0002, + SGN_ALG_3 = 0x0003, /* not published */ + SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */ + SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004 +}; +enum seal_alg { + SEAL_ALG_NONE = 0xffff, + SEAL_ALG_DES = 0x0000, + SEAL_ALG_1 = 0x0001, /* not published */ + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */ + SEAL_ALG_DES3KD = 0x0002 +}; + +#define KG_USAGE_SEAL 22 +#define KG_USAGE_SIGN 23 + /** internal types **/ typedef krb5_principal krb5_gss_name_t; @@ -89,7 +134,6 @@ typedef struct _krb5_gss_cred_id_rec { krb5_principal princ; /* this is not interned as a gss_name_t */ int prerfc_mech; int rfc_mech; - int rfcv2_mech; /* keytab (accept) data */ krb5_keytab keytab; @@ -125,7 +169,6 @@ typedef struct _krb5_gss_ctx_id_rec { int big_endian; krb5_auth_context auth_context; gss_OID_desc *mech_used; - int gsskrb5_version; int nctypes; krb5_cksumtype *ctypes; } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index d0c8bc9..ac6a066 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -49,6 +73,7 @@ #include "gssapiP_krb5.h" #include <memory.h> #include <stdlib.h> +#include <assert.h> /* * $Id$ @@ -63,17 +88,20 @@ int krb5_gss_dbg_client_expcreds = 0; * ccache. */ static krb5_error_code get_credentials(context, cred, server, now, - endtime, enctype, out_creds) + endtime, enctypes, out_creds) krb5_context context; krb5_gss_cred_id_t cred; krb5_principal server; krb5_timestamp now; krb5_timestamp endtime; - krb5_enctype enctype; + const krb5_enctype *enctypes; krb5_creds **out_creds; { krb5_error_code code; krb5_creds in_creds; + krb5_enctype *senctypes = 0; + int i; + int found_supported_enctype; memset((char *) &in_creds, 0, sizeof(krb5_creds)); @@ -82,12 +110,38 @@ static krb5_error_code get_credentials(context, cred, server, now, if ((code = krb5_copy_principal(context, server, &in_creds.server))) goto cleanup; in_creds.times.endtime = endtime; - in_creds.keyblock.enctype = enctype; - if ((code = krb5_get_credentials(context, 0, cred->ccache, - &in_creds, out_creds))) + in_creds.keyblock.enctype = 0; + code = krb5_get_tgs_ktypes (context, + /* unused! */ cred->princ, + &senctypes); + if (code) goto cleanup; + found_supported_enctype = 0; + for (i = 0; enctypes[i]; i++) { + int j; + for (j = 0; senctypes[j]; j++) + if (enctypes[i] == senctypes[j]) + break; + if (senctypes[j] == 0) + continue; + found_supported_enctype = 1; + in_creds.keyblock.enctype = enctypes[i]; + code = krb5_get_credentials(context, 0, cred->ccache, + &in_creds, out_creds); + if (code == 0) + break; + if (code == KRB5_CC_NOT_KTYPE) + continue; + } + if (enctypes[i] == 0) { + if (found_supported_enctype) + return code; + else + return KRB5_CONFIG_ETYPE_NOSUPP; + } + /* * Enforce a stricter limit (without timeskew forgiveness at the * boundaries) because accept_sec_context code is also similarly @@ -99,6 +153,8 @@ static krb5_error_code get_credentials(context, cred, server, now, } cleanup: + if (senctypes) + krb5_free_ktypes (context, senctypes); if (in_creds.client) krb5_free_principal(context, in_creds.client); if (in_creds.server) @@ -117,196 +173,8 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token) gss_OID mech_type; gss_buffer_t token; { - krb5_flags mk_req_flags = 0; - krb5_int32 con_flags; - krb5_error_code code; - krb5_data credmsg, cksumdata, ap_req; - int i, tlen, cblen, nctypes; - krb5_cksumtype *ctypes; - unsigned char *t, *ptr; - - credmsg.data = 0; - cksumdata.data = 0; - ap_req.data = 0; - ctypes = 0; - - /* create the option data if necessary */ - if (ctx->gss_flags & GSS_C_DELEG_FLAG) { - /* first get KRB_CRED message, so we know its length */ - - /* clear the time check flag that was set in krb5_auth_con_init() */ - krb5_auth_con_getflags(context, ctx->auth_context, &con_flags); - krb5_auth_con_setflags(context, ctx->auth_context, - con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); - - code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0, - cred->princ, ctx->there, cred->ccache, 1, - &credmsg); - - /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */ - krb5_auth_con_setflags(context, ctx->auth_context, con_flags); - - if (code) { - /* don't fail here; just don't accept/do the delegation - request */ - ctx->gss_flags &= ~GSS_C_DELEG_FLAG; - } else { - if (credmsg.length > KRB5_INT16_MAX) { - krb5_free_data_contents(context, &credmsg); - return(KRB5KRB_ERR_FIELD_TOOLONG); - } - } - } else { - credmsg.length = 0; - } - - /* construct the list of compatible cksum types */ - - if ((code = krb5_c_keyed_checksum_types(context, - k_cred->keyblock.enctype, - &nctypes, &ctypes))) - goto cleanup; - - if (nctypes == 0) { - code = KRB5_CRYPTO_INTERNAL; - goto cleanup; - } - - /* construct the checksum fields */ - - cblen = 4*5; - if (chan_bindings) - cblen += (chan_bindings->initiator_address.length+ - chan_bindings->acceptor_address.length+ - chan_bindings->application_data.length); - - cksumdata.length = cblen + 8 + 4*nctypes + 4; - if (credmsg.length) - cksumdata.length += 4 + credmsg.length; - - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) - goto cleanup; - - /* helper macros. This code currently depends on a long being 32 - bits, and htonl dtrt. */ - - ptr = cksumdata.data; - - if (chan_bindings) { - TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1); - TWRITE_BUF(ptr, chan_bindings->initiator_address, 1); - TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1); - TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1); - TWRITE_BUF(ptr, chan_bindings->application_data, 1); - } else { - memset(ptr, 0, cblen); - ptr += cblen; - } - - /* construct the token fields */ - - ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff; - ptr[1] = KG2_TOK_INITIAL & 0xff; - - ptr[2] = (ctx->gss_flags >> 24) & 0xff; - ptr[3] = (ctx->gss_flags >> 16) & 0xff; - ptr[4] = (ctx->gss_flags >> 8) & 0xff; - ptr[5] = ctx->gss_flags & 0xff; - - ptr[6] = (nctypes >> 8) & 0xff; - ptr[7] = nctypes & 0xff; - - ptr += 8; - - for (i=0; i<nctypes; i++) { - ptr[0] = (ctypes[i] >> 24) & 0xff; - ptr[1] = (ctypes[i] >> 16) & 0xff; - ptr[2] = (ctypes[i] >> 8) & 0xff; - ptr[3] = ctypes[i] & 0xff; - - ptr += 4; - } - - if (credmsg.length) { - ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff; - ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff; - - ptr[2] = (credmsg.length >> 8) & 0xff; - ptr[3] = credmsg.length & 0xff; - - ptr += 4; - - memcpy(ptr, credmsg.data, credmsg.length); - - ptr += credmsg.length; - } - - memset(ptr, 0, 4); - - /* call mk_req. subkey and ap_req need to be used or destroyed */ - - mk_req_flags = AP_OPTS_USE_SUBKEY; - - if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) - mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; - - if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, - &cksumdata, k_cred, &ap_req))) - goto cleanup; - - /* store the interesting stuff from creds and authent */ - ctx->endtime = k_cred->times.endtime; - ctx->krb_flags = k_cred->ticket_flags; - - /* build up the token */ - - /* allocate space for the token */ - tlen = g_token_size((gss_OID) mech_type, - (cksumdata.length-(2+cblen))+2+ap_req.length); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { - code = ENOMEM; - goto cleanup; - } - - ptr = t; - - g_make_token_header((gss_OID) mech_type, - (cksumdata.length-(2+cblen))+2+ap_req.length, - &ptr, KG2_TOK_INITIAL); - - /* skip over the channel bindings and the token id */ - memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2)); - ptr += cksumdata.length-(cblen+2); - ptr[0] = (ap_req.length >> 8) & 0xff; - ptr[1] = ap_req.length & 0xff; - ptr += 2; - memcpy(ptr, ap_req.data, ap_req.length); - - /* pass allocated data back */ - - ctx->nctypes = nctypes; - ctx->ctypes = ctypes; - - token->length = tlen; - token->value = (void *) t; - - code = 0; - -cleanup: - if (code) { - if (ctypes) - krb5_free_cksumtypes(context, ctypes); - } - - if (credmsg.data) - free(credmsg.data); - if (ap_req.data) - free(ap_req.data); - if (cksumdata.data) - free(cksumdata.data); - - return(code); + int krb5_mech2_supported = 0; + assert(krb5_mech2_supported); } static krb5_error_code @@ -480,13 +348,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, krb5_context context; krb5_gss_cred_id_t cred; krb5_creds *k_cred = 0; - krb5_enctype enctype = ENCTYPE_DES_CBC_CRC; + static const krb5_enctype wanted_enctypes[] = { +#if 1 + ENCTYPE_DES3_CBC_SHA1, +#endif + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4, + 0 + }; krb5_error_code code; krb5_gss_ctx_id_rec *ctx, *ctx_free; krb5_timestamp now; gss_buffer_desc token; - int gsskrb5_vers = 0; - int i, err; + int i, j, err; int default_mech = 0; krb5_ui_4 resp_flags; OM_uint32 major_status; @@ -528,32 +402,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, err = 0; if (mech_type == GSS_C_NULL_OID) { default_mech = 1; - if (cred->rfcv2_mech) { - mech_type = gss_mech_krb5_v2; - gsskrb5_vers = 2000; - } else if (cred->rfc_mech) { + if (cred->rfc_mech) { mech_type = gss_mech_krb5; - gsskrb5_vers = 1000; - enctype = ENCTYPE_DES_CBC_CRC; } else if (cred->prerfc_mech) { mech_type = gss_mech_krb5_old; - gsskrb5_vers = 1000; - enctype = ENCTYPE_DES_CBC_CRC; } else { err = 1; } - } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) { - if (!cred->rfcv2_mech) - err = 1; - gsskrb5_vers = 2000; } else if (g_OID_equal(mech_type, gss_mech_krb5)) { if (!cred->rfc_mech) err = 1; - gsskrb5_vers = 1000; } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { if (!cred->prerfc_mech) err = 1; - gsskrb5_vers = 1000; } else { err = 1; } @@ -607,7 +468,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ ctx->seqstate = 0; - ctx->gsskrb5_version = gsskrb5_vers; ctx->nctypes = 0; ctx->ctypes = 0; @@ -628,27 +488,12 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, goto fail; if ((code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, enctype, &k_cred))) + ctx->endtime, wanted_enctypes, &k_cred))) goto fail; - /* - * If the default mechanism was requested, and the keytype is - * DES_CBC, force the old mechanism - */ - if (default_mech && - ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) || - (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) || - (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) { - ctx->gsskrb5_version = gsskrb5_vers = 1000; + if (default_mech) { mech_type = gss_mech_krb5; - if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) { - krb5_free_creds(context, k_cred); - enctype = ENCTYPE_DES_CBC_CRC; - if ((code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, enctype, &k_cred))) - goto fail; - } - } + } if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used) != GSS_S_COMPLETE) { @@ -660,24 +505,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, */ ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); - if (ctx->gsskrb5_version == 2000) { - /* gsskrb5 v2 */ - if ((code = make_ap_req_v2(context, ctx, - cred, k_cred, input_chan_bindings, - mech_type, &token))) { - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - major_status = GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, - &ctx->seq_send); - krb5_auth_con_getlocalsubkey(context, ctx->auth_context, - &ctx->subkey); - } else { + { /* gsskrb5 v1 */ if ((code = make_ap_req_v1(context, ctx, cred, k_cred, input_chan_bindings, @@ -699,11 +527,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, switch(ctx->subkey->enctype) { case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_MD4: case ENCTYPE_DES_CBC_CRC: ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; + ctx->signalg = SGN_ALG_DES_MAC_MD5; ctx->cksum_size = 8; - ctx->sealalg = 0; + ctx->sealalg = SEAL_ALG_DES; + + /* The encryption key is the session key XOR + 0xf0f0f0f0f0f0f0f0. */ + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) + goto fail; + + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; + + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) + goto fail; + + break; + + case ENCTYPE_DES3_CBC_SHA1: + ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; + + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc); + if (code) + goto fail; + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq); + if (code) { + krb5_free_keyblock (context, ctx->enc); + goto fail; + } break; #if 0 case ENCTYPE_DES3_CBC_MD5: @@ -714,20 +572,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, break; #endif default: + *minor_status = KRB5_BAD_ENCTYPE; return GSS_S_FAILURE; } - /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ - - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) - goto fail; - - for (i=0; i<ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xf0; - - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) - goto fail; } if (k_cred) { @@ -824,94 +672,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ptr = (unsigned char *) input_token->value; - if (ctx->gsskrb5_version == 2000) { - int token_length; - int nctypes; - krb5_cksumtype *ctypes = 0; - - /* gsskrb5 v2 */ - - if ((code = g_verify_token_header((gss_OID) ctx->mech_used, - &token_length, - &ptr, KG2_TOK_RESPONSE, - input_token->length))) { - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } - - if (GSS_ERROR(major_status = - kg2_parse_token(minor_status, ptr, token_length, - &resp_flags, &nctypes, &ctypes, - 0, NULL, &ap_rep, &mic))) { - if (ctypes) - free(ctypes); - code = *minor_status; - goto fail; - } - major_status = GSS_S_FAILURE; - - kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + if ((err = g_verify_token_header((gss_OID) ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length))) { + if (g_verify_token_header((gss_OID) ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_ERROR, + input_token->length) == 0) { - free(ctypes); - - if (ctx->nctypes == 0) { - code = KG_NO_CTYPES; - goto fail; - } + /* Handle a KRB_ERROR message from the server */ - if (resp_flags & KG2_RESP_FLAG_ERROR) { - if ((code = krb5_rd_error(context, &ap_rep, &krb_error))) + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + + code = krb5_rd_error(context, &ap_rep, &krb_error); + if (code) goto fail; - if (krb_error->error) code = krb_error->error + ERROR_TABLE_BASE_krb5; else code = 0; - krb5_free_error(context, krb_error); goto fail; + } else { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); } - - if (resp_flags & KG2_RESP_FLAG_DELEG_OK) - ctx->gss_flags |= GSS_C_DELEG_FLAG; - - /* drop through to ap_rep handling */ - } else { - /* gsskrb5 v1 */ - - if ((err = g_verify_token_header((gss_OID) ctx->mech_used, - &(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length))) { - if (g_verify_token_header((gss_OID) ctx->mech_used, - &(ap_rep.length), - &ptr, KG_TOK_CTX_ERROR, - input_token->length) == 0) { - - /* Handle a KRB_ERROR message from the server */ - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); - - code = krb5_rd_error(context, &ap_rep, &krb_error); - if (code) - goto fail; - if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; - else - code = 0; - krb5_free_error(context, krb_error); - goto fail; - } else { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - } - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); } + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + /* decode the ap_rep */ if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, &ap_rep_data))) { @@ -938,26 +730,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, /* set established */ ctx->established = 1; - if (ctx->gsskrb5_version == 2000) { - gss_buffer_desc mic_data, mic_token; - - /* start with the token id */ - mic_data.value = ptr-2; - /* end before the ap-rep length */ - mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2)); - - mic_token.length = mic.length; - mic_token.value = mic.data; - - if (GSS_ERROR(major_status = - krb5_gss_verify_mic(minor_status, *context_handle, - &mic_data, &mic_token, NULL))) { - code = *minor_status; - goto fail; - } - major_status = GSS_S_FAILURE; - } - /* set returns */ if (time_rec) { diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index c800012..6da0a52 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -121,10 +145,6 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, (cred->rfc_mech && GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, gss_mech_krb5, - &mechs))) || - (cred->rfcv2_mech && - GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, - gss_mech_krb5_v2, &mechs)))) { krb5_free_principal(context, ret_name); /* *minor_status set above */ diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index ae8cc75..cfdc2db 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -1,6 +1,6 @@ /* * 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 @@ -10,7 +10,7 @@ * 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 @@ -22,14 +22,14 @@ /* * 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 @@ -40,7 +40,7 @@ * 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. @@ -49,196 +49,279 @@ #include "gssapiP_krb5.h" static krb5_error_code -make_priv_token_v2 PROTOTYPE((krb5_context context, - krb5_keyblock *subkey, +make_seal_token_v1 PROTOTYPE((krb5_context context, + krb5_keyblock *enc, + krb5_keyblock *seq, krb5_int32 *seqnum, int direction, gss_buffer_t text, gss_buffer_t token, + int signalg, + int cksum_size, + int sealalg, + int encrypt, + int toktype, + int bigend, gss_OID oid)); static krb5_error_code -make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid) - krb5_context context; - krb5_keyblock *subkey; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - gss_OID oid; -{ - krb5_data plain; - krb5_enc_data cipher; - krb5_error_code code; - size_t enclen; - int tlen; - unsigned char *t, *ptr; - - plain.data = 0; - cipher.ciphertext.data = 0; - t = 0; - - plain.length = 7+text->length; - if ((plain.data = (void *) malloc(plain.length)) == NULL) { - code = ENOMEM; - goto cleanup; - } - - plain.data[0] = (*seqnum >> 24) & 0xff; - plain.data[1] = (*seqnum >> 16) & 0xff; - plain.data[2] = (*seqnum >> 8) & 0xff; - plain.data[3] = *seqnum & 0xff; - - plain.data[4] = direction?0:0xff; - - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; - - memcpy(plain.data+7, text->value, text->length); - - if (code = krb5_c_encrypt_length(context, subkey->enctype, - plain.length, &enclen)) - goto cleanup; - - tlen = g_token_size((gss_OID) oid, 2+enclen); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); - - ptr = t; - - g_make_token_header((gss_OID) oid, 2+enclen, &ptr, - KG2_TOK_WRAP_PRIV); - - ptr[0] = (enclen >> 8) & 0xff; - ptr[1] = enclen & 0xff; - - cipher.ciphertext.length = enclen; - cipher.ciphertext.data = ptr+2; - - if (code = krb5_c_encrypt(context, subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, - 0, &plain, &cipher)) - goto cleanup; - - /* that's it. return the token */ - - (*seqnum)++; - - token->length = tlen; - token->value = (void *) t; - - code = 0; - -cleanup: - if (plain.data) - free(plain.data); - if (code) { - if (t) - free(t); - } - - return(code); -} - -static krb5_error_code -make_integ_token_v2 PROTOTYPE((krb5_context context, - krb5_keyblock *subkey, - krb5_cksumtype ctype, - krb5_int32 *seqnum, - int direction, - gss_buffer_t text, - gss_buffer_t token, - int toktype, - gss_OID oid)); - -static krb5_error_code -make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, - toktype, oid) - krb5_context context; - krb5_keyblock *subkey; - krb5_cksumtype ctype; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - int toktype; - gss_OID oid; +make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, + signalg, cksum_size, sealalg, encrypt, toktype, + bigend, oid) + krb5_context context; + krb5_keyblock *enc; + krb5_keyblock *seq; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + int signalg; + int cksum_size; + int sealalg; + int encrypt; + int toktype; + int bigend; + gss_OID oid; { krb5_error_code code; - int tmp, tlen; - unsigned char *t, *ptr; - krb5_data plain; + size_t sumlen; + char *data_ptr; + krb5_data plaind; + krb5_checksum md5cksum; krb5_checksum cksum; + int conflen=0, tmsglen, tlen; + unsigned char *t, *ptr; - plain.data = 0; - t = 0; - cksum.contents = 0; + int encblksize, sumblksize; + + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + sumblksize = 1; + break; + case SGN_ALG_DES_MAC: + sumblksize = 8; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + sumblksize = 1; + break; + default: + abort (); + return 123; /* find error code */ + } - /* assemble the checksum buffer and compute the checksum */ + switch (sealalg) { + case SEAL_ALG_NONE: + case SEAL_ALG_DES: + case SEAL_ALG_DES3KD: + encblksize = 8; + break; + default: + abort (); + return 12345654321; + } - plain.length = 7+text->length; + /* create the token buffer */ - if ((plain.data = (char *) malloc(plain.length)) == NULL) { - code = errno; - goto cleanup; + if (toktype == KG_TOK_SEAL_MSG) { + if (bigend && !encrypt) { + tmsglen = text->length; + } else { + conflen = kg_confounder_size(context, enc); + /* XXX knows that des block size is 8 */ + tmsglen = (conflen+text->length+8)&(~7); + } + } else { + tmsglen = 0; } - plain.data[0] = (*seqnum >> 24) & 0xff; - plain.data[1] = (*seqnum >> 16) & 0xff; - plain.data[2] = (*seqnum >> 8) & 0xff; - plain.data[3] = *seqnum & 0xff; + tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); - plain.data[4] = direction?0:0xff; + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; + /*** fill in the token */ - memcpy(plain.data+7, text->value, text->length); + ptr = t; - if (code = krb5_c_make_checksum(context, ctype, subkey, - (toktype == KG2_TOK_WRAP_INTEG)? - KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG: - KRB5_KEYUSAGE_GSS_TOK_MIC, - &plain, &cksum)) - goto cleanup; + g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); - /* assemble the token itself */ + /* 0..1 SIGN_ALG */ - if (toktype == KG2_TOK_WRAP_INTEG) - tmp = 4+(7+text->length)+2+cksum.length; - else - tmp = 4+(5)+2+cksum.length; + ptr[0] = signalg & 0xff; + ptr[1] = (signalg >> 8) & 0xff; - tlen = g_token_size((gss_OID) oid, tmp); + /* 2..3 SEAL_ALG or Filler */ - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); + if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { + ptr[2] = sealalg & 0xff; + ptr[3] = (sealalg >> 8) & 0xff; + } else { + /* No seal */ + ptr[2] = 0xff; + ptr[3] = 0xff; + } - ptr = t; + /* 4..5 Filler */ + + ptr[4] = 0xff; + ptr[5] = 0xff; + + /* pad the plaintext, encrypt if needed, and stick it in the token */ + + /* initialize the the cksum */ + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + default: + case SGN_ALG_DES_MAC: + abort (); + } - g_make_token_header((gss_OID) oid, tmp, &ptr, toktype); + if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen)) + return(code); + md5cksum.length = sumlen; + + if (toktype == KG_TOK_SEAL_MSG) { + unsigned char *plain; + unsigned char pad; + + if (!bigend || encrypt) { + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + xfree(t); + return(ENOMEM); + } + + if ((code = kg_make_confounder(context, enc, plain))) { + xfree(plain); + xfree(t); + return(code); + } + + memcpy(plain+conflen, text->value, text->length); + + /* XXX 8 is DES cblock size */ + pad = 8-(text->length%8); + + memset(plain+conflen+text->length, pad, pad); + } else { + /* plain is never used in the bigend && !encrypt case */ + plain = NULL; + } + + if (encrypt) { + if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain, + (krb5_pointer) (ptr+cksum_size+14), + tmsglen))) { + if (plain) + xfree(plain); + xfree(t); + return(code); + } + } else { + if (bigend) + memcpy(ptr+14+cksum_size, text->value, text->length); + else + memcpy(ptr+14+cksum_size, plain, tmsglen); + } + + /* compute the checksum */ + + /* 8 = head of token body as specified by mech spec */ + if (! (data_ptr = + (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { + if (plain) + xfree(plain); + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); + if (bigend) + (void) memcpy(data_ptr+8, text->value, text->length); + else + (void) memcpy(data_ptr+8, plain, tmsglen); + plaind.length = 8 + (bigend ? text->length : tmsglen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, + KG_USAGE_SIGN, &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (plain) + xfree(plain); + xfree(t); + return(code); + } - ptr[0] = (ctype >> 24) & 0xff; - ptr[1] = (ctype >> 16) & 0xff; - ptr[2] = (ctype >> 8) & 0xff; - ptr[3] = ctype & 0xff; + if (plain) + xfree(plain); + } else { + /* Sign only. */ + /* compute the checksum */ - ptr += 4; + if (! (data_ptr = (char *) xmalloc(8 + text->length))) { + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, text->value, text->length); + plaind.length = 8 + text->length; + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, + KG_USAGE_SIGN, &plaind, &md5cksum); + xfree(data_ptr); + if (code) { + xfree(t); + return(code); + } + } - if (toktype == KG2_TOK_WRAP_INTEG) { - memcpy(ptr, plain.data, 7+text->length); - ptr += 7+text->length; - } else { - memcpy(ptr, plain.data, 5); - ptr += 5; + switch(signalg) { + case SGN_ALG_DES_MAC_MD5: + case 3: + + if ((code = kg_encrypt(context, seq, + (g_OID_equal(oid, gss_mech_krb5_old) ? + seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16))) { + xfree(md5cksum.contents); + xfree(t); + return code; + } + + cksum.length = cksum_size; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + memcpy(ptr+14, cksum.contents, cksum.length); + break; + + case SGN_ALG_HMAC_SHA1_DES3_KD: + /* + * Using key derivation, the call to krb5_c_make_checksum + * already dealt with encrypting. + */ + if (md5cksum.length != cksum_size) + abort (); + memcpy (ptr+14, md5cksum.contents, md5cksum.length); + break; } - ptr[0] = (cksum.length >> 8) & 0xff; - ptr[1] = cksum.length & 0xff; - ptr += 2; + xfree(md5cksum.contents); + + /* create the seq_num */ - memcpy(ptr, cksum.contents, cksum.length); + if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, + ptr+14, ptr+6))) { + xfree(t); + return(code); + } /* that's it. return the token */ @@ -247,372 +330,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, token->length = tlen; token->value = (void *) t; - code = 0; - -cleanup: - if (plain.data) - free(plain.data); - if (cksum.contents) - krb5_free_checksum_contents(context, &cksum); - if (code) { - if (t) - free(t); - } - - return(code); + return(0); } -static krb5_error_code -make_seal_token_v1 PROTOTYPE((krb5_context context, - krb5_keyblock *enc, - krb5_keyblock *seq, - krb5_int32 *seqnum, - int direction, - gss_buffer_t text, - gss_buffer_t token, - int signalg, - int cksum_size, - int sealalg, - int encrypt, - int toktype, - int bigend, - gss_OID oid)); +/* if signonly is true, ignore conf_req, conf_state, + and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ -static krb5_error_code -make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, - signalg, cksum_size, sealalg, encrypt, toktype, - bigend, oid) - krb5_context context; - krb5_keyblock *enc; - krb5_keyblock *seq; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - int signalg; - int cksum_size; - int sealalg; - int encrypt; - int toktype; - int bigend; - gss_OID oid; +OM_uint32 +kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, output_message_buffer, toktype) + krb5_context context; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + int qop_req; + gss_buffer_t input_message_buffer; + int *conf_state; + gss_buffer_t output_message_buffer; + int toktype; { - krb5_error_code code; - size_t sumlen; - char *data_ptr; - krb5_data plaind; - krb5_checksum md5cksum; - krb5_checksum cksum; - int conflen=0, tmsglen, tlen; - unsigned char *t, *ptr; - - /* create the token buffer */ - - if (toktype == KG_TOK_SEAL_MSG) { - if (bigend && !encrypt) { - tmsglen = text->length; - } else { - conflen = kg_confounder_size(context, enc); - /* XXX knows that des block size is 8 */ - tmsglen = (conflen+text->length+8)&(~7); - } - } else { - tmsglen = 0; - } - - tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); - - /*** fill in the token */ - - ptr = t; - - g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); - - /* 0..1 SIGN_ALG */ - - ptr[0] = signalg; - ptr[1] = 0; - - /* 2..3 SEAL_ALG or Filler */ - - if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { - ptr[2] = sealalg; - ptr[3] = 0; - } else { - /* No seal */ - ptr[2] = 0xff; - ptr[3] = 0xff; - } - - /* 4..5 Filler */ - - ptr[4] = 0xff; - ptr[5] = 0xff; - - /* pad the plaintext, encrypt if needed, and stick it in the token */ - - /* initialize the the cksum */ - if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) - return(code); - - md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = sumlen; - if (toktype == KG_TOK_SEAL_MSG) { - unsigned char *plain; - unsigned char pad; - - if (!bigend || encrypt) { - if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - xfree(t); - return(ENOMEM); - } - - if ((code = kg_make_confounder(context, enc, plain))) { - xfree(plain); - xfree(t); - return(code); - } - - memcpy(plain+conflen, text->value, text->length); - - /* XXX 8 is DES cblock size */ - pad = 8-(text->length%8); - - memset(plain+conflen+text->length, pad, pad); - } else { - /* plain is never used in the bigend && !encrypt case */ - plain = NULL; - } + krb5_gss_ctx_id_rec *ctx; + krb5_error_code code; + krb5_timestamp now; - if (encrypt) { - if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain, - (krb5_pointer) (ptr+cksum_size+14), - tmsglen))) { - if (plain) - xfree(plain); - xfree(t); - return(code); - } - } else { - if (bigend) - memcpy(ptr+14+cksum_size, text->value, text->length); - else - memcpy(ptr+14+cksum_size, plain, tmsglen); - } - - /* compute the checksum */ - - /* 8 = head of token body as specified by mech spec */ - if (! (data_ptr = - (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { - if (plain) - xfree(plain); - xfree(t); - return(ENOMEM); - } - (void) memcpy(data_ptr, ptr-2, 8); - if (bigend) - (void) memcpy(data_ptr+8, text->value, text->length); - else - (void) memcpy(data_ptr+8, plain, tmsglen); - plaind.length = 8 + (bigend ? text->length : tmsglen); - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, - 0, 0, &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (plain) - xfree(plain); - xfree(t); - return(code); - memcpy(ptr+14+cksum_size, plain, tmsglen); - } - - if (plain) - xfree(plain); - } else { - /* compute the checksum */ - - if (! (data_ptr = (char *) xmalloc(8 + text->length))) { - xfree(t); - return(ENOMEM); - } - (void) memcpy(data_ptr, ptr-2, 8); - (void) memcpy(data_ptr+8, text->value, text->length); - plaind.length = 8 + text->length; - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - if (code) { - xfree(t); - return(code); - } - } - - switch(signalg) { - case 0: - case 3: + output_message_buffer->length = 0; + output_message_buffer->value = NULL; + /* only default qop or matching established cryptosystem is allowed */ + #if 0 - /* XXX this depends on the key being a single-des key */ - - /* DES CBC doesn't use a zero IV like it should in some - krb5 implementations (beta5+). So we just do the - DES encryption the long way, and keep the last block - as the MAC */ - - /* XXX not converted to new api since it's inside an #if 0 */ - - /* initialize the the cksum and allocate the contents buffer */ - cksum.checksum_type = CKSUMTYPE_DESCBC; - cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); - if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) - return(ENOMEM); - - /* XXX not converted to new api since it's inside an #if 0 */ - if (code = krb5_calculate_checksum(context, cksum.checksum_type, - md5cksum.contents, 16, - seq->contents, - seq->length, - &cksum)) { - xfree(cksum.contents); - xfree(md5cksum.contents); - xfree(t); - return(code); - } - - memcpy(ptr+14, cksum.contents, 8); - - xfree(cksum.contents); + switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) { + case GSS_C_QOP_DEFAULT: + break; + default: + unknown_qop: + *minor_status = (OM_uint32) G_UNKNOWN_QOP; + return GSS_S_FAILURE; + case GSS_KRB5_CONF_C_QOP_DES: + if (ctx->sealalg != SEAL_ALG_DES) { + bad_qop: + *minor_status = (OM_uint32) G_BAD_QOP; + return GSS_S_FAILURE; + } + break; + case GSS_KRB5_CONF_C_QOP_DES3: + if (ctx->sealalg != SEAL_ALG_DES3) + goto bad_qop; + break; + } + switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) { + case GSS_C_QOP_DEFAULT: + break; + default: + goto unknown_qop; + case GSS_KRB5_INTEG_C_QOP_MD5: + case GSS_KRB5_INTEG_C_QOP_DES_MD5: + case GSS_KRB5_INTEG_C_QOP_DES_MAC: + if (ctx->sealalg != SEAL_ALG_DES) + goto bad_qop; + break; + case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1: + if (ctx->sealalg != SEAL_ALG_DES3KD) + goto bad_qop; + break; + } #else - if ((code = kg_encrypt(context, seq, - (g_OID_equal(oid, gss_mech_krb5_old) ? - seq->contents : NULL), - md5cksum.contents, md5cksum.contents, 16))) { - xfree(md5cksum.contents); - xfree(t); - return code; - } - - cksum.length = cksum_size; - cksum.contents = md5cksum.contents + 16 - cksum.length; - - memcpy(ptr+14, cksum.contents, cksum.length); + if (qop_req != 0) { + *minor_status = (OM_uint32) G_UNKNOWN_QOP; + return GSS_S_FAILURE; + } #endif - break; - } - - xfree(md5cksum.contents); - - /* create the seq_num */ + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } - if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, - ptr+14, ptr+6))) { - xfree(t); - return(code); - } + ctx = (krb5_gss_ctx_id_rec *) context_handle; - /* that's it. return the token */ + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } - (*seqnum)++; + if ((code = krb5_timeofday(context, &now))) { + *minor_status = code; + return(GSS_S_FAILURE); + } - token->length = tlen; - token->value = (void *) t; + code = make_seal_token_v1(context, ctx->enc, ctx->seq, + &ctx->seq_send, ctx->initiate, + input_message_buffer, output_message_buffer, + ctx->signalg, ctx->cksum_size, ctx->sealalg, + conf_req_flag, toktype, ctx->big_endian, + ctx->mech_used); - return(0); -} + if (code) { + *minor_status = code; + return(GSS_S_FAILURE); + } -/* if signonly is true, ignore conf_req, conf_state, - and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ + if (conf_state) + *conf_state = conf_req_flag; -OM_uint32 -kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, - input_message_buffer, conf_state, output_message_buffer, toktype) - krb5_context context; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - int conf_req_flag; - int qop_req; - gss_buffer_t input_message_buffer; - int *conf_state; - gss_buffer_t output_message_buffer; - int toktype; -{ - krb5_gss_ctx_id_rec *ctx; - krb5_error_code code; - krb5_timestamp now; - - output_message_buffer->length = 0; - output_message_buffer->value = NULL; - - /* only default qop is allowed */ - if (qop_req != GSS_C_QOP_DEFAULT) { - *minor_status = (OM_uint32) G_UNKNOWN_QOP; - return(GSS_S_FAILURE); - } - - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (ctx->gsskrb5_version == 2000) { - if (toktype == KG_TOK_WRAP_MSG) { - if (conf_req_flag) - toktype = KG2_TOK_WRAP_PRIV; - else - toktype = KG2_TOK_WRAP_INTEG; - } else { - toktype = KG2_TOK_MIC; - } - - if (conf_req_flag) { - code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send, - ctx->initiate, input_message_buffer, - output_message_buffer, ctx->mech_used); - } else { - code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0], - &ctx->seq_send, ctx->initiate, - input_message_buffer, - output_message_buffer, toktype, - ctx->mech_used); - } - } else { - code = make_seal_token_v1(context, ctx->enc, ctx->seq, - &ctx->seq_send, ctx->initiate, - input_message_buffer, output_message_buffer, - ctx->signalg, ctx->cksum_size, ctx->sealalg, - conf_req_flag, toktype, ctx->big_endian, - ctx->mech_used); - } - - if (code) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (conf_state) - *conf_state = conf_req_flag; - - *minor_status = 0; - return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); + *minor_status = 0; + return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 64a9539..a2deb43 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -1,6 +1,6 @@ /* * 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 @@ -10,7 +10,7 @@ * 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 @@ -22,14 +22,14 @@ /* * 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 @@ -40,7 +40,7 @@ * 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. @@ -53,834 +53,438 @@ * $Id$ */ -static OM_uint32 -kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, - text, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t text; - gss_qop_t *qop_state; +/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX + conf_state is only valid if SEAL. */ + +OM_uint32 +kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, + conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; { - size_t cksumlen; krb5_error_code code; - krb5_data plain; - krb5_cksumtype tctype; - krb5_ui_4 tseqnum; - int tdirection; + int tmsglen; + int conflen = 0; + int signalg; + int sealalg; + gss_buffer_desc token; krb5_checksum cksum; - krb5_boolean ckvalid; + krb5_checksum md5cksum; + krb5_data plaind; + char *data_ptr; krb5_timestamp now; + unsigned char *plain; + int cksum_len = 0; + int plainlen; + int direction; + krb5_int32 seqnum; OM_uint32 retval; + size_t sumlen; - plain.data = 0; - cksum.contents = 0; - - /* verify the header */ - - if (bodysize < 11) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + if (toktype == KG_TOK_SEAL_MSG) { + message_buffer->length = 0; + message_buffer->value = NULL; } - /* allocate the checksum buffer */ - - plain.length = 7+text->length; - - if ((plain.data = (char *) malloc(plain.length)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + /* get the sign and seal algorithms */ - /* suck out the body parts from the token */ + signalg = ptr[0] + (ptr[1]<<8); + sealalg = ptr[2] + (ptr[3]<<8); - tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | - (ptr[2]<<8) | ptr[3]); - ptr += 4; + /* Sanity checks */ - memcpy(plain.data, ptr, 5); - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; - - cksum.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 11; - - if (cksum.length != bodysize) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } - cksum.contents = ptr; - cksum.checksum_type = tctype; + if ((toktype != KG_TOK_SEAL_MSG) && + (sealalg != 0xffff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } - /* finish assembling the checksum buffer and compute the checksum */ + /* in the current spec, there is only one valid seal algorithm per + key type, so a simple comparison is ok */ - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; + if ((toktype == KG_TOK_SEAL_MSG) && + !((sealalg == 0xffff) || + (sealalg == ctx->sealalg))) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } - memcpy(plain.data+7, text->value, text->length); + /* there are several mappings of seal algorithms to sign algorithms, + but few enough that we can try them all. */ - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_MIC, - &plain, &cksum, &ckvalid)) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); + if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) || + (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) || + (ctx->sealalg == SEAL_ALG_DES3KD && + signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } - if (!ckvalid) { - free(plain.data); + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + cksum_len = 8; + break; + case SGN_ALG_3: + cksum_len = 16; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + cksum_len = 20; + break; + default: *minor_status = 0; - return(GSS_S_BAD_SIG); + return GSS_S_DEFECTIVE_TOKEN; } - /* check context expiry */ + if (toktype == KG_TOK_SEAL_MSG) + tmsglen = bodysize-(14+cksum_len); - if ((code = krb5_timeofday(context, &now))) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); - } + /* get the token parameters */ - if (now > ctx->endtime) { - free(plain.data); - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } + /* decode the message, if SEAL */ - /* do sequencing checks */ + if (toktype == KG_TOK_SEAL_MSG) { + if (sealalg != 0xffff) { + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - free(plain.data); - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } + if ((code = kg_decrypt(context, ctx->enc, NULL, + ptr+14+cksum_len, plain, tmsglen))) { + xfree(plain); + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + plain = ptr+14+cksum_len; + } - retval = g_order_check(&(ctx->seqstate), tseqnum); + plainlen = tmsglen; - free(plain.data); + if ((sealalg == 0xffff) && ctx->big_endian) { + token.length = tmsglen; + } else { + conflen = kg_confounder_size(context, ctx->enc); + token.length = tmsglen - conflen - plain[tmsglen-1]; + } - if (retval) { - *minor_status = 0; - return(retval); - } + if (token.length) { + if ((token.value = (void *) xmalloc(token.length)) == NULL) { + if (sealalg != 0xffff) + xfree(plain); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + memcpy(token.value, plain+conflen, token.length); + } + } else if (toktype == KG_TOK_SIGN_MSG) { + token = *message_buffer; + plain = token.value; + plainlen = token.length; + } else { + token.length = 0; + token.value = NULL; + plain = token.value; + plainlen = token.length; + } - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; + /* compute the checksum of the message */ + + /* initialize the the cksum */ + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + case SGN_ALG_DES_MAC: + case SGN_ALG_3: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + default: + abort (); + } - *minor_status = 0; - return(GSS_S_COMPLETE); -} + if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen)) + return(code); + md5cksum.length = sumlen; -static OM_uint32 -kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t output; - gss_qop_t *qop_state; -{ - krb5_error_code code; - OM_uint32 retval; - krb5_ui_4 tseqnum; - int tdirection; - int tmsglen; - unsigned char *tmsg; - krb5_data plain; - krb5_checksum tcksum; - krb5_boolean ckvalid; - krb5_timestamp now; + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_3: + /* compute the checksum of the message */ - output->length = 0; - output->value = NULL; + /* 8 = bytes of token body to be checksummed according to spec */ - /* read the body parts out of the message */ + if (! (data_ptr = (void *) + xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - if (bodysize < 11) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + (void) memcpy(data_ptr, ptr-2, 8); - tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | - (ptr[2]<<8) | ptr[3]); - ptr += 4; + if (ctx->big_endian) + (void) memcpy(data_ptr+8, token.value, token.length); + else + (void) memcpy(data_ptr+8, plain, plainlen); - plain.data = ptr; + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; + if ((code = kg_encrypt(context, ctx->seq, + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? + ctx->seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16))) { + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return GSS_S_FAILURE; + } - tmsglen = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 11; + if (signalg == 0) + cksum.length = 8; + else + cksum.length = 16; + cksum.contents = md5cksum.contents + 16 - cksum.length; - if (bodysize < tmsglen) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + code = memcmp(cksum.contents, ptr+14, cksum.length); + break; - tmsg = ptr; - ptr += tmsglen; - bodysize -= tmsglen; + case SGN_ALG_MD2_5: + if (!ctx->seed_init && + (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return GSS_S_FAILURE; + } - plain.length = ((char*)ptr) - ((char *)plain.data); + if (! (data_ptr = (void *) + xmalloc(sizeof(ctx->seed) + 8 + + (ctx->big_endian ? token.length : plainlen)))) { + xfree(md5cksum.contents); + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); + if (ctx->big_endian) + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + token.value, token.length); + else + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + plain, plainlen); + plaind.length = 8 + sizeof(ctx->seed) + + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + xfree(md5cksum.contents); + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - tcksum.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 2; + code = memcmp(md5cksum.contents, ptr+14, 8); + /* Falls through to defective-token?? */ - if (bodysize != tcksum.length) { - *minor_status = G_TOK_TRUNC; + default: + *minor_status = 0; return(GSS_S_DEFECTIVE_TOKEN); - } - - tcksum.contents = ptr; - /* verify the MIC */ + case SGN_ALG_HMAC_SHA1_DES3_KD: + /* compute the checksum of the message */ - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG, - &plain, &tcksum, &ckvalid)) { - *minor_status = code; - return(GSS_S_FAILURE); - } + /* 8 = bytes of token body to be checksummed according to spec */ - if (!ckvalid) { - *minor_status = 0; - return(GSS_S_BAD_SIG); - } + if (! (data_ptr = (void *) + xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - /* check context expiry */ - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (now > ctx->endtime) { - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } - - /* do sequencing checks */ - - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } - - if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { - *minor_status = 0; - return(retval); - } - - if (tmsglen) { - if ((output->value = (void *) malloc(tmsglen)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(output->value, tmsg, tmsglen); - output->length = tmsglen; - } - - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; - - *minor_status = 0; - return(GSS_S_COMPLETE); -} + (void) memcpy(data_ptr, ptr-2, 8); -static OM_uint32 -kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t output; - gss_qop_t *qop_state; -{ - krb5_error_code code; - OM_uint32 retval; - krb5_enc_data cipher; - krb5_data plain; - krb5_ui_4 tseqnum; - int tdirection; - int tmsglen; - unsigned char *tmsg; - krb5_timestamp now; + if (ctx->big_endian) + (void) memcpy(data_ptr+8, token.value, token.length); + else + (void) memcpy(data_ptr+8, plain, plainlen); - output->length = 0; - output->value = NULL; + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); - /* read the body parts out of the message */ + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - if (bodysize < 2) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + code = memcmp(md5cksum.contents, ptr+14, md5cksum.length); + break; } - cipher.ciphertext.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 2; + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); - if (bodysize != cipher.ciphertext.length) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + /* compare the computed checksum against the transmitted checksum */ - cipher.ciphertext.data = ptr; - cipher.enctype = ENCTYPE_UNKNOWN; - - plain.length = cipher.ciphertext.length; - if ((plain.data = (char *) malloc(plain.length)) == NULL) { + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); *minor_status = 0; - return(GSS_S_FAILURE); - } - - /* decrypt (and implicitly verify) the encrypted data */ - - if (code = krb5_c_decrypt(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, - 0, &cipher, &plain)) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); + return(GSS_S_BAD_SIG); } - /* parse out the encrypted fields */ - ptr = plain.data; - bodysize = plain.length; + /* it got through unscathed. Make sure the context is unexpired */ - if (bodysize < 7) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + if (toktype == KG_TOK_SEAL_MSG) + *message_buffer = token; - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; + if (conf_state) + *conf_state = (sealalg != 0xffff); - tmsglen = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 7; - - /* check context expiry */ + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; if ((code = krb5_timeofday(context, &now))) { - free(plain.data); *minor_status = code; return(GSS_S_FAILURE); } if (now > ctx->endtime) { - free(plain.data); *minor_status = 0; return(GSS_S_CONTEXT_EXPIRED); } /* do sequencing checks */ - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - free(plain.data); - *minor_status = G_BAD_DIRECTION; + if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, + &seqnum))) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; return(GSS_S_BAD_SIG); } - if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { - free(plain.data); - *minor_status = 0; - return(retval); - } - - /* now copy out the data. can't do a strict equality check here, - since the output could be padded. */ - - if (bodysize < tmsglen) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } - - tmsg = ptr; - - if (tmsglen) { - if ((output->value = (void *) malloc(tmsglen)) == NULL) { - free(plain.data); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(output->value, tmsg, tmsglen); - output->length = tmsglen; + if ((ctx->initiate && direction != 0xff) || + (!ctx->initiate && direction != 0)) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); } - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; + retval = g_order_check(&(ctx->seqstate), seqnum); - free(plain.data); + /* success or ordering violation */ *minor_status = 0; - return(GSS_S_COMPLETE); + return(retval); } /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX conf_state is only valid if SEAL. */ OM_uint32 -kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, - conf_state, qop_state, toktype) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t message_buffer; - int *conf_state; - int *qop_state; - int toktype; +kg_unseal(context, minor_status, context_handle, input_token_buffer, + message_buffer, conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_token_buffer; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; { - krb5_error_code code; - int tmsglen; - int conflen = 0; - int signalg; - int sealalg; - gss_buffer_desc token; - krb5_checksum cksum; - krb5_checksum desmac; - krb5_checksum md5cksum; - krb5_data plaind; - char *data_ptr; - krb5_timestamp now; - unsigned char *plain; - int cksum_len = 0; - int plainlen; - int err; - int direction; - krb5_int32 seqnum; - OM_uint32 retval; - size_t sumlen; - - if (toktype == KG_TOK_SEAL_MSG) { - message_buffer->length = 0; - message_buffer->value = NULL; - } - - /* get the sign and seal algorithms */ - - signalg = ptr[0] + (ptr[1]<<8); - sealalg = ptr[2] + (ptr[3]<<8); - - /* Sanity checks */ - - if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - if ((toktype != KG_TOK_SEAL_MSG) && - (sealalg != 0xffff)) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - /* in the current spec, there is only one valid seal algorithm per - key type, so a simple comparison is ok */ - - if ((toktype == KG_TOK_SEAL_MSG) && - !((sealalg == 0xffff) || - (sealalg == ctx->sealalg))) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - /* there are several mappings of seal algorithms to sign algorithms, - but few enough that we can try them all. */ - - if (((ctx->sealalg == 0) && - (signalg > 1)) || - ((ctx->sealalg == 1) && - (signalg != 3))) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - switch (signalg) { - case 0: - case 1: - cksum_len = 8; - break; - case 3: - cksum_len = 16; - break; - } - - if (toktype == KG_TOK_SEAL_MSG) - tmsglen = bodysize-(14+cksum_len); - - /* get the token parameters */ - - /* decode the message, if SEAL */ - - if (toktype == KG_TOK_SEAL_MSG) { - if (sealalg != 0xffff) { - if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + int err; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } - if ((code = kg_decrypt(context, ctx->enc, NULL, - ptr+14+cksum_len, plain, tmsglen))) { - xfree(plain); - *minor_status = code; - return(GSS_S_FAILURE); - } - } else { - plain = ptr+14+cksum_len; - } - - plainlen = tmsglen; - - if ((sealalg == 0xffff) && ctx->big_endian) { - token.length = tmsglen; - } else { - conflen = kg_confounder_size(context, ctx->enc); - token.length = tmsglen - conflen - plain[tmsglen-1]; - } - - if (token.length) { - if ((token.value = (void *) xmalloc(token.length)) == NULL) { - if (sealalg != 0xffff) - xfree(plain); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(token.value, plain+conflen, token.length); - } - } else if (toktype == KG_TOK_SIGN_MSG) { - token = *message_buffer; - plain = token.value; - plainlen = token.length; - } else { - token.length = 0; - token.value = NULL; - plain = token.value; - plainlen = token.length; - } - - /* compute the checksum of the message */ - - /* initialize the the cksum */ - if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) - return(code); - - md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = sumlen; - - switch (signalg) { - case 0: - case 3: - /* compute the checksum of the message */ - - /* 8 = bytes of token body to be checksummed according to spec */ - - if (! (data_ptr = (void *) - xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { - if (sealalg != 0xffff) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - (void) memcpy(data_ptr, ptr-2, 8); - - if (ctx->big_endian) - (void) memcpy(data_ptr+8, token.value, token.length); - else - (void) memcpy(data_ptr+8, plain, plainlen); - - plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - -#if 0 - /* XXX this depends on the key being a single-des key, but that's - all that kerberos supports right now */ - - /* initialize the the cksum and allocate the contents buffer */ - cksum.checksum_type = CKSUMTYPE_DESCBC; - cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); - if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) { - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - /* XXX not converted to new api since it's inside an #if 0 */ - if (code = krb5_calculate_checksum(context, cksum.checksum_type, - md5cksum.contents, 16, - ctx->seq.key->contents, - ctx->seq.key->length, - &cksum)) { - xfree(cksum.contents); - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - - code = memcmp(cksum.contents, ptr+14, cksum.length); - - xfree(cksum.contents); -#else - if ((code = kg_encrypt(context, ctx->seq, - (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq->contents : NULL), - md5cksum.contents, md5cksum.contents, 16))) { - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return GSS_S_FAILURE; - } - - if (signalg == 0) - cksum.length = 8; - else - cksum.length = 16; - cksum.contents = md5cksum.contents + 16 - cksum.length; - - code = memcmp(cksum.contents, ptr+14, cksum.length); -#endif - break; - - case 1: - if (!ctx->seed_init && - (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { - xfree(md5cksum.contents); - if (sealalg != 0xffff) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return GSS_S_FAILURE; - } - - if (! (data_ptr = (void *) - xmalloc(sizeof(ctx->seed) + 8 + - (ctx->big_endian ? token.length : plainlen)))) { - xfree(md5cksum.contents); - if (sealalg == 0) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - (void) memcpy(data_ptr, ptr-2, 8); - (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); - if (ctx->big_endian) - (void) memcpy(data_ptr+8+sizeof(ctx->seed), - token.value, token.length); - else - (void) memcpy(data_ptr+8+sizeof(ctx->seed), - plain, plainlen); - plaind.length = 8 + sizeof(ctx->seed) + - (ctx->big_endian ? token.length : plainlen); - plaind.data = data_ptr; - xfree(md5cksum.contents); - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (sealalg == 0) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - - code = memcmp(md5cksum.contents, ptr+14, 8); - - default: - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - - xfree(md5cksum.contents); - if (sealalg != 0xffff) - xfree(plain); - - /* compare the computed checksum against the transmitted checksum */ - - if (code) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = 0; - return(GSS_S_BAD_SIG); - } - - - /* it got through unscathed. Make sure the context is unexpired */ - - if (toktype == KG_TOK_SEAL_MSG) - *message_buffer = token; - - if (conf_state) - *conf_state = (sealalg != 0xffff); - - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (now > ctx->endtime) { - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } - - /* do sequencing checks */ - - if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, - &seqnum))) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_BAD_SIG); - } - - if ((ctx->initiate && direction != 0xff) || - (!ctx->initiate && direction != 0)) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } - - retval = g_order_check(&(ctx->seqstate), seqnum); - - /* success or ordering violation */ - - *minor_status = 0; - return(retval); -} + ctx = (krb5_gss_ctx_id_rec *) context_handle; -/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX - conf_state is only valid if SEAL. */ + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } -OM_uint32 -kg_unseal(context, minor_status, context_handle, input_token_buffer, - message_buffer, conf_state, qop_state, toktype) - krb5_context context; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_token_buffer; - gss_buffer_t message_buffer; - int *conf_state; - int *qop_state; - int toktype; -{ - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - int err; - OM_uint32 retval; - - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - /* parse the token, leave the data in message_buffer, setting conf_state */ - - /* verify the header */ - - ptr = (unsigned char *) input_token_buffer->value; - - if (ctx->gsskrb5_version == 2000) { - if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, KG2_TOK_MIC, - input_token_buffer->length))) { - return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, - message_buffer, qop_state)); - } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, - KG2_TOK_WRAP_INTEG, - input_token_buffer->length))) { - if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status, - ctx, ptr, bodysize, - message_buffer, qop_state))) - return(retval); - - if (conf_state) - *conf_state = 0; - return(GSS_S_COMPLETE); - } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, - KG2_TOK_WRAP_PRIV, - input_token_buffer->length))) { - if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status, - ctx, ptr, bodysize, - message_buffer, qop_state))) - return(retval); - - if (conf_state) - *conf_state = 1; - return(GSS_S_COMPLETE); - } - } else { - if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, toktype, - input_token_buffer->length))) { - return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, - message_buffer, conf_state, qop_state, - toktype)); - } - } - - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); + /* parse the token, leave the data in message_buffer, setting conf_state */ + + /* verify the header */ + + ptr = (unsigned char *) input_token_buffer->value; + + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, toktype, + input_token_buffer->length))) { + return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, + message_buffer, conf_state, qop_state, + toktype)); + } + + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); } diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 2a6231e..1989a7d 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -233,7 +233,6 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for seq_recv. * krb5_int32 for established. * krb5_int32 for big_endian. - * krb5_int32 for gsskrb5_version. * krb5_int32 for nctypes. * krb5_int32 for trailer. */ @@ -349,8 +348,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version, - &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes, &bp, &remain); @@ -477,8 +474,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->big_endian = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->gsskrb5_version = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->nctypes = (int) ibuf; if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index 10e6b65..47ffc5b 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -27,6 +27,7 @@ #include "gssapiP_krb5.h" #include <memory.h> +/* Checksumming the channel bindings always uses plain MD5. */ krb5_error_code kg_checksum_channel_bindings(context, cb, cksum, bigend) krb5_context context; diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 93d4694..8030139 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -54,8 +54,6 @@ * $Id$ */ -static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; - int kg_confounder_size(context, key) krb5_context context; @@ -136,9 +134,7 @@ kg_encrypt(context, key, iv, in, out, length) outputd.ciphertext.data = out; return(krb5_c_encrypt(context, key, - /* XXX this routine is only used for the old - bare-des stuff which doesn't use the - key usage */ 0, pivd, &inputd, &outputd)); + KG_USAGE_SEAL, pivd, &inputd, &outputd)); } /* length is the length of the cleartext. */ @@ -176,7 +172,5 @@ kg_decrypt(context, key, iv, in, out, length) outputd.data = out; return(krb5_c_decrypt(context, key, - /* XXX this routine is only used for the old - bare-des stuff which doesn't use the - key usage */ 0, pivd, &inputd, &outputd)); + KG_USAGE_SEAL, pivd, &inputd, &outputd)); } diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index f7fee73..55d4bce 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -66,6 +90,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, krb5_context context; krb5_gss_ctx_id_rec *ctx; krb5_error_code code; + OM_uint32 data_size, conflen; + OM_uint32 ohlen; + int overhead; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -88,92 +115,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, return(GSS_S_NO_CONTEXT); } - if (ctx->gsskrb5_version == 2000) { - if (conf_req_flag) { - /* this is pretty gross. take the max output, and call - krb5_c_encrypt_length to see how much overhead is added - on. subtract that much, and see if it fits in the - requested space. If not, start subtracting 1 until it - does. This doesn't necessarily give us the optimal - packing, but I think that's ok (I could start adding 1 - until I went over, but that seems like it's not worth - the effort). This is probably O(blocksize), but that's - never going to be large. */ - - OM_uint32 headerlen, plainlen; - size_t enclen; - - headerlen = g_token_size((gss_OID) ctx->mech_used, 2); - plainlen = req_output_size - headerlen; - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - plainlen -= plainlen - (enclen - plainlen); - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - while (headerlen + enclen > req_output_size) { - plainlen--; - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - } - - /* subtract off the fixed size inside the encrypted part */ - - plainlen -= 7; - - *max_input_size = plainlen; - } else { - size_t cksumlen; - OM_uint32 headerlen; - - if (code = krb5_c_checksum_length(context, ctx->ctypes[0], - &cksumlen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen); - - *max_input_size = req_output_size - headerlen; - } - } else { - OM_uint32 data_size, conflen; - OM_uint32 ohlen; - int overhead; - - /* Calculate the token size and subtract that from the output size */ - overhead = 7 + ctx->mech_used->length; - data_size = req_output_size; - if (conf_req_flag) { - conflen = kg_confounder_size(context, ctx->enc); - data_size = (conflen + data_size + 8) & (~7); - } - ohlen = g_token_size((gss_OID) ctx->mech_used, - (unsigned int) (data_size + ctx->cksum_size + 14)) - - req_output_size; - - if (ohlen+overhead < req_output_size) - /* - * Cannot have trailer length that will cause us to pad over - * our length - */ - *max_input_size = (req_output_size - ohlen - overhead) & (~7); - else - *max_input_size = 0; - } + /* Calculate the token size and subtract that from the output size */ + overhead = 7 + ctx->mech_used->length; + data_size = req_output_size; + conflen = kg_confounder_size(context, ctx->enc); + data_size = (conflen + data_size + 8) & (~(OM_uint32)7); + ohlen = g_token_size((gss_OID) ctx->mech_used, + (unsigned int) (data_size + ctx->cksum_size + 14)) + - req_output_size; + + if (ohlen+overhead < req_output_size) + /* + * Cannot have trailer length that will cause us to pad over our + * length. + */ + *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7); + else + *max_input_size = 0; *minor_status = 0; return(GSS_S_COMPLETE); diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog index a2ab81a..ddaef06 100644 --- a/src/lib/krb5/ChangeLog +++ b/src/lib/krb5/ChangeLog @@ -1,3 +1,7 @@ +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (SHLIB_EXPLIBS): Add @RESOLV_LIB@. + 2000-03-14 Ken Raeburn <raeburn@mit.edu> * configure.in: Check for gethostbyname2. diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 0dab1f3..1c9c558c 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -58,7 +58,7 @@ RELDIR=krb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(TOPLIBD)/libcom_err$(SHLIBEXT) -SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ +SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ @RESOLV_LIB@ SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 59d8765..45517bf 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,26 @@ +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * init_ctx.c (krb5_free_ktypes): New routine, to free values + returned by krb5_get_tgs_ktypes, krb5_get_permitted_enctypes, and + krb5_get_default_in_tkt_ktypes. + (krb5_set_default_tgs_ktypes, krb5_is_permitted_enctype): Use it. + (get_profile_etype_list): Use passed-in enctype list if the + passed-in count is non-zero, instead of checking the + in_tkt_ktype_count value in the context. + +2000-04-08 Tom Yu <tlyu@mit.edu> + + * vfy_increds.c (krb5_verify_init_creds): appdefault_boolean -> + libdefault_boolean; it somehow got missed earlier. + +2000-04-07 Jeffrey Altman <jaltman@columbia.edu> + + * gic_pwd.c (krb5_get_init_creds_keytab), gic_pwd.c (krb5_get_init_creds_password) + when determining whether or not to retry with a "master kdc" do not retry if + the return value from the first attempt was KRB5_REALM_CANT_RESOLV. Also, do + not overwrite the return code if the return value from the access to the "master + kdc" was KRB5_REALM_CANT_RESOLV. + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * init_ctx.c (init_common), gic_pwd.c (krb5_get_as_key_password, diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index c1c6df1..9686f57 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -84,13 +84,13 @@ static krb5_error_code make_preauth_list PROTOTYPE((krb5_context, */ static krb5_error_code send_as_request(context, request, time_now, ret_err_reply, ret_as_reply, - master) + use_master) krb5_context context; krb5_kdc_req *request; krb5_timestamp *time_now; krb5_error ** ret_err_reply; krb5_kdc_rep ** ret_as_reply; - int * master; + int use_master; { krb5_kdc_rep *as_reply = 0; krb5_error_code retval; @@ -116,7 +116,7 @@ send_as_request(context, request, time_now, ret_err_reply, ret_as_reply, k4_version = packet->data[0]; retval = krb5_sendto_kdc(context, packet, krb5_princ_realm(context, request->client), - &reply, master); + &reply, use_master); krb5_free_data(context, packet); if (retval) goto cleanup; @@ -559,7 +559,7 @@ cleanup: return (retval); } -/* begin appdefaults parsing code. This should almost certainly move +/* begin libdefaults parsing code. This should almost certainly move somewhere else, but I don't know where the correct somewhere else is yet. */ @@ -595,7 +595,7 @@ _krb5_conf_boolean(s) } static krb5_error_code -krb5_appdefault_string(context, realm, option, ret_value) +krb5_libdefault_string(context, realm, option, ret_value) krb5_context context; const krb5_data *realm; const char *option; @@ -673,7 +673,7 @@ goodbye: /* as well as the DNS code */ krb5_error_code -krb5_appdefault_boolean(context, realm, option, ret_value) +krb5_libdefault_boolean(context, realm, option, ret_value) krb5_context context; const char *option; const krb5_data *realm; @@ -682,7 +682,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value) char *string = NULL; krb5_error_code retval; - retval = krb5_appdefault_string(context, realm, option, &string); + retval = krb5_libdefault_string(context, realm, option, &string); if (retval) return(retval); @@ -696,7 +696,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value) KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_init_creds(context, creds, client, prompter, prompter_data, start_time, in_tkt_service, options, gak_fct, gak_data, - master, as_reply) + use_master, as_reply) krb5_context context; krb5_creds *creds; krb5_principal client; @@ -707,7 +707,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, krb5_get_init_creds_opt *options; krb5_gic_get_as_key_fct gak_fct; void *gak_data; - int *master; + int use_master; krb5_kdc_rep **as_reply; { krb5_error_code ret; @@ -751,7 +751,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)) tempint = options->forwardable; - else if ((ret = krb5_appdefault_boolean(context, &client->realm, + else if ((ret = krb5_libdefault_boolean(context, &client->realm, "forwardable", &tempint)) == 0) ; else @@ -763,7 +763,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)) tempint = options->proxiable; - else if ((ret = krb5_appdefault_boolean(context, &client->realm, + else if ((ret = krb5_libdefault_boolean(context, &client->realm, "proxiable", &tempint)) == 0) ; else @@ -775,7 +775,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)) { renew_life = options->renew_life; - } else if ((ret = krb5_appdefault_string(context, &client->realm, + } else if ((ret = krb5_libdefault_string(context, &client->realm, "renew_lifetime", &tempstr)) == 0) { if (ret = krb5_string_to_deltat(tempstr, &renew_life)) { @@ -868,7 +868,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, } /* it would be nice if this parsed out an address list, but that would be work. */ - else if (((ret = krb5_appdefault_boolean(context, &client->realm, + else if (((ret = krb5_libdefault_boolean(context, &client->realm, "noaddresses", &tempint)) == 0) && tempint) { ; @@ -923,7 +923,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, err_reply = 0; local_as_reply = 0; if ((ret = send_as_request(context, &request, &time_now, &err_reply, - &local_as_reply, master))) + &local_as_reply, use_master))) goto cleanup; if (err_reply) { diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c index 8b6f231..98bbbd0 100644 --- a/src/lib/krb5/krb/gic_keytab.c +++ b/src/lib/krb5/krb/gic_keytab.c @@ -61,7 +61,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, krb5_get_init_creds_opt *options; { krb5_error_code ret, ret2; - int master; + int use_master; krb5_keytab keytab; if (arg_keytab == NULL) { @@ -71,14 +71,14 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, keytab = arg_keytab; } - master = 0; + use_master = 0; /* first try: get the requested tkt from any kdc */ ret = krb5_get_init_creds(context, creds, client, NULL, NULL, start_time, in_tkt_service, options, krb5_get_as_key_keytab, (void *) keytab, - &master, NULL); + use_master,NULL); /* check for success */ @@ -87,19 +87,19 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, /* If all the kdc's are unavailable fail */ - if (ret == KRB5_KDC_UNREACH) + if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ - if (!master) { - master = 1; + if (!use_master) { + use_master = 1; ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL, start_time, in_tkt_service, options, krb5_get_as_key_keytab, (void *) keytab, - &master, NULL); + use_master, NULL); if (ret2 == 0) { ret = 0; @@ -109,7 +109,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, /* if the master is unreachable, return the error from the slave we were able to contact */ - if (ret2 == KRB5_KDC_UNREACH) + if ((ret2 == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; ret = ret2; diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 7ca4343..86a1480 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -97,7 +97,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, krb5_get_init_creds_opt *options; { krb5_error_code ret, ret2; - int master; + int use_master; krb5_kdc_rep *as_reply; int tries; krb5_creds chpw_creds; @@ -107,7 +107,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, krb5_prompt prompt[2]; krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])]; - master = 0; + use_master = 0; as_reply = NULL; memset(&chpw_creds, 0, sizeof(chpw_creds)); @@ -133,7 +133,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, ret = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); /* check for success */ @@ -144,19 +144,20 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, user interrupt, fail */ if ((ret == KRB5_KDC_UNREACH) || - (ret == KRB5_LIBOS_PWDINTR)) + (ret == KRB5_LIBOS_PWDINTR) || + (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ - if (!master) { - master = 1; + if (!use_master) { + use_master = 1; ret2 = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); if (ret2 == 0) { ret = 0; @@ -166,7 +167,8 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, /* if the master is unreachable, return the error from the slave we were able to contact */ - if (ret2 == KRB5_KDC_UNREACH) + if ((ret2 == KRB5_KDC_UNREACH) || + (ret2 == KRB5_REALM_CANT_RESOLVE)) goto cleanup; ret = ret2; @@ -195,7 +197,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, prompter, data, start_time, "kadmin/changepw", &chpw_opts, krb5_get_as_key_password, (void *) &pw0, - &master, NULL))) + use_master, NULL))) goto cleanup; prompt[0].prompt = "Enter new password"; @@ -282,7 +284,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, ret = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); cleanup: krb5int_set_prompt_types(context, 0); diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index e2eccc4..dae8db3 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -1,7 +1,7 @@ /* * lib/krb5/krb/init_ctx.c * - * Copyright 1994 by the Massachusetts Institute of Technology. + * Copyright 1994,1999,2000 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -281,7 +281,7 @@ get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list) { krb5_enctype *old_ktypes; - if (context->in_tkt_ktype_count) { + if (ctx_count) { /* application-set defaults */ if ((old_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * @@ -396,12 +396,20 @@ krb5_set_default_tgs_ktypes(context, ktypes) } if (context->tgs_ktypes) - free(context->tgs_ktypes); + krb5_free_ktypes(context, context->tgs_ktypes); context->tgs_ktypes = new_ktypes; context->tgs_ktype_count = i; return 0; } +void +krb5_free_ktypes (context, val) + krb5_context context; + krb5_enctype FAR *val; +{ + free (val); +} + krb5_error_code krb5_get_tgs_ktypes(context, princ, ktypes) krb5_context context; @@ -441,7 +449,7 @@ krb5_is_permitted_enctype(context, etype) if (*ptr == etype) ret = 1; - krb5_xfree(list); + krb5_free_ktypes (context, list); return(ret); } diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c index 85a8465..f046ab5 100644 --- a/src/lib/krb5/krb/vfy_increds.c +++ b/src/lib/krb5/krb/vfy_increds.c @@ -109,7 +109,7 @@ krb5_verify_init_creds(krb5_context context, (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) { if (options->ap_req_nofail) goto cleanup; - } else if ((ret2 = krb5_appdefault_boolean(context, + } else if ((ret2 = krb5_libdefault_boolean(context, &creds->client->realm, "verify_ap_req_nofail", &nofail)) diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 8f8c018..defdbb1 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,33 @@ +2000-04-22 Ken Raeburn <raeburn@mit.edu> + + * localaddr.c: Include stddef.h. + (foreach_localaddr): Check each address against previously used + addresses, and skip duplicates, in case multiple interfaces have + the same address. If called functions fail, drop out of loop and + return nonzero. + (krb5_os_localaddr): Increment count of addresses to include null + pointer terminator. Delete check for zero count. + +2000-04-18 Danilo Almeida <dalmeida@mit.edu> + + * prompter.c (krb5int_set_prompt_types): Set to actual value + intead of 0. + +2000-04-04 Ken Raeburn <raeburn@mit.edu> + + * locate_kdc.c (maybe_use_dns): Renamed from _krb5_use_dns. Now + takes an arg to indicate a key to look up in krb5.conf, falling + back to "dns_fallback", and an arg indicating the default value if + no config file entries match. + (_krb5_use_dns_realm): New routine; use "dns_lookup_realm" and + KRB5_DNS_LOOKUP_REALM setting. + (_krb5_use_dns_kdc): New routine; use "dns_lookup_kdc" and + KRB5_DNS_LOOKUP_KDC. + (krb5_locate_kdc): Call _krb5_use_dns_kdc. + * changepw.c (krb5_locate_kpasswd): Call _krb5_use_dns_kdc. + * def_realm.c (krb5_get_default_realm): Call _krb5_use_dns_realm. + * hst_realm.c (krb5_get_host_realm): Call _krb5_use_dns_realm. + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * prompter.c: Add krb5int_set_prompt_types() and diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c index 6ed95bc..575866e 100644 --- a/src/lib/krb5/os/changepw.c +++ b/src/lib/krb5/os/changepw.c @@ -53,31 +53,24 @@ */ static krb5_error_code -krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) +krb5_locate_kpasswd(context, realm, addr_pp, naddrs) krb5_context context; const krb5_data *realm; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; { krb5_error_code code; int i; -#ifdef KRB5_DNS_LOOKUP - struct sockaddr *admin_addr_p, *kdc_addr_p; - int nadmin_addrs, nkdc_addrs; - int j; -#endif /* KRB5_DNS_LOOKUP */ /* * We always try the local file first */ - code = krb5_locate_srv_conf(context, realm, "kpasswd_server", addr_pp, naddrs, - master_index, nmasters); + code = krb5_locate_srv_conf(context, realm, "kpasswd_server", + addr_pp, naddrs, 0); if (code) { - code = krb5_locate_srv_conf(context, realm, "admin_server", addr_pp, naddrs, - master_index, nmasters); + code = krb5_locate_srv_conf(context, realm, "admin_server", + addr_pp, naddrs, 0); if ( !code ) { /* success with admin_server but now we need to change the port */ /* number to use DEFAULT_KPASSWD_PORT. */ @@ -90,7 +83,7 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) #ifdef KRB5_DNS_LOOKUP if (code) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_kdc(context); if ( use_dns ) { code = krb5_locate_srv_dns(realm, "_kpasswd", "_udp", addr_pp, naddrs); @@ -108,10 +101,6 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) } } } - if ( !code && master_index && nmasters ) { - *master_index = 1; - *nmasters = *naddrs; - } } } #endif /* KRB5_DNS_LOOKUP */ @@ -158,7 +147,7 @@ krb5_change_password(context, creds, newpw, result_code, if (code = krb5_locate_kpasswd(context, krb5_princ_realm(context, creds->client), - &addr_p, &naddr_p,NULL,NULL)) + &addr_p, &naddr_p)) goto cleanup; /* this is really obscure. s1 is used for all communications. it diff --git a/src/lib/krb5/os/def_realm.c b/src/lib/krb5/os/def_realm.c index 8647f89..7c2bfe2 100644 --- a/src/lib/krb5/os/def_realm.c +++ b/src/lib/krb5/os/def_realm.c @@ -103,7 +103,7 @@ krb5_get_default_realm(context, lrealm) #ifdef KRB5_DNS_LOOKUP if (context->default_realm == 0) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_realm(context); if ( use_dns ) { /* * Since this didn't appear in our config file, try looking diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c index 3c0005c..d8a72e0 100644 --- a/src/lib/krb5/os/hst_realm.c +++ b/src/lib/krb5/os/hst_realm.c @@ -312,7 +312,7 @@ krb5_get_host_realm(context, host, realmsp) #ifdef KRB5_DNS_LOOKUP if (realm == (char *)NULL) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_realm(context); if ( use_dns ) { /* * Since this didn't appear in our config file, try looking diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index 9079500..7398ce5 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -1,7 +1,7 @@ /* * lib/krb5/os/localaddr.c * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * Copyright 1990,1991,2000 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -39,6 +39,7 @@ #include <sys/ioctl.h> #include <sys/time.h> #include <errno.h> +#include <stddef.h> /* * The SIOCGIF* ioctls require a socket. @@ -255,13 +256,14 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) int (*betweenfn) (void *); int (*pass2fn) (void *, struct sockaddr *); { - struct ifreq *ifr, ifreq; + struct ifreq *ifr, ifreq, *ifr2; struct ifconf ifc; - int s, code, n, i; + int s, code, n, i, j; int est_if_count = 8, est_ifreq_size; char *buf = 0; size_t current_buf_size = 0; - + int fail = 0; + s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) return SOCKET_ERRNO; @@ -312,26 +314,49 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); - if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0 -#ifdef IFF_LOOPBACK - /* None of the current callers want loopback addresses. */ - || (ifreq.ifr_flags & IFF_LOOPBACK) -#endif - /* Ignore interfaces that are down. */ - || !(ifreq.ifr_flags & IFF_UP)) { + if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + skip: /* mark for next pass */ ifr->ifr_name[0] = 0; continue; } +#ifdef IFF_LOOPBACK + /* None of the current callers want loopback addresses. */ + if (ifreq.ifr_flags & IFF_LOOPBACK) + goto skip; +#endif + /* Ignore interfaces that are down. */ + if (!(ifreq.ifr_flags & IFF_UP)) + goto skip; + + /* Make sure we didn't process this address already. */ + for (j = 0; j < i; j += ifreq_size(*ifr2)) { + ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j); + if (ifr2->ifr_name[0] == 0) + continue; + if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family + && ifreq_size (*ifr) == ifreq_size (*ifr2) + /* Compare address info. If this isn't good enough -- + i.e., if random padding bytes turn out to differ + when the addresses are the same -- then we'll have + to do it on a per address family basis. */ + && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data, + (ifreq_size (*ifr) + - offsetof (struct ifreq, ifr_addr.sa_data)))) + goto skip; + } + if ((*pass1fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } if (betweenfn && (*betweenfn)(data)) { - abort (); + fail = 1; + goto punt; } if (pass2fn) @@ -343,13 +368,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; if ((*pass2fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } + punt: closesocket(s); free (buf); - return 0; + return fail; } @@ -376,10 +403,9 @@ krb5_os_localaddr(context, addr) return r; } + data.cur_idx++; /* null termination */ if (data.mem_err) return ENOMEM; - else if (data.cur_idx == 0) - abort (); else if (data.cur_idx == data.count) *addr = data.addr_temp; else { diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index fcdfa03..2cabf84 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -53,29 +53,57 @@ #define KPASSWD_PORTNAME "kpasswd" #endif -int -_krb5_use_dns(context) - krb5_context context; +#if KRB5_DNS_LOOKUP_KDC +#define DEFAULT_LOOKUP_KDC 1 +#else +#define DEFAULT_LOOKUP_KDC 0 +#endif +#if KRB5_DNS_LOOKUP_REALM +#define DEFAULT_LOOKUP_REALM 1 +#else +#define DEFAULT_LOOKUP_REALM 0 +#endif + +static int +maybe_use_dns (context, name, defalt) + krb5_context context; + const char *name; + int defalt; { krb5_error_code code; char * value = NULL; int use_dns = 0; code = profile_get_string(context->profile, "libdefaults", - "dns_fallback", 0, - context->profile_in_memory?"1":"0", - &value); + name, 0, 0, &value); + if (value == 0 && code == 0) + code = profile_get_string(context->profile, "libdefaults", + "dns_fallback", 0, 0, &value); if (code) - return(code); + return defalt; - if (value) { - use_dns = _krb5_conf_boolean(value); - profile_release_string(value); - } + if (value == 0) + return defalt; + use_dns = _krb5_conf_boolean(value); + profile_release_string(value); return use_dns; } +int +_krb5_use_dns_kdc(context) + krb5_context context; +{ + return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC); +} + +int +_krb5_use_dns_realm(context) + krb5_context context; +{ + return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM); +} + #endif /* KRB5_DNS_LOOKUP */ /* @@ -85,14 +113,13 @@ _krb5_use_dns(context) */ krb5_error_code -krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmasters) +krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters) krb5_context context; const krb5_data *realm; const char * name; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; + int get_masters; { const char *realm_srv_names[4]; char **masterlist, **hostlist, *host, *port, *cp; @@ -162,10 +189,7 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste return 0; } - if (master_index) { - *master_index = 0; - *nmasters = 0; - + if (get_masters) { realm_srv_names[0] = "realms"; realm_srv_names[1] = host; realm_srv_names[2] = "admin_server"; @@ -209,8 +233,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count); if (addr_p == NULL) { - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); return ENOMEM; } @@ -239,12 +265,12 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste if (masterlist) { for (j=0; masterlist[j]; j++) { if (strcasecmp(hostlist[i], masterlist[j]) == 0) { - *master_index = out; ismaster = 1; } } } + if ( !get_masters || ismaster ) { switch (hp->h_addrtype) { #ifdef HAVE_NETINET_IN_H @@ -263,8 +289,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste realloc ((char *)addr_p, sizeof(struct sockaddr) * count); if (addr_p == NULL) { - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); return ENOMEM; } } @@ -279,12 +307,13 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste default: break; } - if (ismaster) - *nmasters = out - *master_index; + } } - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); if (out == 0) { /* Couldn't resolve any KDC names */ free (addr_p); @@ -564,78 +593,29 @@ krb5_locate_srv_dns(realm, service, protocol, addr_pp, naddrs) */ krb5_error_code -krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) +krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters) krb5_context context; const krb5_data *realm; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; + int get_masters; { krb5_error_code code; -#ifdef KRB5_DNS_LOOKUP - struct sockaddr *admin_addr_p, *kdc_addr_p; - int nadmin_addrs, nkdc_addrs; - int i,j; -#endif /* KRB5_DNS_LOOKUP */ /* * We always try the local file first */ code = krb5_locate_srv_conf(context, realm, "kdc", addr_pp, naddrs, - master_index, nmasters); + get_masters); #ifdef KRB5_DNS_LOOKUP if (code) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_kdc(context); if ( use_dns ) { - code = krb5_locate_srv_dns(realm, "_kerberos", "_udp", - addr_pp, naddrs); - if ( master_index && nmasters ) { - - code = krb5_locate_srv_dns(realm, "_kerberos-adm", "_tcp", - &admin_addr_p, &nadmin_addrs); - if ( code ) { - free(*addr_pp); - *addr_pp = NULL; - *naddrs = 0; - return(code); - } - - kdc_addr_p = *addr_pp; - nkdc_addrs = *naddrs; - - *naddrs = 0; - *addr_pp = (struct sockaddr *) malloc(sizeof(*kdc_addr_p)); - if ( *addr_pp == NULL ) { - free(kdc_addr_p); - free(admin_addr_p); - return ENOMEM; - } - - for ( i=0; i<nkdc_addrs; i++ ) { - for ( j=0 ; j<nadmin_addrs; j++) { - if ( !memcmp(&kdc_addr_p[i].sa_data[2],&admin_addr_p[j].sa_data[2],4) ) { - memcpy(&(*addr_pp)[(*naddrs)],&kdc_addr_p[i], - sizeof(struct sockaddr)); - (*naddrs)++; - break; - } - } - } - - free(kdc_addr_p); - free(admin_addr_p); - - if ( *naddrs == 0 ) { - free(*addr_pp); - *addr_pp = NULL; - return KRB5_REALM_CANT_RESOLVE; - } - *master_index = 1; - *nmasters = *naddrs; - } + code = krb5_locate_srv_dns(realm, + get_masters ? "_kerberos-master" : "_kerberos", + "_udp", addr_pp, naddrs); } } #endif /* KRB5_DNS_LOOKUP */ diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h index fed7a81..a6b67f1 100644 --- a/src/lib/krb5/os/os-proto.h +++ b/src/lib/krb5/os/os-proto.h @@ -36,8 +36,7 @@ krb5_error_code krb5_locate_kdc const krb5_data *, struct sockaddr **, int *, - int *, - int *)); + int)); #endif #ifdef HAVE_NETINET_IN_H diff --git a/src/lib/krb5/os/prompter.c b/src/lib/krb5/os/prompter.c index 933ff2c..985ed6e 100644 --- a/src/lib/krb5/os/prompter.c +++ b/src/lib/krb5/os/prompter.c @@ -235,7 +235,7 @@ krb5int_set_prompt_types(context, types) krb5_context context; krb5_prompt_type *types; { - context->prompt_types = 0; + context->prompt_types = types; } KRB5_DLLIMP diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index 01b797e..47f2408 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -60,16 +60,16 @@ extern int krb5_skdc_timeout_shift; extern int krb5_skdc_timeout_1; krb5_error_code -krb5_sendto_kdc (context, message, realm, reply, master) +krb5_sendto_kdc (context, message, realm, reply, use_master) krb5_context context; const krb5_data * message; const krb5_data * realm; krb5_data * reply; - int *master; + int use_master; { register int timeout, host, i; struct sockaddr *addr; - int naddr, master_index, nmasters; + int naddr; int sent, nready; krb5_error_code retval; SOCKET *socklist; @@ -81,14 +81,10 @@ krb5_sendto_kdc (context, message, realm, reply, master) * find KDC location(s) for realm */ - if (retval = krb5_locate_kdc (context, realm, &addr, &naddr, - master?&master_index:NULL, - master?&nmasters:NULL)) + if (retval = krb5_locate_kdc (context, realm, &addr, &naddr, use_master)) return retval; if (naddr == 0) - return KRB5_REALM_UNKNOWN; - if (master && (*master == 1) && (nmasters == 0)) - return KRB5_KDC_UNREACH; + return (use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN); socklist = (SOCKET *)malloc(naddr * sizeof(SOCKET)); if (socklist == NULL) { @@ -128,12 +124,6 @@ krb5_sendto_kdc (context, message, realm, reply, master) timeout <<= krb5_skdc_timeout_shift) { sent = 0; for (host = 0; host < naddr; host++) { - /* if a master kdc is required, skip the non-master kdc's */ - - if (master && (*master == 1) && - ((host < master_index) || (host >= (master_index+nmasters)))) - continue; - /* send to the host, wait timeout seconds for a response, then move on. */ /* cache some sockets for each host */ @@ -211,12 +201,6 @@ krb5_sendto_kdc (context, message, realm, reply, master) reply->length = cc; retval = 0; - /* if the caller asked to be informed if it - got a master kdc, tell it */ - if (master) - *master = ((host >= master_index) && - (host < (master_index+nmasters))); - goto out; } else if (nready == 0) { /* timeout */ diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c index 0846b1c..a95c67a 100644 --- a/src/lib/krb5/os/t_std_conf.c +++ b/src/lib/krb5/os/t_std_conf.c @@ -110,14 +110,14 @@ void test_locate_kdc(ctx, realm) struct sockaddr *addrs; struct sockaddr_in *sin; int i, naddrs; - int master_index, nmasters; + int get_masters=0; krb5_data rlm; krb5_error_code retval; rlm.data = realm; rlm.length = strlen(realm); retval = krb5_locate_kdc(ctx, &rlm, &addrs, &naddrs, - &master_index, &nmasters); + get_masters); if (retval) { com_err("krb5_get_krbhst", retval, 0); return; diff --git a/src/util/pty/ChangeLog b/src/util/pty/ChangeLog index ff815b7..1986967 100644 --- a/src/util/pty/ChangeLog +++ b/src/util/pty/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/util/pty/configure.in b/src/util/pty/configure.in index 398b182..58ceb83 100644 --- a/src/util/pty/configure.in +++ b/src/util/pty/configure.in @@ -30,7 +30,7 @@ ac_cv_func_setsid=no # setsid doesn't do the right thing under Ultrix even thoug # Moreover, strops.h trashes sys/ioctl.h krb5_cv_has_streams=no ;; -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,main, AC_DEFINE(HAVE_SETLUID) LOGINLIBS="$LOGINLIBS -lsecurity" diff --git a/src/windows/ChangeLog b/src/windows/ChangeLog index ce20631..23bc3ec 100644 --- a/src/windows/ChangeLog +++ b/src/windows/ChangeLog @@ -1,3 +1,7 @@ +2000-04-25 Danilo Almeida <dalmeida@mit.edu> + + * version.rc: Bump version to 1.2 beta. + 2000-02-06 Danilo Almeida <dalmeida@mit.edu> * README: Add documentation about debug vs. release builds. diff --git a/src/windows/version.rc b/src/windows/version.rc index 67660fc..ba5e1a1 100644 --- a/src/windows/version.rc +++ b/src/windows/version.rc @@ -5,6 +5,16 @@ * BEGIN COMMON VERSION INFO for GSS and Kerberos version resources */ +#define PRE_RELEASE + +#ifdef PRE_RELEASE +#define BETA_STR " beta" +#define BETA_FLAG VS_FF_PRERELEASE +#else +#define BETA_STR "" +#define BETA_FLAG 0 +#endif + #if !defined(_WIN32) #define Targ_OS VOS__WINDOWS16 #else @@ -13,10 +23,10 @@ /* we're going to stamp all the DLLs with the same version number */ -#define K5_PRODUCT_VERSION_STRING "1.1.1\0" -#define K5_PRODUCT_VERSION 1, 1, 1, 0 +#define K5_PRODUCT_VERSION_STRING "1.2" BETA_STR "\0" +#define K5_PRODUCT_VERSION 1, 2, 0, 0 -#define K5_COPYRIGHT "Copyright (C) 1997-1999 by the Massachusetts Institute of Technology\0" +#define K5_COPYRIGHT "Copyright (C) 1997-2000 by the Massachusetts Institute of Technology\0" #define K5_COMPANY_NAME "Massachusetts Institute of Technology.\0" /* @@ -134,7 +144,7 @@ VS_VERSION_INFO VERSIONINFO FILEVERSION K5_PRODUCT_VERSION PRODUCTVERSION K5_PRODUCT_VERSION FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD) +FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD | BETA_FLAG) FILEOS Targ_OS FILETYPE K5_FILETYPE BEGIN |