svn rev #21769: branches/mkey_migrate/src/ include/ kadmin/passwd/unit-test/ ...

wfiveash@MIT.EDU wfiveash at MIT.EDU
Wed Jan 21 14:16:39 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=21769
Commit By: wfiveash
Log Message:
Merge with current head of trunk:
svn merge -r21722:HEAD svn+ssh://wfiveash@svn.mit.edu/krb5/trunk

Everything compiles.



Changed Files:
U   branches/mkey_migrate/src/include/k5-int.h
U   branches/mkey_migrate/src/kadmin/passwd/unit-test/Makefile.in
U   branches/mkey_migrate/src/kadmin/passwd/unit-test/config/unix.exp
U   branches/mkey_migrate/src/kadmin/server/network.c
U   branches/mkey_migrate/src/kdc/do_as_req.c
U   branches/mkey_migrate/src/kdc/do_tgs_req.c
U   branches/mkey_migrate/src/kdc/kdc_preauth.c
U   branches/mkey_migrate/src/kdc/kdc_util.c
U   branches/mkey_migrate/src/kdc/kdc_util.h
U   branches/mkey_migrate/src/kdc/network.c
U   branches/mkey_migrate/src/lib/crypto/cksumtypes.c
U   branches/mkey_migrate/src/lib/crypto/cksumtypes.h
U   branches/mkey_migrate/src/lib/crypto/etypes.c
U   branches/mkey_migrate/src/lib/crypto/etypes.h
U   branches/mkey_migrate/src/lib/crypto/string_to_cksumtype.c
U   branches/mkey_migrate/src/lib/crypto/string_to_enctype.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/accept_sec_context.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/gssapi_krb5.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3iov.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/k5unseal.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/k5unsealiov.c
U   branches/mkey_migrate/src/lib/gssapi/krb5/util_crypt.c
U   branches/mkey_migrate/src/lib/gssapi/libgssapi_krb5.exports
U   branches/mkey_migrate/src/lib/gssapi/mechglue/Makefile.in
U   branches/mkey_migrate/src/lib/gssapi/mechglue/deps
D   branches/mkey_migrate/src/lib/gssapi/mechglue/g_export_name_object.c
D   branches/mkey_migrate/src/lib/gssapi/mechglue/g_imp_name_object.c
U   branches/mkey_migrate/src/lib/gssapi/mechglue/g_initialize.c
U   branches/mkey_migrate/src/lib/gssapi/mechglue/mglueP.h
U   branches/mkey_migrate/src/lib/gssapi/spnego/spnego_mech.c
U   branches/mkey_migrate/src/lib/kadm5/clnt/client_init.c
U   branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c
U   branches/mkey_migrate/src/lib/kadm5/unit-test/Makefile.in
U   branches/mkey_migrate/src/lib/kadm5/unit-test/config/unix.exp
U   branches/mkey_migrate/src/lib/krb5/krb/auth_con.c
U   branches/mkey_migrate/src/lib/krb5/krb/mk_cred.c
U   branches/mkey_migrate/src/lib/krb5/krb/mk_priv.c
U   branches/mkey_migrate/src/lib/krb5/krb/mk_req_ext.c
U   branches/mkey_migrate/src/lib/krb5/krb/mk_safe.c
U   branches/mkey_migrate/src/lib/krb5/krb/pac.c
U   branches/mkey_migrate/src/lib/krb5/krb/rd_cred.c
U   branches/mkey_migrate/src/lib/krb5/krb/rd_priv.c
U   branches/mkey_migrate/src/lib/krb5/krb/rd_rep.c
U   branches/mkey_migrate/src/lib/krb5/krb/rd_req_dec.c
U   branches/mkey_migrate/src/lib/krb5/krb/rd_safe.c
U   branches/mkey_migrate/src/lib/krb5/krb/sendauth.c
U   branches/mkey_migrate/src/lib/krb5/libkrb5.exports
U   branches/mkey_migrate/src/lib/krb5/os/accessor.c
U   branches/mkey_migrate/src/lib/krb5/os/deps
U   branches/mkey_migrate/src/lib/krb5/os/hst_realm.c
U   branches/mkey_migrate/src/lib/krb5/os/net_write.c
U   branches/mkey_migrate/src/lib/krb5/os/os-proto.h
U   branches/mkey_migrate/src/lib/krb5/os/write_msg.c
U   branches/mkey_migrate/src/lib/krb5/rcache/Makefile.in
U   branches/mkey_migrate/src/lib/krb5/rcache/deps
U   branches/mkey_migrate/src/lib/krb5/rcache/rc_conv.c
U   branches/mkey_migrate/src/lib/krb5/rcache/rc_dfl.c
A   branches/mkey_migrate/src/lib/krb5/rcache/t_replay.c
U   branches/mkey_migrate/src/lib/rpc/unit-test/Makefile.in
U   branches/mkey_migrate/src/lib/rpc/xdr.c
U   branches/mkey_migrate/src/tests/asn.1/Makefile.in
U   branches/mkey_migrate/src/tests/asn.1/deps
U   branches/mkey_migrate/src/tests/threads/t_rcache.c
Modified: branches/mkey_migrate/src/include/k5-int.h
===================================================================
--- branches/mkey_migrate/src/include/k5-int.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/include/k5-int.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006,2007,2008 by the Massachusetts Institute of Technology,
+ * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006,2007,2008,2009 by the Massachusetts Institute of Technology,
  * Cambridge, MA, USA.  All Rights Reserved.
  * 
  * This software is being provided to you, the LICENSEE, by the 
@@ -657,69 +657,6 @@
 				    size_t num_data);
 };
 
-typedef void (*krb5_encrypt_length_func) (const struct krb5_enc_provider *enc,
-  const struct krb5_hash_provider *hash,
-  size_t inputlen, size_t *length);
-
-typedef krb5_error_code (*krb5_crypt_func) (const struct krb5_enc_provider *enc,
-  const struct krb5_hash_provider *hash,
-  const krb5_keyblock *key, krb5_keyusage keyusage,
-  const krb5_data *ivec, 
-  const krb5_data *input, krb5_data *output);
-
-typedef krb5_error_code (*krb5_str2key_func) (const struct krb5_enc_provider *enc, const krb5_data *string,
-  const krb5_data *salt, const krb5_data *parm, krb5_keyblock *key);
-
-typedef krb5_error_code (*krb5_prf_func)(
-					 const struct krb5_enc_provider *enc,
-					 const struct krb5_hash_provider *hash,
-					 const krb5_keyblock *key,
-					 const krb5_data *in, krb5_data *out);
-
-struct krb5_keytypes {
-    krb5_enctype etype;
-    char *in_string;
-    char *out_string;
-    const struct krb5_enc_provider *enc;
-    const struct krb5_hash_provider *hash;
-    size_t prf_length;
-    krb5_encrypt_length_func encrypt_len;
-    krb5_crypt_func encrypt;
-    krb5_crypt_func decrypt;
-    krb5_str2key_func str2key;
-    krb5_prf_func prf;
-    krb5_cksumtype required_ctype;
-    const struct krb5_aead_provider *aead;
-};
-
-struct krb5_cksumtypes {
-    krb5_cksumtype ctype;
-    unsigned int flags;
-    char *in_string;
-    char *out_string;
-    /* if the hash is keyed, this is the etype it is keyed with.
-       Actually, it can be keyed by any etype which has the same
-       enc_provider as the specified etype.  DERIVE checksums can
-       be keyed with any valid etype. */
-    krb5_enctype keyed_etype;
-    /* I can't statically initialize a union, so I'm just going to use
-       two pointers here.  The keyhash is used if non-NULL.  If NULL,
-       then HMAC/hash with derived keys is used if the relevant flag
-       is set.  Otherwise, a non-keyed hash is computed.  This is all
-       kind of messy, but so is the krb5 api. */
-    const struct krb5_keyhash_provider *keyhash;
-    const struct krb5_hash_provider *hash;
-    /* This just gets uglier and uglier.  In the key derivation case,
-       we produce an hmac.  To make the hmac code work, we can't hack
-       the output size indicated by the hash provider, but we may want
-       a truncated hmac.  If we want truncation, this is the number of
-       bytes we truncate to; it should be 0 otherwise.  */
-    unsigned int trunc_size;
-};
-
-#define KRB5_CKSUMFLAG_DERIVE		0x0001
-#define KRB5_CKSUMFLAG_NOT_COLL_PROOF	0x0002
-
 /*
  * in here to deal with stuff from lib/crypto
  */
@@ -1964,7 +1901,7 @@
 /* To keep happy libraries which are (for now) accessing internal stuff */
 
 /* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 12
+#define KRB5INT_ACCESS_STRUCT_VERSION 13
 
 #ifndef ANAME_SZ
 struct ktext;			/* from krb.h, for krb524 support */
@@ -1977,6 +1914,7 @@
 				   const krb5_keyblock *key,
 				   unsigned int icount, const krb5_data *input,
 				   krb5_data *output);
+    krb5_error_code (* krb5_auth_con_get_subkey_enctype)(krb5_context, krb5_auth_context, krb5_enctype *);
     /* service location and communication */
     krb5_error_code (*sendto_udp) (krb5_context, const krb5_data *msg,
 				   const struct addrlist *, struct sendto_callback_info*, krb5_data *reply,
@@ -2182,6 +2120,7 @@
     krb5_ui_4 hash;
     char *server;			/* null-terminated */
     char *client;			/* null-terminated */
+    char *msghash;			/* null-terminated */
     krb5_int32 cusec;
     krb5_timestamp ctime;
 } krb5_donot_replay;
@@ -2206,6 +2145,9 @@
 	(krb5_context,
 		krb5_tkt_authent *,
 		krb5_donot_replay *);
+krb5_error_code krb5_rc_hash_message
+	(krb5_context context,
+		const krb5_data *message, char **out);
 
 
 krb5_error_code KRB5_CALLCONV krb5_rc_initialize
@@ -2581,6 +2523,11 @@
 	    krb5_auth_context,
 	    krb5_enctype **);
 
+krb5_error_code krb5_auth_con_get_subkey_enctype
+	(krb5_context context,
+	    krb5_auth_context,
+	    krb5_enctype *);
+
 krb5_error_code KRB5_CALLCONV
 krb5int_server_decrypt_ticket_keyblock
   	(krb5_context context,
@@ -2589,6 +2536,7 @@
 
 krb5_error_code krb5_read_message (krb5_context, krb5_pointer, krb5_data *);
 krb5_error_code krb5_write_message (krb5_context, krb5_pointer, krb5_data *);
+krb5_error_code krb5int_write_messages (krb5_context, krb5_pointer, krb5_data *, int);
 int krb5_net_read (krb5_context, int , char *, int);
 int krb5_net_write (krb5_context, int , const char *, int);
 

Modified: branches/mkey_migrate/src/kadmin/passwd/unit-test/Makefile.in
===================================================================
--- branches/mkey_migrate/src/kadmin/passwd/unit-test/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kadmin/passwd/unit-test/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -16,10 +16,10 @@
 	$(ENV_SETUP) $(RUNTEST) --tool kpasswd KPASSWD=../kpasswd \
 		KINIT=$(BUILDTOP)/clients/kinit/kinit \
 		KDESTROY=$(BUILDTOP)/clients/kdestroy/kdestroy \
-		PRIOCNTL_HACK=@PRIOCNTL_HACK@
+		PRIOCNTL_HACK=@PRIOCNTL_HACK@ VALGRIND="$(VALGRIND)"
 
 unit-test-setup::
-	$(ENV_SETUP) $(START_SERVERS)
+	$(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
 
 unit-test-cleanup::
 	$(ENV_SETUP) $(STOP_SERVERS)

Modified: branches/mkey_migrate/src/kadmin/passwd/unit-test/config/unix.exp
===================================================================
--- branches/mkey_migrate/src/kadmin/passwd/unit-test/config/unix.exp	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kadmin/passwd/unit-test/config/unix.exp	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,3 +1,44 @@
+if { [string length $VALGRIND] } {
+    rename spawn valgrind_aux_spawn
+    proc spawn { args } {
+	global VALGRIND
+	upvar 1 spawn_id spawn_id
+	set newargs {}
+	set inflags 1
+	set eatnext 0
+	foreach arg $args {
+	    if { $arg == "-ignore" \
+		     || $arg == "-open" \
+		     || $arg == "-leaveopen" } {
+		lappend newargs $arg
+		set eatnext 1
+		continue
+	    }
+	    if [string match "-*" $arg] {
+		lappend newargs $arg
+		continue
+	    }
+	    if { $eatnext } {
+		set eatnext 0
+		lappend newargs $arg
+		continue
+	    }
+	    if { $inflags } {
+		set inflags 0
+		# Only run valgrind for local programs, not
+		# system ones.
+#&&![string match "/bin/sh" $arg] sh is used to start kadmind!
+		if [string match "/" [string index $arg 0]]&&![string match "/bin/ls" $arg]&&![regexp {/kshd$} $arg] {
+		    set newargs [concat $newargs $VALGRIND]
+		}
+	    }
+	    lappend newargs $arg
+	}
+	set pid [eval valgrind_aux_spawn $newargs]
+	return $pid
+    }
+}
+
 # Hack around Solaris 9 kernel race condition that causes last output
 # from a pty to get dropped.
 if { $PRIOCNTL_HACK } {

Modified: branches/mkey_migrate/src/kadmin/server/network.c
===================================================================
--- branches/mkey_migrate/src/kadmin/server/network.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kadmin/server/network.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * kadmin/server/network.c
  *
- * Copyright 1990,2000,2007,2008 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2000,2007,2008,2009 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.
@@ -180,13 +180,16 @@
 
 /* kadmin data.  */
 
-enum kadm_conn_type { CONN_UDP, CONN_UDP_PKTINFO, CONN_TCP_LISTENER,
-		      CONN_TCP, CONN_ROUTING, CONN_RPC_LISTENER, CONN_RPC };
+enum conn_type {
+    CONN_UDP, CONN_UDP_PKTINFO, CONN_TCP_LISTENER, CONN_TCP,
+    CONN_RPC_LISTENER, CONN_RPC,
+    CONN_ROUTING
+};
 
 /* Per-connection info.  */
 struct connection {
     int fd;
-    enum kadm_conn_type type;
+    enum conn_type type;
     void (*service)(void *handle, struct connection *, const char *, int);
     union {
 	/* Type-specific information.  */
@@ -334,10 +337,6 @@
 
 #define USE_AF AF_INET
 #define USE_TYPE SOCK_DGRAM
-
-
-#define USE_AF AF_INET
-#define USE_TYPE SOCK_DGRAM
 #define USE_PROTO 0
 #define SOCKET_ERRNO errno
 #include "foreachaddr.h"
@@ -351,7 +350,7 @@
 };
 
 static struct connection *
-add_fd (struct socksetup *data, int sock, enum kadm_conn_type conntype,
+add_fd (struct socksetup *data, int sock, enum conn_type conntype,
 	void (*service)(void *handle, struct connection *, const char *, int))
 {
     struct connection *newconn;
@@ -1147,8 +1146,13 @@
 	     struct sockaddr *to, socklen_t *tolen)
 {
 #if (!defined(IP_PKTINFO) && !defined(IPV6_PKTINFO)) || !defined(CMSG_SPACE)
-    if (to && tolen)
+    if (to && tolen) {
+	/* Clobber with something recognizeable in case we try to use
+	   the address.  */
+	memset(to, 0x40, *tolen);
 	*tolen = 0;
+    }
+
     return recvfrom(s, buf, len, flags, from, fromlen);
 #else
     int r;
@@ -1160,6 +1164,10 @@
     if (!to || !tolen)
 	return recvfrom(s, buf, len, flags, from, fromlen);
 
+    /* Clobber with something recognizeable in case we can't extract
+       the address but try to use it anyways.  */
+    memset(to, 0x40, *tolen);
+
     iov.iov_base = buf;
     iov.iov_len = len;
     memset(&msg, 0, sizeof(msg));
@@ -1393,6 +1401,17 @@
     }
 #endif
 
+    if (daddr_len == 0 && conn->type == CONN_UDP) {
+	/* If the PKTINFO option isn't set, this socket should be
+	   bound to a specific local address.  This info probably
+	   should've been saved in our socket data structure at setup
+	   time.  */
+	daddr_len = sizeof(daddr);
+	if (getsockname(port_fd, (struct sockaddr *)&daddr, &daddr_len) != 0)
+	    daddr_len = 0;
+	/* On failure, keep going anyways.  */
+    }
+
     request.length = cc;
     request.data = pktbuf;
     faddr.address = &addr;

Modified: branches/mkey_migrate/src/kdc/do_as_req.c
===================================================================
--- branches/mkey_migrate/src/kdc/do_as_req.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/do_as_req.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -2,7 +2,7 @@
  * kdc/do_as_req.c
  *
  * Portions Copyright (C) 2007 Apple Inc.
- * Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2007,2008,2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -99,7 +99,7 @@
     krb5_error_code errcode;
     int c_nprincs = 0, s_nprincs = 0;
     krb5_boolean more;
-    krb5_timestamp kdc_time, authtime;
+    krb5_timestamp kdc_time, authtime = 0;
     krb5_keyblock session_key;
     const char *status;
     krb5_key_data *server_key, *client_key;
@@ -561,9 +561,6 @@
     memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length);
     free(reply.enc_part.ciphertext.data);
 
-    log_as_req(from, request, &reply, cname, sname, authtime, 0, 0, 0);
-    did_log = 1;
-
 #ifdef	KRBCONF_KDC_MODIFIES_KDB
     /*
      * If we get this far, we successfully did the AS_REQ.
@@ -573,6 +570,10 @@
 #endif	/* KRBCONF_KDC_MODIFIES_KDB */
     update_client = 1;
 
+    log_as_req(from, request, &reply, &client, cname, &server, sname,
+	       authtime, 0, 0, 0);
+    did_log = 1;
+
     goto egress;
 
 errout:
@@ -580,10 +581,6 @@
     /* fall through */
 
 egress:
-    if (update_client) {
-	audit_as_request(request, &client, &server, authtime, errcode);
-    }
-
     if (pa_context)
 	free_padata_context(kdc_context, &pa_context);
 
@@ -591,7 +588,7 @@
 	emsg = krb5_get_error_message(kdc_context, errcode);
 
     if (status) {
-	log_as_req(from, request, &reply, cname, sname, 0,
+	log_as_req(from, request, &reply, &client, cname, &server, sname, 0,
 		   status, errcode, emsg);
 	did_log = 1;
     }

Modified: branches/mkey_migrate/src/kdc/do_tgs_req.c
===================================================================
--- branches/mkey_migrate/src/kdc/do_tgs_req.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/do_tgs_req.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * kdc/do_tgs_req.c
  *
- * Copyright 1990,1991,2001,2007,2008 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2001,2007,2008,2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -282,6 +282,7 @@
 	 */
 	if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
 					  c_flags,
+					  TRUE, /* match_enctype */
 					  &st_client,
 					  &st_nprincs,
 					  &st_sealing_key,
@@ -839,7 +840,7 @@
     if (errcode) 
 	emsg = krb5_get_error_message (kdc_context, errcode);
     log_tgs_req(from, request, &reply, cname, sname, altcname, authtime,
-		status, errcode, emsg);
+		c_flags, s4u_name, status, errcode, emsg);
     if (errcode) {
 	krb5_free_error_message (kdc_context, emsg);
 	emsg = NULL;

Modified: branches/mkey_migrate/src/kdc/kdc_preauth.c
===================================================================
--- branches/mkey_migrate/src/kdc/kdc_preauth.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/kdc_preauth.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1161,6 +1161,7 @@
      */
     switch(retval) {
     case 0: /* in case of PA-PAC-REQUEST with no PA-ENC-TIMESTAMP */
+    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     case KRB5KRB_AP_ERR_SKEW:
     case KRB5KDC_ERR_ETYPE_NOSUPP:
     /* rfc 4556 */
@@ -1184,7 +1185,6 @@
     /* This value is shared with KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED. */
     /* case KRB5KDC_ERR_KEY_TOO_WEAK: */
 	return retval;
-    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     default:
 	return KRB5KDC_ERR_PREAUTH_FAILED;
     }
@@ -2407,6 +2407,7 @@
 	/* Now check the replay cache. */
 	rep.client = princ_psr;
 	rep.server = "SAM/rc";  /* Should not match any principal name. */
+	rep.msghash = NULL;
 	rep.ctime = psr->stime;
 	rep.cusec = psr->susec;
 	retval = krb5_rc_store(kdc_context, kdc_rcache, &rep);

Modified: branches/mkey_migrate/src/kdc/kdc_util.c
===================================================================
--- branches/mkey_migrate/src/kdc/kdc_util.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/kdc_util.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * kdc/kdc_util.c
  *
- * Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2007,2008,2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -292,7 +292,8 @@
 	goto cleanup_auth_context;
 #endif
 
-    if ((retval = kdc_get_server_key(apreq->ticket, 0, krbtgt, nprincs, &key, &kvno)))
+    if ((retval = kdc_get_server_key(apreq->ticket, 0, foreign_server,
+				     krbtgt, nprincs, &key, &kvno)))
 	goto cleanup_auth_context;
     /*
      * We do not use the KDB keytab because other parts of the TGS need the TGT key.
@@ -408,11 +409,11 @@
  */
 krb5_error_code
 kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
-		   krb5_db_entry *server,
+		   krb5_boolean match_enctype, krb5_db_entry *server,
 		   int *nprincs, krb5_keyblock **key, krb5_kvno *kvno)
 {
     krb5_error_code 	  retval;
-    krb5_boolean 	  more;
+    krb5_boolean 	  more, similar;
     krb5_key_data	* server_key;
     krb5_keyblock       * tmp_mkey;
 
@@ -433,34 +434,55 @@
 	char *sname;
 
 	if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) {
+	    limit_string(sname);
 	    krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'",
 			     sname);
 	    free(sname);
 	}
 	return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
     }
+    if (server->attributes & KRB5_KDB_DISALLOW_SVR ||
+	server->attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
+	retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+	goto errout;
+    }
 
     retval = krb5_dbe_find_mkey(kdc_context, master_keylist, server, &tmp_mkey);
     if (retval)
 	goto errout;
 
     retval = krb5_dbe_find_enctype(kdc_context, server,
-				   ticket->enc_part.enctype, -1,
-				   (krb5_int32)ticket->enc_part.kvno, &server_key);
+				   match_enctype ? ticket->enc_part.enctype : -1,
+				   -1, (krb5_int32)ticket->enc_part.kvno,
+				   &server_key);
     if (retval)
 	goto errout;
     if (!server_key) {
 	retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
 	goto errout;
     }
-    *kvno = server_key->key_data_kvno;
     if ((*key = (krb5_keyblock *)malloc(sizeof **key))) {
 	retval = krb5_dbekd_decrypt_key_data(kdc_context, tmp_mkey,
 					     server_key,
 					     *key, NULL);
     } else
 	retval = ENOMEM;
+    retval = krb5_c_enctype_compare(kdc_context, ticket->enc_part.enctype,
+				    (*key)->enctype, &similar);
+    if (retval)
+	goto errout;
+    if (!similar) {
+	retval = KRB5_KDB_NO_PERMITTED_KEY;
+	goto errout;
+    }
+    (*key)->enctype = ticket->enc_part.enctype;
+    *kvno = server_key->key_data_kvno;
 errout:
+    if (retval != 0) {
+	krb5_db_free_principal(kdc_context, server, *nprincs);
+	*nprincs = 0;
+    }
+
     return retval;
 }
 
@@ -1698,11 +1720,8 @@
     krb5_data rep_data;
 
     *ret_authdata = NULL;
-    if (ad_entry != NULL) {
-	assert(ad_nprincs != NULL);
-	memset(ad_entry, 0, sizeof(*ad_entry));
-	*ad_nprincs = 0;
-    }
+    memset(ad_entry, 0, sizeof(*ad_entry));
+    *ad_nprincs = 0;
 
     memset(&req, 0, sizeof(req));
     memset(&rep, 0, sizeof(rep));
@@ -1994,7 +2013,7 @@
 
     /* Must be in same realm */
     if (!krb5_realm_compare(context, server->princ, proxy)) {
-	return KRB5_IN_TKT_REALM_MISMATCH; /* XXX */
+	return KRB5KDC_ERR_BADOPTION;
     }
 
     req.server = server;
@@ -2104,84 +2123,6 @@
 }
 
 krb5_error_code
-audit_as_request(krb5_kdc_req *request,
-		 krb5_db_entry *client,
-		 krb5_db_entry *server,
-		 krb5_timestamp authtime,
-		 krb5_error_code errcode)
-{
-    krb5_error_code		code;
-    kdb_audit_as_req		req;
-    krb5_data			req_data;
-    krb5_data			rep_data;
-
-    memset(&req, 0, sizeof(req));
-
-    req.request			= request;
-    req.client			= client;
-    req.server			= server;
-    req.authtime		= authtime;
-    req.error_code		= errcode;
-
-    req_data.data = (void *)&req;
-    req_data.length = sizeof(req);
-
-    rep_data.data = NULL;
-    rep_data.length = 0;
-
-    code = krb5_db_invoke(kdc_context,
-			  KRB5_KDB_METHOD_AUDIT_AS,
-			  &req_data,
-			  &rep_data);
-    if (code == KRB5_KDB_DBTYPE_NOSUP) {
-	return 0;
-    }
-
-    assert(rep_data.length == 0);
-
-    return code;
-}
-
-krb5_error_code
-audit_tgs_request(krb5_kdc_req *request,
-		  krb5_const_principal client,
-		  krb5_db_entry *server,
-		  krb5_timestamp authtime,
-		  krb5_error_code errcode)
-{
-    krb5_error_code		code;
-    kdb_audit_tgs_req		req;
-    krb5_data			req_data;
-    krb5_data			rep_data;
-
-    memset(&req, 0, sizeof(req));
-
-    req.request			= request;
-    req.client			= client;
-    req.server			= server;
-    req.authtime		= authtime;
-    req.error_code		= errcode;
-
-    req_data.data = (void *)&req;
-    req_data.length = sizeof(req);
-
-    rep_data.data = NULL;
-    rep_data.length = 0;
-
-    code = krb5_db_invoke(kdc_context,
-			  KRB5_KDB_METHOD_AUDIT_TGS,
-			  &req_data,
-			  &rep_data);
-    if (code == KRB5_KDB_DBTYPE_NOSUP) {
-	return 0;
-    }
-
-    assert(rep_data.length == 0);
-
-    return code;
-}
-
-krb5_error_code
 validate_transit_path(krb5_context context,
 		      krb5_const_principal client,
 		      krb5_db_entry *server,
@@ -2212,10 +2153,12 @@
 
 /* "status" is null to indicate success.  */
 /* Someday, pass local address/port as well.  */
+/* Currently no info about name canonicalization is logged.  */
 void
 log_as_req(const krb5_fulladdr *from,
 	   krb5_kdc_req *request, krb5_kdc_rep *reply,
-	   const char *cname, const char *sname,
+	   krb5_db_entry *client, const char *cname,
+	   krb5_db_entry *server, const char *sname,
 	   krb5_timestamp authtime,
 	   const char *status, krb5_error_code errcode, const char *emsg)
 {
@@ -2255,15 +2198,45 @@
     audit_krb5kdc_as_req(some in_addr *, (in_port_t)from->port, 0,
 			 cname, sname, errcode);
 #endif
+#if 1
+    {
+	kdb_audit_as_req	req;
+	krb5_data		req_data;
+	krb5_data		rep_data;
+
+	memset(&req, 0, sizeof(req));
+
+	req.request		= request;
+	req.client		= client;
+	req.server		= server;
+	req.authtime		= authtime;
+	req.error_code		= errcode;
+
+	req_data.data = (void *)&req;
+	req_data.length = sizeof(req);
+
+	rep_data.data = NULL;
+	rep_data.length = 0;
+
+	(void) krb5_db_invoke(kdc_context,
+			      KRB5_KDB_METHOD_AUDIT_AS,
+			      &req_data,
+			      &rep_data);
+	assert(rep_data.length == 0);
+    }
+#endif
 }
 
 /* Here "status" must be non-null.  Error code
-   KRB5KDC_ERR_SERVER_NOMATCH is handled specially.  */
+   KRB5KDC_ERR_SERVER_NOMATCH is handled specially.
+
+   Currently no info about name canonicalization is logged.  */
 void
 log_tgs_req(const krb5_fulladdr *from,
 	    krb5_kdc_req *request, krb5_kdc_rep *reply,
 	    const char *cname, const char *sname, const char *altcname,
 	    krb5_timestamp authtime,
+	    unsigned int c_flags, const char *s4u_name,
 	    const char *status, krb5_error_code errcode, const char *emsg)
 {
     char ktypestr[128];
@@ -2285,7 +2258,7 @@
     /* Differences: server-nomatch message logs 2nd ticket's client
        name (useful), and doesn't log ktypestr (probably not
        important).  */
-    if (errcode != KRB5KDC_ERR_SERVER_NOMATCH)
+    if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
 	krb5_klog_syslog(LOG_INFO,
 			 "TGS_REQ (%s) %s: %s: authtime %d, %s%s %s for %s%s%s",
 			 ktypestr,
@@ -2296,7 +2269,19 @@
 			 sname ? sname : "<unknown server>",
 			 errcode ? ", " : "",
 			 errcode ? emsg : "");
-    else
+	if (s4u_name) {
+	    assert(isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) ||
+		   isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION));
+	    if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
+		krb5_klog_syslog(LOG_INFO,
+				 "... PROTOCOL-TRANSITION s4u-client=%s",
+				 s4u_name);
+	    else if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION))
+		krb5_klog_syslog(LOG_INFO,
+				 "... CONSTRAINED-DELEGATION s4u-client=%s",
+				 s4u_name);
+	}
+    } else
 	krb5_klog_syslog(LOG_INFO,
 			 "TGS_REQ %s: %s: authtime %d, %s for %s, 2nd tkt client %s",
 			 fromstring, status, authtime,
@@ -2306,6 +2291,7 @@
 
     /* OpenSolaris: audit_krb5kdc_tgs_req(...)  or
        audit_krb5kdc_tgs_req_2ndtktmm(...) */
+    /* ... krb5_db_invoke ... */
 }
 
 void

Modified: branches/mkey_migrate/src/kdc/kdc_util.h
===================================================================
--- branches/mkey_migrate/src/kdc/kdc_util.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/kdc_util.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -69,6 +69,7 @@
 	           krb5_keyblock **);
 
 krb5_error_code kdc_get_server_key (krb5_ticket *, unsigned int,
+				    krb5_boolean match_enctype,
 				    krb5_db_entry *, int *,
 				    krb5_keyblock **, krb5_kvno *);
 
@@ -283,7 +284,8 @@
 void
 log_as_req(const krb5_fulladdr *from,
 	   krb5_kdc_req *request, krb5_kdc_rep *reply,
-	   const char *cname, const char *sname,
+	   krb5_db_entry *client, const char *cname,
+	   krb5_db_entry *server, const char *sname,
 	   krb5_timestamp authtime,
 	   const char *status, krb5_error_code errcode, const char *emsg);
 void
@@ -291,6 +293,7 @@
 	    krb5_kdc_req *request, krb5_kdc_rep *reply,
 	    const char *cname, const char *sname, const char *altcname,
 	    krb5_timestamp authtime,
+	    unsigned int c_flags, const char *s4u_name,
 	    const char *status, krb5_error_code errcode, const char *emsg);
 void log_tgs_alt_tgt(krb5_principal p);
 

Modified: branches/mkey_migrate/src/kdc/network.c
===================================================================
--- branches/mkey_migrate/src/kdc/network.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/kdc/network.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * kdc/network.c
  *
- * Copyright 1990,2000,2007,2008 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2000,2007,2008,2009 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.
@@ -175,27 +175,19 @@
 
 /* KDC data.  */
 
-enum kdc_conn_type { CONN_UDP, CONN_UDP_PKTINFO, CONN_TCP_LISTENER, CONN_TCP, CONN_ROUTING };
+enum conn_type {
+    CONN_UDP, CONN_UDP_PKTINFO, CONN_TCP_LISTENER, CONN_TCP,
+    CONN_ROUTING
+};
 
 /* Per-connection info.  */
 struct connection {
     int fd;
-    enum kdc_conn_type type;
+    enum conn_type type;
     void (*service)(struct connection *, const char *, int);
     union {
 	/* Type-specific information.  */
-#if 0
 	struct {
-	    int x;
-	} udp;
-	struct {
-	    int x;
-	} udp_pktinfo;
-	struct {
-	    int x;
-	} tcp_listener;
-#endif
-	struct {
 	    /* connection */
 	    struct sockaddr_storage addr_s;
 	    socklen_t addrlen;
@@ -316,7 +308,7 @@
 };
 
 static struct connection *
-add_fd (struct socksetup *data, int sock, enum kdc_conn_type conntype,
+add_fd (struct socksetup *data, int sock, enum conn_type conntype,
 	void (*service)(struct connection *, const char *, int))
 {
     struct connection *newconn;
@@ -527,7 +519,7 @@
 
 	/* Sockets are created, prepare to listen on them.  */
 	if (s4 >= 0) {
-	    if (add_tcp_listener_fd(data, s4) == 0)
+	    if (add_tcp_listener_fd(data, s4) == NULL)
 		close(s4);
 	    else {
 		FD_SET(s4, &sstate.rfds);
@@ -539,7 +531,7 @@
 	}
 #ifdef KRB5_USE_INET6
 	if (s6 >= 0) {
-	    if (add_tcp_listener_fd(data, s6) == 0) {
+	    if (add_tcp_listener_fd(data, s6) == NULL) {
 		close(s6);
 		s6 = -1;
 	    } else {
@@ -1012,8 +1004,12 @@
 	     struct sockaddr *to, socklen_t *tolen)
 {
 #if (!defined(IP_PKTINFO) && !defined(IPV6_PKTINFO)) || !defined(CMSG_SPACE)
-    if (to && tolen)
+    if (to && tolen) {
+	/* Clobber with something recognizeable in case we try to use
+	   the address.  */
+	memset(to, 0x40, *tolen);
 	*tolen = 0;
+    }
     return recvfrom(s, buf, len, flags, from, fromlen);
 #else
     int r;
@@ -1025,6 +1021,10 @@
     if (!to || !tolen)
 	return recvfrom(s, buf, len, flags, from, fromlen);
 
+    /* Clobber with something recognizeable in case we can't extract
+       the address but try to use it anyways.  */
+    memset(to, 0x40, *tolen);
+
     iov.iov_base = buf;
     iov.iov_len = len;
     memset(&msg, 0, sizeof(msg));
@@ -1306,7 +1306,7 @@
     sockdata.retval = 0;
 
     newconn = add_tcp_data_fd(&sockdata, s);
-    if (newconn == 0)
+    if (newconn == NULL)
 	return;
 
     if (getnameinfo((struct sockaddr *)&addr_s, addrlen,

Modified: branches/mkey_migrate/src/lib/crypto/cksumtypes.c
===================================================================
--- branches/mkey_migrate/src/lib/crypto/cksumtypes.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/cksumtypes.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -31,69 +31,58 @@
 
 const struct krb5_cksumtypes krb5_cksumtypes_list[] = {
     { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF,
-      "crc32", "CRC-32",
+      "crc32", { 0 }, "CRC-32",
       0, NULL,
       &krb5int_hash_crc32 },
 
     { CKSUMTYPE_RSA_MD4, 0,
-      "md4", "RSA-MD4",
+      "md4", { 0 }, "RSA-MD4",
       0, NULL,
       &krb5int_hash_md4 },
     { CKSUMTYPE_RSA_MD4_DES, 0,
-      "md4-des", "RSA-MD4 with DES cbc mode",
+      "md4-des", { 0 }, "RSA-MD4 with DES cbc mode",
       ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md4des,
       NULL },
 
     { CKSUMTYPE_DESCBC, 0,
-      "des-cbc", "DES cbc mode",
+      "des-cbc", { 0 }, "DES cbc mode",
       ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_descbc,
       NULL },
 
     { CKSUMTYPE_RSA_MD5, 0,
-      "md5", "RSA-MD5",
+      "md5", { 0 }, "RSA-MD5",
       0, NULL,
       &krb5int_hash_md5 },
     { CKSUMTYPE_RSA_MD5_DES, 0,
-      "md5-des", "RSA-MD5 with DES cbc mode",
+      "md5-des", { 0 }, "RSA-MD5 with DES cbc mode",
       ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md5des,
       NULL },
 
     { CKSUMTYPE_NIST_SHA, 0,
-      "sha", "NIST-SHA",
+      "sha", { 0 }, "NIST-SHA",
       0, NULL,
       &krb5int_hash_sha1 },
 
     { CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE,
-      "hmac-sha1-des3", "HMAC-SHA1 DES3 key",
+      "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key",
       0, NULL,
       &krb5int_hash_sha1 },
-    { CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE,
-      "hmac-sha1-des3-kd", "HMAC-SHA1 DES3 key", /* alias */
-      0, NULL,
-      &krb5int_hash_sha1 },
     { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
-      "hmac-md5-rc4", "Microsoft HMAC MD5 (RC4 key)", 
+      "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" },
+      "Microsoft HMAC MD5 (RC4 key)", 
       ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
       NULL },
-    { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
-      "hmac-md5-enc", "Microsoft HMAC MD5 (RC4 key)",  /*Heimdal alias*/
-      ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
-      NULL },
-    { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
-      "hmac-md5-earcfour", "Microsoft HMAC MD5 (RC4 key)",  /* alias*/
-      ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
-      NULL },
 
     { CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE,
-      "hmac-sha1-96-aes128", "HMAC-SHA1 AES128 key",
+      "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key",
       0, NULL, 
       &krb5int_hash_sha1, 12 },
     { CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE,
-      "hmac-sha1-96-aes256", "HMAC-SHA1 AES256 key",
+      "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key",
       0, NULL, 
       &krb5int_hash_sha1, 12 },
     { CKSUMTYPE_MD5_HMAC_ARCFOUR, 0,
-      "md5-hmac-rc4", "Microsoft MD5 HMAC (RC4 key)",
+      "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC (RC4 key)",
       ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_md5_hmac, 
       NULL }
 };

Modified: branches/mkey_migrate/src/lib/crypto/cksumtypes.h
===================================================================
--- branches/mkey_migrate/src/lib/crypto/cksumtypes.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/cksumtypes.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -26,5 +26,34 @@
 
 #include "k5-int.h"
 
+struct krb5_cksumtypes {
+    krb5_cksumtype ctype;
+    unsigned int flags;
+    char *name;
+    char *aliases[2];
+    char *out_string;
+    /* if the hash is keyed, this is the etype it is keyed with.
+       Actually, it can be keyed by any etype which has the same
+       enc_provider as the specified etype.  DERIVE checksums can
+       be keyed with any valid etype. */
+    krb5_enctype keyed_etype;
+    /* I can't statically initialize a union, so I'm just going to use
+       two pointers here.  The keyhash is used if non-NULL.  If NULL,
+       then HMAC/hash with derived keys is used if the relevant flag
+       is set.  Otherwise, a non-keyed hash is computed.  This is all
+       kind of messy, but so is the krb5 api. */
+    const struct krb5_keyhash_provider *keyhash;
+    const struct krb5_hash_provider *hash;
+    /* This just gets uglier and uglier.  In the key derivation case,
+       we produce an hmac.  To make the hmac code work, we can't hack
+       the output size indicated by the hash provider, but we may want
+       a truncated hmac.  If we want truncation, this is the number of
+       bytes we truncate to; it should be 0 otherwise.  */
+    unsigned int trunc_size;
+};
+
+#define KRB5_CKSUMFLAG_DERIVE		0x0001
+#define KRB5_CKSUMFLAG_NOT_COLL_PROOF	0x0002
+
 extern const struct krb5_cksumtypes krb5_cksumtypes_list[];
 extern const unsigned int krb5_cksumtypes_length;

Modified: branches/mkey_migrate/src/lib/crypto/etypes.c
===================================================================
--- branches/mkey_migrate/src/lib/crypto/etypes.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/etypes.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -42,7 +42,7 @@
 
 const struct krb5_keytypes krb5_enctypes_list[] = {
     { ENCTYPE_DES_CBC_CRC,
-      "des-cbc-crc", "DES cbc mode with CRC-32",
+      "des-cbc-crc", { 0 }, "DES cbc mode with CRC-32",
       &krb5int_enc_des, &krb5int_hash_crc32,
       8,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
@@ -51,7 +51,7 @@
       CKSUMTYPE_RSA_MD5,
       NULL  /*AEAD*/ },
     { ENCTYPE_DES_CBC_MD4,
-      "des-cbc-md4", "DES cbc mode with RSA-MD4",
+      "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
       &krb5int_enc_des, &krb5int_hash_md4,
       8,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
@@ -60,7 +60,7 @@
       CKSUMTYPE_RSA_MD4,
       NULL  /*AEAD*/  },
     { ENCTYPE_DES_CBC_MD5,
-      "des-cbc-md5", "DES cbc mode with RSA-MD5",
+      "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
       &krb5int_enc_des, &krb5int_hash_md5,
       8,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
@@ -68,18 +68,8 @@
       NULL, /*PRF*/
       CKSUMTYPE_RSA_MD5,
       NULL  /*AEAD*/ },
-    { ENCTYPE_DES_CBC_MD5,
-      "des", "DES cbc mode with RSA-MD5", /* alias */
-      &krb5int_enc_des, &krb5int_hash_md5,
-      8,
-      krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
-      krb5int_des_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_RSA_MD5,
-      NULL  /*AEAD*/ },
-
     { ENCTYPE_DES_CBC_RAW,
-      "des-cbc-raw", "DES cbc mode raw",
+      "des-cbc-raw", { 0 }, "DES cbc mode raw",
       &krb5int_enc_des, NULL,
       8,
       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
@@ -88,7 +78,7 @@
       0,
       &krb5int_aead_raw },
     { ENCTYPE_DES3_CBC_RAW,
-      "des3-cbc-raw", "Triple DES cbc mode raw",
+      "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
       &krb5int_enc_des3, NULL,
       8,
       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
@@ -98,7 +88,8 @@
       &krb5int_aead_raw },
 
     { ENCTYPE_DES3_CBC_SHA1,
-      "des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
+      "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
+      "Triple DES cbc mode with HMAC/sha1",
       &krb5int_enc_des3, &krb5int_hash_sha1,
       8,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
@@ -106,27 +97,9 @@
       NULL, /*PRF*/
       CKSUMTYPE_HMAC_SHA1_DES3,
       &krb5int_aead_dk },
-    { ENCTYPE_DES3_CBC_SHA1,	/* alias */
-      "des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
-      &krb5int_enc_des3, &krb5int_hash_sha1,
-      8,
-      krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_SHA1_DES3,
-      &krb5int_aead_dk },
-    { ENCTYPE_DES3_CBC_SHA1,	/* alias */
-      "des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
-      &krb5int_enc_des3, &krb5int_hash_sha1,
-      8,
-      krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_SHA1_DES3,
-      &krb5int_aead_dk },
 
     { ENCTYPE_DES_HMAC_SHA1,
-      "des-hmac-sha1", "DES with HMAC/sha1",
+      "des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
       &krb5int_enc_des, &krb5int_hash_sha1,
       8,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
@@ -135,34 +108,19 @@
       0,
       NULL },
     { ENCTYPE_ARCFOUR_HMAC, 
-      "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
+      "arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" },
+      "ArcFour with HMAC/md5",
+      &krb5int_enc_arcfour,
       &krb5int_hash_md5,
       0,
-krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_MD5_ARCFOUR,
-      &krb5int_aead_arcfour },
-    { ENCTYPE_ARCFOUR_HMAC,  /* alias */
-      "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
-      &krb5int_hash_md5,
-      0,
       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
       NULL, /*PRF*/
       CKSUMTYPE_HMAC_MD5_ARCFOUR,
       &krb5int_aead_arcfour },
-    { ENCTYPE_ARCFOUR_HMAC,  /* alias */
-      "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
-      &krb5int_hash_md5,
-      0,
-      krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_MD5_ARCFOUR,
-      &krb5int_aead_arcfour },
     { ENCTYPE_ARCFOUR_HMAC_EXP, 
-      "arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5",
+      "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
+      "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5,
       0,
@@ -171,29 +129,10 @@
       NULL, /*PRF*/
       CKSUMTYPE_HMAC_MD5_ARCFOUR,
       &krb5int_aead_arcfour },
-    { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
-      "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
-      &krb5int_enc_arcfour,
-      &krb5int_hash_md5,
-      0,
-      krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_MD5_ARCFOUR,
-      &krb5int_aead_arcfour },
-    { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
-      "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
-      &krb5int_enc_arcfour,
-      &krb5int_hash_md5,
-      0,
-      krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
-      CKSUMTYPE_HMAC_MD5_ARCFOUR,
-      &krb5int_aead_arcfour },
 
     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
-      "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
+      "aes128-cts-hmac-sha1-96", { "aes128-cts" },
+      "AES-128 CTS mode with 96-bit SHA-1 HMAC",
       &krb5int_enc_aes128, &krb5int_hash_sha1,
       16,
       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
@@ -201,17 +140,9 @@
       krb5int_dk_prf,
       CKSUMTYPE_HMAC_SHA1_96_AES128,
       &krb5int_aead_aes },
-    { ENCTYPE_AES128_CTS_HMAC_SHA1_96, /* alias */
-      "aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
-      &krb5int_enc_aes128, &krb5int_hash_sha1,
-      16,
-      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
-      krb5int_aes_string_to_key,
-      krb5int_dk_prf,
-      CKSUMTYPE_HMAC_SHA1_96_AES128,
-      &krb5int_aead_aes },
     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
-      "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
+      "aes256-cts-hmac-sha1-96", { "aes256-cts" },
+      "AES-256 CTS mode with 96-bit SHA-1 HMAC",
       &krb5int_enc_aes256, &krb5int_hash_sha1,
       16,
       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
@@ -219,15 +150,6 @@
       krb5int_dk_prf,
       CKSUMTYPE_HMAC_SHA1_96_AES256,
       &krb5int_aead_aes },
-    { ENCTYPE_AES256_CTS_HMAC_SHA1_96, /* alias */
-      "aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
-      &krb5int_enc_aes256, &krb5int_hash_sha1,
-      16,
-      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
-      krb5int_aes_string_to_key,
-      krb5int_dk_prf,
-      CKSUMTYPE_HMAC_SHA1_96_AES256,
-      &krb5int_aead_aes },
 };
 
 const int krb5_enctypes_length =

Modified: branches/mkey_migrate/src/lib/crypto/etypes.h
===================================================================
--- branches/mkey_migrate/src/lib/crypto/etypes.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/etypes.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -26,5 +26,41 @@
 
 #include "k5-int.h"
 
+typedef void (*krb5_encrypt_length_func) (const struct krb5_enc_provider *enc,
+  const struct krb5_hash_provider *hash,
+  size_t inputlen, size_t *length);
+
+typedef krb5_error_code (*krb5_crypt_func) (const struct krb5_enc_provider *enc,
+  const struct krb5_hash_provider *hash,
+  const krb5_keyblock *key, krb5_keyusage keyusage,
+  const krb5_data *ivec, 
+  const krb5_data *input, krb5_data *output);
+
+typedef krb5_error_code (*krb5_str2key_func) (const struct krb5_enc_provider *enc, const krb5_data *string,
+  const krb5_data *salt, const krb5_data *parm, krb5_keyblock *key);
+
+typedef krb5_error_code (*krb5_prf_func)(
+					 const struct krb5_enc_provider *enc,
+					 const struct krb5_hash_provider *hash,
+					 const krb5_keyblock *key,
+					 const krb5_data *in, krb5_data *out);
+
+struct krb5_keytypes {
+    krb5_enctype etype;
+    char *name;
+    char *aliases[2];
+    char *out_string;
+    const struct krb5_enc_provider *enc;
+    const struct krb5_hash_provider *hash;
+    size_t prf_length;
+    krb5_encrypt_length_func encrypt_len;
+    krb5_crypt_func encrypt;
+    krb5_crypt_func decrypt;
+    krb5_str2key_func str2key;
+    krb5_prf_func prf;
+    krb5_cksumtype required_ctype;
+    const struct krb5_aead_provider *aead;
+};
+
 extern const struct krb5_keytypes krb5_enctypes_list[];
 extern const int krb5_enctypes_length;

Modified: branches/mkey_migrate/src/lib/crypto/string_to_cksumtype.c
===================================================================
--- branches/mkey_migrate/src/lib/crypto/string_to_cksumtype.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/string_to_cksumtype.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -30,13 +30,23 @@
 krb5_error_code KRB5_CALLCONV
 krb5_string_to_cksumtype(char *string, krb5_cksumtype *cksumtypep)
 {
-    unsigned int i;
+    unsigned int i, j;
 
     for (i=0; i<krb5_cksumtypes_length; i++) {
-	if (strcasecmp(krb5_cksumtypes_list[i].in_string, string) == 0) {
+	if (strcasecmp(krb5_cksumtypes_list[i].name, string) == 0) {
 	    *cksumtypep = krb5_cksumtypes_list[i].ctype;
 	    return(0);
 	}
+#define MAX_ALIASES (sizeof(krb5_cksumtypes_list[i].aliases) / sizeof(krb5_cksumtypes_list[i].aliases[0]))
+	for (j = 0; j < MAX_ALIASES; j++) {
+	    const char *alias = krb5_cksumtypes_list[i].aliases[j];
+	    if (alias == NULL)
+		break;
+	    if (strcasecmp(alias, string) == 0) {
+		*cksumtypep = krb5_cksumtypes_list[i].ctype;
+		return 0;
+	    }
+	}
     }
 
     return(EINVAL);

Modified: branches/mkey_migrate/src/lib/crypto/string_to_enctype.c
===================================================================
--- branches/mkey_migrate/src/lib/crypto/string_to_enctype.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/crypto/string_to_enctype.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -30,13 +30,23 @@
 krb5_error_code KRB5_CALLCONV
 krb5_string_to_enctype(char *string, krb5_enctype *enctypep)
 {
-    int i;
+    int i, j;
 
     for (i=0; i<krb5_enctypes_length; i++) {
-	if (strcasecmp(krb5_enctypes_list[i].in_string, string) == 0) {
+	if (strcasecmp(krb5_enctypes_list[i].name, string) == 0) {
 	    *enctypep = krb5_enctypes_list[i].etype;
-	    return(0);
+	    return 0;
 	}
+#define MAX_ALIASES (sizeof(krb5_enctypes_list[i].aliases) / sizeof(krb5_enctypes_list[i].aliases[0]))
+	for (j = 0; j < MAX_ALIASES; j++) {
+	    const char *alias = krb5_enctypes_list[i].aliases[j];
+	    if (alias == NULL)
+		break;
+	    if (strcasecmp(alias, string) == 0) {
+		*enctypep = krb5_enctypes_list[i].etype;
+		return 0;
+	    }
+	}
     }
 
     return(EINVAL);

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/accept_sec_context.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/accept_sec_context.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/accept_sec_context.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -395,6 +395,7 @@
     int cred_rcache = 0;
     int no_encap = 0;
     krb5_flags ap_req_options = 0;
+    krb5_enctype negotiated_etype;
 
     code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
     if (code) {
@@ -903,6 +904,34 @@
         krb5_int32 seq_temp;
         int cfx_generate_subkey;
 
+	/*
+	 * Do not generate a subkey per RFC 4537 unless we are upgrading to CFX,
+	 * because pre-CFX tokens do not indicate which key to use. (Note that
+	 * DCE_STYLE implies that we will use a subkey.)
+	 */
+	if (ctx->proto == 0 &&
+	    (ctx->gss_flags & GSS_C_DCE_STYLE) == 0 && 
+	    (ap_req_options & AP_OPTS_USE_SUBKEY)) {
+	    code = (*kaccess.krb5_auth_con_get_subkey_enctype) (context,
+								auth_context,
+								&negotiated_etype);
+	    if (code != 0) {
+		major_status = GSS_S_FAILURE;
+		goto fail;
+	    }
+
+	    switch (negotiated_etype) {
+	    case ENCTYPE_DES_CBC_MD5:
+	    case ENCTYPE_DES_CBC_MD4:
+	    case ENCTYPE_DES_CBC_CRC:
+	    case ENCTYPE_DES3_CBC_SHA1:
+	    case ENCTYPE_ARCFOUR_HMAC:
+	    case ENCTYPE_ARCFOUR_HMAC_EXP:
+		ap_req_options &= ~(AP_OPTS_USE_SUBKEY);
+		break;
+	    }
+	}
+
         if (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) ||
 	    (ap_req_options & AP_OPTS_USE_SUBKEY))
             cfx_generate_subkey = CFX_ACCEPTOR_SUBKEY;

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/gssapi_krb5.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/gssapi_krb5.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/gssapi_krb5.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -386,11 +386,13 @@
 /*
  * gss_inquire_cred_by_oid() methods
  */
+#if 0
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*func)(OM_uint32 *, const gss_cred_id_t, const gss_OID, gss_buffer_set_t *);
 } krb5_gss_inquire_cred_by_oid_ops[] = {
 };
+#endif
 
 static OM_uint32
 krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status,
@@ -425,6 +427,7 @@
 
     cred = (krb5_gss_cred_id_t) cred_handle;
 
+#if 0
     for (i = 0; i < sizeof(krb5_gss_inquire_cred_by_oid_ops)/
 		    sizeof(krb5_gss_inquire_cred_by_oid_ops[0]); i++) {
 	if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_cred_by_oid_ops[i].oid)) {
@@ -434,6 +437,7 @@
 							       data_set);
 	}
     }
+#endif
 
     *minor_status = EINVAL;
 
@@ -443,11 +447,13 @@
 /*
  * gss_set_sec_context_option() methods
  */
+#if 0
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*func)(OM_uint32 *, gss_ctx_id_t *, const gss_OID, const gss_buffer_t);
 } krb5_gss_set_sec_context_option_ops[] = {
 };
+#endif
 
 static OM_uint32
 krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
@@ -480,6 +486,7 @@
 	    return GSS_S_NO_CONTEXT;
     }
 
+#if 0
     for (i = 0; i < sizeof(krb5_gss_set_sec_context_option_ops)/
 		    sizeof(krb5_gss_set_sec_context_option_ops[0]); i++) {
 	if (g_OID_prefix_equal(desired_object, &krb5_gss_set_sec_context_option_ops[i].oid)) {
@@ -489,6 +496,7 @@
 								  value);
 	}
     }
+#endif
 
     *minor_status = EINVAL;
 
@@ -661,8 +669,6 @@
     krb5_gss_wrap_size_limit,
     krb5_gss_export_name,
     NULL,                        /* store_cred */
-    NULL,                        /* import_name_object */
-    NULL,                        /* export_name_object */
     krb5_gss_inquire_sec_context_by_oid,
     krb5_gss_inquire_cred_by_oid,
     krb5_gss_set_sec_context_option,

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -320,8 +320,8 @@
     krb5_keyblock *key;
     krb5_cksumtype cksumtype;
 
-    assert(ctx->big_endian == 0);
-    assert(ctx->proto == 1);
+    if (ctx->big_endian != 0)
+	goto defective;
 
     if (qop_state)
         *qop_state = GSS_C_QOP_DEFAULT;

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3iov.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3iov.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/k5sealv3iov.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -297,8 +297,8 @@
     krb5_cksumtype cksumtype;
     int conf_flag = 0;
 
-    assert(ctx->big_endian == 0);
-    assert(ctx->proto == 1);
+    if (ctx->big_endian != 0)
+	return GSS_S_DEFECTIVE_TOKEN;
 
     if (qop_state != NULL)
 	*qop_state = GSS_C_QOP_DEFAULT;

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/k5unseal.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/k5unseal.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/k5unseal.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -494,6 +494,7 @@
     unsigned int bodysize;
     int err;
     int toktype2;
+    int vfyflags = 0;
     OM_uint32 ret;
 
     /* validate the context handle */
@@ -515,26 +516,49 @@
 
     ptr = (unsigned char *) input_token_buffer->value;
 
-    toktype2 = kg_map_toktype(ctx->proto, toktype);
 
     err = g_verify_token_header(ctx->mech_used,
-                                &bodysize, &ptr, toktype2,
+                                &bodysize, &ptr, -1,
                                 input_token_buffer->length,
-                                !ctx->proto);
+                                vfyflags);
     if (err) {
         *minor_status = err;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    if (ctx->proto == 0)
+    if (bodysize < 2) {
+	*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
+	return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    toktype2 = load_16_be(ptr);
+
+    ptr += 2;
+    bodysize -= 2;
+
+    switch (toktype2) {
+    case KG2_TOK_MIC_MSG:
+    case KG2_TOK_WRAP_MSG:
+    case KG2_TOK_DEL_CTX:
+        ret = gss_krb5int_unseal_token_v3(&ctx->k5_context, minor_status, ctx,
+                                          ptr, bodysize, message_buffer,
+                                          conf_state, qop_state, toktype);
+	break;
+    case KG_TOK_MIC_MSG:
+    case KG_TOK_WRAP_MSG:
+    case KG_TOK_DEL_CTX:
         ret = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
                            message_buffer, conf_state, qop_state,
                            toktype);
-    else
-        ret = gss_krb5int_unseal_token_v3(&ctx->k5_context, minor_status, ctx,
-                                          ptr, bodysize, message_buffer,
-                                          conf_state, qop_state, toktype);
+	break;
+    default:
+	*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
+	ret = GSS_S_DEFECTIVE_TOKEN;
+	break;
+    }
+
     if (ret != 0)
         save_error_info (*minor_status, ctx->k5_context);
+
     return ret;
 }

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/k5unsealiov.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/k5unsealiov.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/k5unsealiov.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -172,7 +172,7 @@
 					      iov, iov_count);
 		krb5_free_keyblock(context, enc_key);
 	    } else {
-		code = kg_decrypt_iov(context, ctx->proto,
+		code = kg_decrypt_iov(context, 0,
 				      ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0),
 				      0 /*EC*/, 0 /*RRC*/,
 				      ctx->enc, KG_USAGE_SEAL, NULL,
@@ -325,8 +325,7 @@
 		    gss_qop_t *qop_state,
 		    gss_iov_buffer_desc *iov,
 		    int iov_count,
-		    int toktype,
-		    int toktype2)
+		    int toktype)
 {
     krb5_error_code code;
     krb5_context context = ctx->k5_context;
@@ -336,6 +335,7 @@
     gss_iov_buffer_t trailer;
     size_t input_length;
     unsigned int bodysize;
+    int toktype2;
     int vfyflags = 0;
 
     header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
@@ -364,26 +364,46 @@
 	    input_length += trailer->buffer.length;
     }
 
-    if (ctx->proto == 0)
-	vfyflags |= G_VFY_TOKEN_HDR_WRAPPER_REQUIRED;
     if (ctx->gss_flags & GSS_C_DCE_STYLE)
 	vfyflags |= G_VFY_TOKEN_HDR_IGNORE_SEQ_SIZE;
 
     code = g_verify_token_header(ctx->mech_used,
-				 &bodysize, &ptr, toktype2,
-				 input_length, vfyflags);
+				 &bodysize, &ptr, -1,
+				 input_length, 0);
     if (code != 0) {
-	*minor_status = code;
+        *minor_status = code;
+        return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    if (bodysize < 2) {
+	*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
 	return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    if (ctx->proto == 0)
+    toktype2 = load_16_be(ptr);
+
+    ptr += 2;
+    bodysize -= 2;
+
+    switch (toktype2) {
+    case KG2_TOK_MIC_MSG:
+    case KG2_TOK_WRAP_MSG:
+    case KG2_TOK_DEL_CTX:
+	code = gss_krb5int_unseal_v3_iov(context, minor_status, ctx, iov, iov_count,
+					 conf_state, qop_state, toktype);
+	break;
+    case KG_TOK_MIC_MSG:
+    case KG_TOK_WRAP_MSG:
+    case KG_TOK_DEL_CTX:
 	code = kg_unseal_v1_iov(context, minor_status, ctx, iov, iov_count,
 				(size_t)(ptr - (unsigned char *)header->buffer.value),
 			        conf_state, qop_state, toktype);
-    else
-	code = gss_krb5int_unseal_v3_iov(context, minor_status, ctx, iov, iov_count,
-					 conf_state, qop_state, toktype);
+	break;
+    default:
+	*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
+	code = GSS_S_DEFECTIVE_TOKEN;
+	break;
+    }
 
     if (code != 0)
 	save_error_info(*minor_status, context);
@@ -402,21 +422,19 @@
 		     gss_qop_t *qop_state,
 		     gss_iov_buffer_desc *iov,
 		     int iov_count,
-		     int toktype,
-		     int toktype2)
+		     int toktype)
 {
     unsigned char *ptr;
     unsigned int bodysize;
     OM_uint32 code = 0, major_status = GSS_S_FAILURE;
     krb5_context context = ctx->k5_context;
-    int conf_req_flag;
+    int conf_req_flag, toktype2;
     int i = 0, j;
     gss_iov_buffer_desc *tiov = NULL;
     gss_iov_buffer_t stream, data = NULL;
     gss_iov_buffer_t theader, tdata = NULL, tpadding, ttrailer;
 
     assert(toktype == KG_TOK_WRAP_MSG);
-    assert(toktype2 == KG_TOK_WRAP_MSG || toktype2 == KG2_TOK_WRAP_MSG);
 
     if (toktype != KG_TOK_WRAP_MSG || (ctx->gss_flags & GSS_C_DCE_STYLE)) {
 	code = EINVAL;
@@ -429,14 +447,23 @@
     ptr = (unsigned char *)stream->buffer.value;
 
     code = g_verify_token_header(ctx->mech_used,
-				 &bodysize, &ptr, toktype2,
-				 stream->buffer.length,
-				 ctx->proto ? 0 : G_VFY_TOKEN_HDR_WRAPPER_REQUIRED);
+				 &bodysize, &ptr, -1,
+				 stream->buffer.length, 0);
     if (code != 0) {
 	major_status = GSS_S_DEFECTIVE_TOKEN;
 	goto cleanup;
     }
 
+    if (bodysize < 2) {
+	*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
+	return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    toktype2 = load_16_be(ptr);
+
+    ptr += 2;
+    bodysize -= 2;
+
     tiov = (gss_iov_buffer_desc *)calloc((size_t)iov_count + 2, sizeof(gss_iov_buffer_desc));
     if (tiov == NULL) {
 	code = ENOMEM;
@@ -489,7 +516,10 @@
     ttrailer = &tiov[i++];
     ttrailer->type = GSS_IOV_BUFFER_TYPE_TRAILER;
 
-    if (ctx->proto == 1) {
+    switch (toktype2) {
+    case KG2_TOK_MIC_MSG:
+    case KG2_TOK_WRAP_MSG:
+    case KG2_TOK_DEL_CTX: {
 	size_t ec, rrc;
 	krb5_enctype enctype = ctx->enc->enctype;
 	unsigned int k5_headerlen = 0;
@@ -525,7 +555,11 @@
 	ttrailer->buffer.length = ec + (conf_req_flag ? 16 : 0 /* E(Header) */) + k5_trailerlen;
 	ttrailer->buffer.value = (unsigned char *)stream->buffer.value +
 				 stream->buffer.length - ttrailer->buffer.length;
-    } else {
+	break;
+    }
+    case KG_TOK_MIC_MSG:
+    case KG_TOK_WRAP_MSG:
+    case KG_TOK_DEL_CTX:
 	theader->buffer.length += ctx->cksum_size + kg_confounder_size(context, ctx->enc);
 
 	/*
@@ -538,6 +572,13 @@
 	/* no TRAILER for pre-CFX */
 	ttrailer->buffer.length = 0;
 	ttrailer->buffer.value = NULL;
+
+	break;
+    default:
+	code = (OM_uint32)G_BAD_TOK_HEADER;
+	major_status = GSS_S_DEFECTIVE_TOKEN;
+	goto cleanup;
+	break;
     }
 
     /* IOV: -----------0-------------+---1---+--2--+----------------3--------------*/
@@ -573,7 +614,7 @@
     assert(i <= iov_count + 2);
 
     major_status = kg_unseal_iov_token(&code, ctx, conf_state, qop_state,
-				       tiov, i, toktype, toktype2);
+				       tiov, i, toktype);
     if (major_status == GSS_S_COMPLETE)
 	*data = *tdata;
     else if (tdata->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
@@ -603,7 +644,6 @@
 {
     krb5_gss_ctx_id_rec *ctx;
     OM_uint32 code;
-    int toktype2;
 
     if (!kg_validate_ctx_id(context_handle)) {
 	*minor_status = (OM_uint32)G_VALIDATE_FAILED;
@@ -616,14 +656,12 @@
 	return GSS_S_NO_CONTEXT;
     }
 
-    toktype2 = kg_map_toktype(ctx->proto, toktype);
-
     if (kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM) != NULL) {
 	code = kg_unseal_stream_iov(minor_status, ctx, conf_state, qop_state,
-				    iov, iov_count, toktype, toktype2);
+				    iov, iov_count, toktype);
     } else {
 	code = kg_unseal_iov_token(minor_status, ctx, conf_state, qop_state,
-				   iov, iov_count, toktype, toktype2);
+				   iov, iov_count, toktype);
     }
 
     return code;

Modified: branches/mkey_migrate/src/lib/gssapi/krb5/util_crypt.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/krb5/util_crypt.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/krb5/util_crypt.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -56,6 +56,34 @@
 
 const char const kg_arcfour_l40[] = "fortybits";
 
+static krb5_error_code
+kg_copy_keys(krb5_context context,
+	     krb5_gss_ctx_id_rec *ctx,
+	     krb5_keyblock *subkey)
+{
+    krb5_error_code code;
+
+    if (ctx->enc != NULL) {
+	krb5_free_keyblock(context, ctx->enc);
+	ctx->enc = NULL;
+    }
+
+    code = krb5_copy_keyblock(context, subkey, &ctx->enc);
+    if (code != 0)
+	return code;
+
+    if (ctx->seq != NULL) {
+	krb5_free_keyblock(context, ctx->seq);
+	ctx->seq = NULL;
+    }
+
+    code = krb5_copy_keyblock(context, subkey, &ctx->seq);
+    if (code != 0)
+	return code;
+
+    return 0;
+}
+
 krb5_error_code
 kg_setup_keys(krb5_context context,
 	      krb5_gss_ctx_id_rec *ctx,
@@ -72,30 +100,28 @@
     *cksumtype = 0;
     ctx->proto = 0;
 
+    if (ctx->enc == NULL) {
+	ctx->signalg = -1;
+	ctx->sealalg = -1;
+    }
+        
     code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION);
     if (code != 0)
 	return code;
 
-    if (ctx->enc != NULL) {
-	krb5_free_keyblock(context, ctx->enc);
-	ctx->enc = NULL;
-    }
-    code = krb5_copy_keyblock(context, subkey, &ctx->enc);
+    code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype,
+						    cksumtype);
     if (code != 0)
 	return code;
 
-    if (ctx->seq != NULL) {
-	krb5_free_keyblock(context, ctx->seq);
-	ctx->seq = NULL;
-    }
-    code = krb5_copy_keyblock(context, subkey, &ctx->seq);
-    if (code != 0)
-	return code;
-
     switch (subkey->enctype) {
     case ENCTYPE_DES_CBC_MD5:
     case ENCTYPE_DES_CBC_MD4:
     case ENCTYPE_DES_CBC_CRC:
+	code = kg_copy_keys(context, ctx, subkey);
+	if (code != 0)
+	    return code;
+
 	ctx->enc->enctype = ENCTYPE_DES_CBC_RAW;
 	ctx->seq->enctype = ENCTYPE_DES_CBC_RAW;
 	ctx->signalg = SGN_ALG_DES_MAC_MD5;
@@ -107,6 +133,10 @@
 	    ctx->enc->contents[i] ^= 0xF0;
 	break;
     case ENCTYPE_DES3_CBC_SHA1:
+	code = kg_copy_keys(context, ctx, subkey);
+	if (code != 0)
+	    return code;
+
 	ctx->enc->enctype = ENCTYPE_DES3_CBC_RAW;
 	ctx->seq->enctype = ENCTYPE_DES3_CBC_RAW;
 	ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
@@ -115,19 +145,17 @@
 	break;
     case ENCTYPE_ARCFOUR_HMAC:
     case ENCTYPE_ARCFOUR_HMAC_EXP:
+	code = kg_copy_keys(context, ctx, subkey);
+	if (code != 0)
+	    return code;
+
 	ctx->signalg = SGN_ALG_HMAC_MD5;
 	ctx->cksum_size = 8;
 	ctx->sealalg = SEAL_ALG_MICROSOFT_RC4;
 	break;
     default:
-	ctx->signalg = -1;
-	ctx->sealalg = -1;
 	ctx->proto = 1;
-
-	code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype,
-							cksumtype);
-	if (code != 0)
-	    return code;
+	break;
     }
 
     return 0;

Modified: branches/mkey_migrate/src/lib/gssapi/libgssapi_krb5.exports
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/libgssapi_krb5.exports	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/libgssapi_krb5.exports	2009-01-21 19:16:22 UTC (rev 21769)
@@ -23,11 +23,9 @@
 gss_display_status
 gss_duplicate_name
 gss_export_name
-gss_export_name_object
 gss_export_sec_context
 gss_get_mic
 gss_import_name
-gss_import_name_object
 gss_import_sec_context
 gss_indicate_mechs
 gss_init_sec_context

Modified: branches/mkey_migrate/src/lib/gssapi/mechglue/Makefile.in
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/mechglue/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/mechglue/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -25,10 +25,8 @@
 	$(srcdir)/g_dup_name.c \
 	$(srcdir)/g_exp_sec_context.c \
 	$(srcdir)/g_export_name.c \
-	$(srcdir)/g_export_name_object.c \
 	$(srcdir)/g_glue.c \
 	$(srcdir)/g_imp_name.c \
-	$(srcdir)/g_imp_name_object.c \
 	$(srcdir)/g_imp_sec_context.c \
 	$(srcdir)/g_init_sec_context.c \
 	$(srcdir)/g_initialize.c \
@@ -71,10 +69,8 @@
 	$(OUTPRE)g_dup_name.$(OBJEXT) \
 	$(OUTPRE)g_exp_sec_context.$(OBJEXT) \
 	$(OUTPRE)g_export_name.$(OBJEXT) \
-	$(OUTPRE)g_export_name_object.$(OBJEXT) \
 	$(OUTPRE)g_glue.$(OBJEXT) \
 	$(OUTPRE)g_imp_name.$(OBJEXT) \
-	$(OUTPRE)g_imp_name_object.$(OBJEXT) \
 	$(OUTPRE)g_imp_sec_context.$(OBJEXT) \
 	$(OUTPRE)g_init_sec_context.$(OBJEXT) \
 	$(OUTPRE)g_initialize.$(OBJEXT) \
@@ -117,10 +113,8 @@
 	g_dup_name.o \
 	g_exp_sec_context.o \
 	g_export_name.o \
-	g_export_name_object.o \
 	g_glue.o \
 	g_imp_name.o \
-	g_imp_name_object.o \
 	g_imp_sec_context.o \
 	g_init_sec_context.o \
 	g_initialize.o \

Modified: branches/mkey_migrate/src/lib/gssapi/mechglue/deps
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/mechglue/deps	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/mechglue/deps	2009-01-21 19:16:22 UTC (rev 21769)
@@ -105,14 +105,6 @@
   $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
   ../generic/gssapi_err_generic.h g_export_name.c mechglue.h \
   mglueP.h
-g_export_name_object.so g_export_name_object.po $(OUTPRE)g_export_name_object.$(OBJEXT): \
-  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
-  $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \
-  $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \
-  $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
-  ../generic/gssapi_err_generic.h g_export_name_object.c \
-  mechglue.h mglueP.h
 g_glue.so g_glue.po $(OUTPRE)g_glue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \
@@ -128,14 +120,6 @@
   $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
   ../generic/gssapi_err_generic.h g_imp_name.c mechglue.h \
   mglueP.h
-g_imp_name_object.so g_imp_name_object.po $(OUTPRE)g_imp_name_object.$(OBJEXT): \
-  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
-  $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-platform.h \
-  $(SRCTOP)/include/k5-thread.h $(srcdir)/../generic/gssapiP_generic.h \
-  $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
-  ../generic/gssapi_err_generic.h g_imp_name_object.c \
-  mechglue.h mglueP.h
 g_imp_sec_context.so g_imp_sec_context.po $(OUTPRE)g_imp_sec_context.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \

Deleted: branches/mkey_migrate/src/lib/gssapi/mechglue/g_export_name_object.c

Deleted: branches/mkey_migrate/src/lib/gssapi/mechglue/g_imp_name_object.c

Modified: branches/mkey_migrate/src/lib/gssapi/mechglue/g_initialize.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/mechglue/g_initialize.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/mechglue/g_initialize.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -750,8 +750,6 @@
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_wrap_size_limit);
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name);
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_store_cred);
-	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_import_name_object);
-	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name_object);
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_sec_context_by_oid);
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_inquire_cred_by_oid);
 	GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_set_sec_context_option);

Modified: branches/mkey_migrate/src/lib/gssapi/mechglue/mglueP.h
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/mechglue/mglueP.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/mechglue/mglueP.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -370,22 +370,7 @@
 		gss_cred_usage_t *	/* cred_usage_stored */
 	/* */);
 
-	OM_uint32	(*gss_import_name_object)
-	(
-		OM_uint32 *,		/* minor_status */
-		void *,			/* input_name */
-		gss_OID,		/* input_name_type */
-		gss_name_t *		/* output_name */
-	/* */);
 
-	OM_uint32	(*gss_export_name_object)
-	(
-		OM_uint32 *,		/* minor_status */
-		gss_name_t,		/* input_name */
-		gss_OID,		/* desired_name_type */
-		void **			/* output_name */
-	/* */);
-
 	/* GGF extensions */
 
 	OM_uint32       (*gss_inquire_sec_context_by_oid)

Modified: branches/mkey_migrate/src/lib/gssapi/spnego/spnego_mech.c
===================================================================
--- branches/mkey_migrate/src/lib/gssapi/spnego/spnego_mech.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/gssapi/spnego/spnego_mech.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -247,8 +247,6 @@
 	spnego_gss_wrap_size_limit,	/* gss_wrap_size_limit */
 	NULL,				/* gss_export_name */
 	NULL,				/* gss_store_cred */
-	NULL,				/* gss_import_name_object */
-	NULL,				/* gss_export_name_object */
  	spnego_gss_inquire_sec_context_by_oid, /* gss_inquire_sec_context_by_oid */
  	NULL,				/* gss_inquire_cred_by_oid */
  	spnego_gss_set_sec_context_option, /* gss_set_sec_context_option */

Modified: branches/mkey_migrate/src/lib/kadm5/clnt/client_init.c
===================================================================
--- branches/mkey_migrate/src/lib/kadm5/clnt/client_init.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/kadm5/clnt/client_init.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -541,8 +541,12 @@
 	     goto error;
      }
 
-     if (init_type != INIT_CREDS)
+     /* Credentials for kadmin don't need to be forwardable or proxiable. */
+     if (init_type != INIT_CREDS) {
 	  krb5_get_init_creds_opt_init(&opt);
+	  krb5_get_init_creds_opt_set_forwardable(&opt, 0);
+	  krb5_get_init_creds_opt_set_proxiable(&opt, 0);
+     }
 
      if (init_type == INIT_PASS) {
 	  code = krb5_get_init_creds_password(ctx, &outcreds, client, pass,

Modified: branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c
===================================================================
--- branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -38,27 +38,26 @@
 			    int n_key_data, krb5_key_data *key_data,
 			    krb5_keyblock **keyblocks, int *n_keys);
 
-static krb5_error_code 
+static krb5_error_code
 kadm5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc)
 {
     register krb5_principal tempprinc;
     register int i, nelems;
-                                                                                                                            
+
     tempprinc = (krb5_principal)krb5_db_alloc(context, NULL, sizeof(krb5_principal_data));
-                                                                                                                            
+
     if (tempprinc == 0)
         return ENOMEM;
-                                                                                                                            
+
     memcpy(tempprinc, inprinc, sizeof(krb5_principal_data));
-                                                                                                                            
+
     nelems = (int) krb5_princ_size(context, inprinc);
     tempprinc->data = krb5_db_alloc(context, NULL, nelems * sizeof(krb5_data));
-                                                                                                                            
     if (tempprinc->data == 0) {
 	krb5_db_free(context, (char *)tempprinc);
         return ENOMEM;
     }
-                                                                                                                            
+
     for (i = 0; i < nelems; i++) {
         unsigned int len = krb5_princ_component(context, inprinc, i)->length;
         krb5_princ_component(context, tempprinc, i)->length = len;
@@ -74,7 +73,7 @@
             memcpy(krb5_princ_component(context, tempprinc, i)->data,
                    krb5_princ_component(context, inprinc, i)->data, len);
     }
-                                                                                                                            
+
     tempprinc->realm.data =
 	krb5_db_alloc(context, NULL, tempprinc->realm.length = inprinc->realm.length);
     if (!tempprinc->realm.data && tempprinc->realm.length) {
@@ -87,19 +86,19 @@
     if (tempprinc->realm.length)
         memcpy(tempprinc->realm.data, inprinc->realm.data,
                inprinc->realm.length);
-                                                                                                                            
+
     *outprinc = tempprinc;
     return 0;
 }
-                                                                                                                            
+
 static void
 kadm5_free_principal(krb5_context context, krb5_principal val)
 {
     register krb5_int32 i;
-                                                                                                                            
+
     if (!val)
         return;
-                                                                                                                            
+
     if (val->data) {
         i = krb5_princ_size(context, val);
         while(--i >= 0)
@@ -119,7 +118,7 @@
    krb5_key_data *from, *to;
 {
      int i, idx;
-     
+
      *to = *from;
 
      idx = (from->key_data_ver == 1 ? 1 : 2);
@@ -170,7 +169,7 @@
    krb5_key_data	* data;
 {
      int i, j;
-     
+
      for (i = 0; i < count; i++)
 	  for (j = 0; j < data[i].key_data_ver; j++)
 	       if (data[i].key_data_length[j])
@@ -247,7 +246,7 @@
     if ((mask & KADM5_POLICY)) {
 	 if ((ret = kadm5_get_policy(handle->lhandle, entry->policy,
 				     &polent)) != KADM5_OK) {
-	    if(ret == EINVAL) 
+	    if(ret == EINVAL)
 		return KADM5_BAD_POLICY;
 	    else
 		return ret;
@@ -273,14 +272,14 @@
     kdb.magic = KRB5_KDB_MAGIC_NUMBER;
     kdb.len = KRB5_KDB_V1_BASE_LENGTH; /* gag me with a chainsaw */
 
-    if ((mask & KADM5_ATTRIBUTES)) 
+    if ((mask & KADM5_ATTRIBUTES))
 	kdb.attributes = entry->attributes;
     else
        kdb.attributes = handle->params.flags;
 
     if ((mask & KADM5_MAX_LIFE))
-	kdb.max_life = entry->max_life; 
-    else 
+	kdb.max_life = entry->max_life;
+    else
 	kdb.max_life = handle->params.max_life;
 
     if (mask & KADM5_MAX_RLIFE)
@@ -302,7 +301,7 @@
     }
     if ((mask & KADM5_PW_EXPIRATION))
 	 kdb.pw_expiration = entry->pw_expiration;
-    
+
     kdb.last_success = 0;
     kdb.last_failed = 0;
     kdb.fail_auth_count = 0;
@@ -437,7 +436,7 @@
     return KADM5_OK;
 }
 
-	
+
 kadm5_ret_t
 kadm5_delete_principal(void *server_handle, krb5_principal principal)
 {
@@ -622,7 +621,7 @@
 					     KADM5_REF_COUNT)))))
 	goto done;
 
-    if ((mask & KADM5_ATTRIBUTES)) 
+    if ((mask & KADM5_ATTRIBUTES))
 	kdb.attributes = entry->attributes;
     if ((mask & KADM5_MAX_LIFE))
 	kdb.max_life = entry->max_life;
@@ -634,7 +633,7 @@
 	 kdb.max_renewable_life = entry->max_renewable_life;
     if (mask & KADM5_FAIL_AUTH_COUNT)
 	 kdb.fail_auth_count = entry->fail_auth_count;
-    
+
     if((mask & KADM5_KVNO)) {
 	 for (i = 0; i < kdb.n_key_data; i++)
 	      kdb.key_data[i].key_data_kvno = entry->kvno;
@@ -675,7 +674,7 @@
     kdb_free_entry(handle, &kdb, &adb);
     return ret;
 }
-    
+
 kadm5_ret_t
 kadm5_rename_principal(void *server_handle,
 			    krb5_principal source, krb5_principal target)
@@ -778,7 +777,7 @@
 
     if ((mask & KADM5_PRINCIPAL) &&
 	(ret = krb5_copy_principal(handle->context, kdb.princ,
-				   &entry->principal))) { 
+				   &entry->principal))) {
 	goto done;
     }
 
@@ -800,12 +799,12 @@
     /* values that must be checked separately against the mask */
     if ((mask & KADM5_MOD_NAME) || (mask & KADM5_MOD_TIME)) {
 	ret = krb5_dbe_lookup_mod_princ_data(handle->context, &kdb,
-					     &(entry->mod_date), 
+					     &(entry->mod_date),
 					     &(entry->mod_name));
 	if (ret) {
 	    goto done;
 	}
-	
+
 	if (! (mask & KADM5_MOD_TIME))
 	    entry->mod_date = 0;
 	if (! (mask & KADM5_MOD_NAME)) {
@@ -821,7 +820,7 @@
 	 for (entry->kvno = 0, i=0; i<kdb.n_key_data; i++)
 	      if (kdb.key_data[i].key_data_kvno > entry->kvno)
 		   entry->kvno = kdb.key_data[i].key_data_kvno;
-    
+
     ret = krb5_dbe_lookup_mkvno(handle->context, &kdb, &entry->mkvno);
     if (ret)
 	goto done;
@@ -857,7 +856,7 @@
 	      krb5_tl_data *tl, *tl2;
 
 	      entry->tl_data = NULL;
-	      
+
 	      tl = kdb.tl_data;
 	      while (tl) {
 		   if (tl->tl_data_type > 255) {
@@ -869,7 +868,7 @@
 			entry->tl_data = tl2;
 			entry->n_tl_data++;
 		   }
-			
+
 		   tl = tl->tl_data_next;
 	      }
 	 }
@@ -882,7 +881,7 @@
 			      ret = ENOMEM;
 			      goto done;
 		      }
-	      } else 
+	      } else
 		      entry->key_data = NULL;
 
 	      for (i = 0; i < entry->n_key_data; i++)
@@ -907,7 +906,7 @@
 	      ret = ENOMEM;
 	      goto done;
 	 }
-	 
+
 	 newv1->principal = entry->principal;
 	 newv1->princ_expire_time = entry->princ_expire_time;
 	 newv1->last_pwd_change = entry->last_pwd_change;
@@ -987,15 +986,15 @@
 						   &pw_hist_data[y].key_data[z],
 						   &histkey, NULL);
 		 if (ret)
-		     return(ret);		
-		 
+		     return(ret);
+
 		 if ((newkey.length == histkey.length) &&
 		     (newkey.enctype == histkey.enctype) &&
 		     (memcmp(newkey.contents, histkey.contents,
 			     histkey.length) == 0)) {
 		     krb5_free_keyblock_contents(context, &histkey);
 		     krb5_free_keyblock_contents(context, &newkey);
-		     
+
 		     return(KADM5_PASS_REUSE);
 		 }
 		 krb5_free_keyblock_contents(context, &histkey);
@@ -1034,7 +1033,7 @@
      int i, ret;
      krb5_keyblock key;
      krb5_keysalt salt;
-     
+
      hist->key_data = (krb5_key_data*)malloc(n_key_data*sizeof(krb5_key_data));
      if (hist->key_data == NULL)
 	  return ENOMEM;
@@ -1054,7 +1053,7 @@
 					   &hist->key_data[i]);
 	 if (ret)
 	     return ret;
-	 
+
 	 krb5_free_keyblock_contents(context, &key);
 	 /* krb5_free_keysalt(context, &salt); */
      }
@@ -1127,7 +1126,7 @@
 	  }
 	  if (adb->old_keys == NULL)
 	       return(ENOMEM);
-	  
+
 	  memset(&adb->old_keys[nkeys], 0, sizeof(osa_pw_hist_ent));
      	  nkeys = ++adb->old_key_len;
 	  /*
@@ -1227,7 +1226,7 @@
 #ifdef USE_PASSWORD_SERVER
 
 /*
- * kadm5_launch_task () runs a program (task_path) to synchronize the 
+ * kadm5_launch_task () runs a program (task_path) to synchronize the
  * Apple password server with the Kerberos database.  Password server
  * programs can receive arguments on the command line (task_argv)
  * and a block of data via stdin (data_buffer).
@@ -1240,11 +1239,11 @@
 static kadm5_ret_t
 kadm5_launch_task (krb5_context context,
                    const char *task_path, char * const task_argv[],
-                   const char *buffer) 
+                   const char *buffer)
 {
     kadm5_ret_t ret;
     int data_pipe[2];
-    
+
     ret = pipe (data_pipe);
     if (ret)
 	ret = errno;
@@ -1257,20 +1256,20 @@
 	    close (data_pipe[1]);
         } else if (pid == 0) {
             /* The child: */
-            
+
             if (dup2 (data_pipe[0], STDIN_FILENO) == -1)
 		_exit (1);
 
 	    close (data_pipe[0]);
 	    close (data_pipe[1]);
-            
+
             execv (task_path, task_argv);
-            
+
             _exit (1); /* Fail if execv fails */
         } else {
             /* The parent: */
             int status;
-                       
+
 	    ret = 0;
 
 	    close (data_pipe[0]);
@@ -1355,7 +1354,7 @@
 	 kdb_free_entry(handle, &kdb, &adb);
 	 return(ret);
     }
-    
+
     if ((adb.aux_attributes & KADM5_POLICY)) {
 	if ((ret = kadm5_get_policy(handle->lhandle, adb.policy, &pol)))
 	     goto done;
@@ -1388,7 +1387,7 @@
     ret = krb5_timeofday(handle->context, &now);
     if (ret)
 	 goto done;
-    
+
     if ((adb.aux_attributes & KADM5_POLICY)) {
        /* the policy was loaded before */
 
@@ -1423,7 +1422,7 @@
 			     1, &hist);
 	if (ret)
 	    goto done;
-	 
+
 	if (pol.pw_history_num > 1) {
 	    if (adb.admin_history_kvno != hist_kvno) {
 		ret = KADM5_BAD_HIST_KEY;
@@ -1470,10 +1469,10 @@
 
             ret = kadm5_launch_task (handle->context, path, argv, password);
         }
-        
+
         if (pstring != NULL)
             free (pstring);
-        
+
         if (ret)
             goto done;
     }
@@ -1498,7 +1497,7 @@
     krb5_db_free_principal(handle->context, &kdb, 1);
 
     if (have_pol && (ret2 = kadm5_free_policy_ent(handle->lhandle, &pol))
-	&& !ret) 
+	&& !ret)
 	 ret = ret2;
 
     return ret;
@@ -1570,7 +1569,7 @@
 
     if ((adb.aux_attributes & KADM5_POLICY)) {
 	if ((ret = kadm5_get_policy(handle->lhandle, adb.policy,
-				    &pol)) != KADM5_OK) 
+				    &pol)) != KADM5_OK)
 	   goto done;
 	have_pol = 1;
 
@@ -1625,7 +1624,7 @@
 					 -1, -1, &key_data);
 	     if (ret)
 		 goto done;
-	     
+
 	     ret = decrypt_key_data(handle->context, act_mkey, 1, key_data,
 				     keyblocks, NULL);
 	     if (ret)
@@ -1637,8 +1636,8 @@
 	     if (ret)
 		 goto done;
 	 }
-    }	 
-    
+    }
+
     /* key data changed, let the database provider know */
     kdb.mask = KADM5_KEY_DATA /* | KADM5_RANDKEY_USED */;
 
@@ -1694,7 +1693,7 @@
 
     if (keyblock->enctype != ENCTYPE_DES_CBC_CRC)
 	return KADM5_SETV4KEY_INVAL_ENCTYPE;
-    
+
     if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
        return(ret);
 
@@ -1704,7 +1703,7 @@
 
     if (kdb.key_data != NULL)
 	 cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
-    
+
     kdb.key_data = (krb5_key_data*)krb5_db_alloc(handle->context, NULL, sizeof(krb5_key_data));
     if (kdb.key_data == NULL)
 	 return ENOMEM;
@@ -1758,7 +1757,7 @@
 
     if ((adb.aux_attributes & KADM5_POLICY)) {
 	if ((ret = kadm5_get_policy(handle->lhandle, adb.policy,
-				    &pol)) != KADM5_OK) 
+				    &pol)) != KADM5_OK)
 	   goto done;
 	have_pol = 1;
 
@@ -1795,7 +1794,7 @@
 		goto done;
 	}
 #endif
-	
+
 	if (pol.pw_max_life)
 	   kdb.pw_expiration = now + pol.pw_max_life;
 	else
@@ -1897,7 +1896,7 @@
 
     if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
        return(ret);
-    
+
     for (kvno = 0, i=0; i<kdb.n_key_data; i++)
 	 if (kdb.key_data[i].key_data_kvno > kvno)
 	      kvno = kdb.key_data[i].key_data_kvno;
@@ -1911,7 +1910,7 @@
 	n_old_keys = 0;
 	old_key_data = NULL;
     }
-    
+
     kdb.key_data = (krb5_key_data*)krb5_db_alloc(handle->context, NULL, (n_keys+n_old_keys)
 						 *sizeof(krb5_key_data));
     if (kdb.key_data == NULL) {
@@ -1996,7 +1995,7 @@
 
     if ((adb.aux_attributes & KADM5_POLICY)) {
 	if ((ret = kadm5_get_policy(handle->lhandle, adb.policy,
-				    &pol)) != KADM5_OK) 
+				    &pol)) != KADM5_OK)
 	   goto done;
 	have_pol = 1;
 
@@ -2033,7 +2032,7 @@
 		goto done;
 	}
 #endif
-	
+
 	if (pol.pw_max_life)
 	   kdb.pw_expiration = now + pol.pw_max_life;
 	else
@@ -2136,7 +2135,7 @@
 
      for (i = 0; i < n_key_data; i++) {
           ret = krb5_dbekd_decrypt_key_data(context, mkey,
-					    &key_data[i], 
+					    &key_data[i],
 					    &keys[i], NULL);
 	  if (ret) {
 	       for (; i >= 0; i--) {
@@ -2237,4 +2236,3 @@
 
     return KADM5_OK;
 }
-

Modified: branches/mkey_migrate/src/lib/kadm5/unit-test/Makefile.in
===================================================================
--- branches/mkey_migrate/src/lib/kadm5/unit-test/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/kadm5/unit-test/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -87,28 +87,28 @@
 	unit-test-server-cleanup
 
 test-randkey:: randkey-test
-	$(ENV_SETUP) ./randkey-test
+	$(ENV_SETUP) $(VALGRIND) ./randkey-test
 
 test-handle-server:: server-handle-test
-	$(ENV_SETUP) ./server-handle-test
+	$(ENV_SETUP) $(VALGRIND) ./server-handle-test
 
 test-handle-client:: client-handle-test
-	$(ENV_SETUP) ./client-handle-test
+	$(ENV_SETUP) $(VALGRIND) ./client-handle-test
 
 test-noauth: init-test
-	$(ENV_SETUP) ./init-test
+	$(ENV_SETUP) $(VALGRIND) ./init-test
 
 test-destroy: destroy-test
-	$(ENV_SETUP) ./destroy-test
+	$(ENV_SETUP) $(VALGRIND) ./destroy-test
 
 unit-test-client-setup::
-	$(ENV_SETUP) $(START_SERVERS)
+	$(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
 
 unit-test-client-cleanup::
 	$(ENV_SETUP) $(STOP_SERVERS)
 
 unit-test-server-setup::
-	$(ENV_SETUP) $(START_SERVERS_LOCAL)
+	$(ENV_SETUP) $(VALGRIND) $(START_SERVERS_LOCAL)
 
 unit-test-server-cleanup::
 	$(ENV_SETUP) $(STOP_SERVERS_LOCAL)
@@ -118,7 +118,8 @@
 		KINIT=$(BUILDTOP)/clients/kinit/kinit \
 		KDESTROY=$(BUILDTOP)/clients/kdestroy/kdestroy \
 		KADMIN_LOCAL=$(BUILDTOP)/kadmin/cli/kadmin.local \
-		PRIOCNTL_HACK=@PRIOCNTL_HACK@ $(RUNTESTFLAGS)
+		PRIOCNTL_HACK=@PRIOCNTL_HACK@ VALGRIND="$(VALGRIND)" \
+		$(RUNTESTFLAGS)
 	-mv api.log capi.log
 	-mv api.sum capi.sum
 
@@ -126,7 +127,8 @@
 	$(ENV_SETUP) $(RUNTEST) --tool api RPC=0 API=$(SRVTCL) \
 		LOCKTEST=./lock-test \
 		KADMIN_LOCAL=$(BUILDTOP)/kadmin/cli/kadmin.local \
-		PRIOCNTL_HACK=@PRIOCNTL_HACK@ $(RUNTESTFLAGS)
+		PRIOCNTL_HACK=@PRIOCNTL_HACK@ VALGRIND="$(VALGRIND)" \
+		$(RUNTESTFLAGS)
 	-mv api.log sapi.log
 	-mv api.sum sapi.sum
 

Modified: branches/mkey_migrate/src/lib/kadm5/unit-test/config/unix.exp
===================================================================
--- branches/mkey_migrate/src/lib/kadm5/unit-test/config/unix.exp	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/kadm5/unit-test/config/unix.exp	2009-01-21 19:16:22 UTC (rev 21769)
@@ -14,6 +14,47 @@
 	set wait_status_index 3
 }
 
+if { [string length $VALGRIND] } {
+    rename spawn valgrind_aux_spawn
+    proc spawn { args } {
+	global VALGRIND
+	upvar 1 spawn_id spawn_id
+	set newargs {}
+	set inflags 1
+	set eatnext 0
+	foreach arg $args {
+	    if { $arg == "-ignore" \
+		     || $arg == "-open" \
+		     || $arg == "-leaveopen" } {
+		lappend newargs $arg
+		set eatnext 1
+		continue
+	    }
+	    if [string match "-*" $arg] {
+		lappend newargs $arg
+		continue
+	    }
+	    if { $eatnext } {
+		set eatnext 0
+		lappend newargs $arg
+		continue
+	    }
+	    if { $inflags } {
+		set inflags 0
+		# Only run valgrind for local programs, not
+		# system ones.
+#&&![string match "/bin/sh" $arg] sh is used to start kadmind!
+		if [string match "/" [string index $arg 0]]&&![string match "/bin/ls" $arg]&&![regexp {/kshd$} $arg] {
+		    set newargs [concat $newargs $VALGRIND]
+		}
+	    }
+	    lappend newargs $arg
+	}
+	set pid [eval valgrind_aux_spawn $newargs]
+	return $pid
+    }
+}
+
 # Hack around Solaris 9 kernel race condition that causes last output
 # from a pty to get dropped.
 if { $PRIOCNTL_HACK } {

Modified: branches/mkey_migrate/src/lib/krb5/krb/auth_con.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/auth_con.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/auth_con.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -556,3 +556,13 @@
     else
 	return 0;
 }
+
+krb5_error_code
+krb5_auth_con_get_subkey_enctype(krb5_context context,
+				 krb5_auth_context auth_context,
+				 krb5_enctype *etype)
+{
+    *etype = auth_context->negotiated_etype;
+    return 0;
+}
+

Modified: branches/mkey_migrate/src/lib/krb5/krb/mk_cred.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/mk_cred.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/mk_cred.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -258,6 +258,7 @@
             goto error;
 
         replay.server = "";             /* XXX */
+        replay.msghash = NULL;
         replay.cusec = replaydata.usec;
         replay.ctime = replaydata.timestamp;
         if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/mk_priv.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/mk_priv.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/mk_priv.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -214,6 +214,7 @@
 	}
 
 	replay.server = "";		/* XXX */
+	replay.msghash = NULL;
 	replay.cusec = replaydata.usec;
 	replay.ctime = replaydata.timestamp;
 	if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/mk_req_ext.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/mk_req_ext.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/mk_req_ext.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -343,23 +343,15 @@
     for (etypes.length = 0;
 	 etypes.etypes[etypes.length] != ENCTYPE_NULL;
 	 etypes.length++)
-	;
-
-    /*
-     * RFC 4537:
-     *
-     *   If the enctype of the ticket session key is included in the enctype
-     *   list sent by the client, it SHOULD be the last on the list;
-     */
-    for (i = 0; i < etypes.length; i++) {
-	if (etypes.etypes[i] == tkt_enctype) {
-	    krb5_enctype etype;
-
-	    etype = etypes.etypes[etypes.length - 1];
-	    etypes.etypes[etypes.length - 1] = tkt_enctype;
-	    etypes.etypes[i] = etype;
+    {
+	/*
+	 * RFC 4537:
+	 *
+	 *   If the enctype of the ticket session key is included in the enctype
+	 *   list sent by the client, it SHOULD be the last on the list;
+	 */
+	if (etypes.length && etypes.etypes[etypes.length - 1] == tkt_enctype)
 	    break;
-	}
     }
 
     code = encode_krb5_etype_list(&etypes, &enc_etype_list);

Modified: branches/mkey_migrate/src/lib/krb5/krb/mk_safe.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/mk_safe.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/mk_safe.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -239,6 +239,7 @@
 	}
 
 	replay.server = "";		/* XXX */
+	replay.msghash = NULL;
 	replay.cusec = replaydata.usec;
 	replay.ctime = replaydata.timestamp;
 	if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/pac.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/pac.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/pac.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -378,7 +378,7 @@
 }
 
 static krb5_error_code
-k5_time_to_seconds_since_1970(krb5_ui_8 ntTime, krb5_timestamp *elapsedSeconds)
+k5_time_to_seconds_since_1970(krb5_int64 ntTime, krb5_timestamp *elapsedSeconds)
 {
     krb5_ui_8 abstime;
 
@@ -419,7 +419,7 @@
     unsigned char *p;
     krb5_timestamp pac_authtime;
     krb5_ui_2 pac_princname_length;
-    krb5_ui_8 pac_nt_authtime;
+    krb5_int64 pac_nt_authtime;
     krb5_principal pac_principal;
 
     ret = k5_pac_locate_buffer(context, pac, PAC_CLIENT_INFO, &client_info);

Modified: branches/mkey_migrate/src/lib/krb5/krb/rd_cred.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/rd_cred.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/rd_cred.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -210,6 +210,7 @@
             goto error;
 
         replay.server = "";             /* XXX */
+        replay.msghash = NULL;
         replay.cusec = replaydata.usec;
         replay.ctime = replaydata.timestamp;
         if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/rd_priv.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/rd_priv.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/rd_priv.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -235,6 +235,7 @@
 	    goto error;
 
 	replay.server = "";		/* XXX */
+	replay.msghash = NULL;
 	replay.cusec = replaydata.usec;
 	replay.ctime = replaydata.timestamp;
 	if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/rd_rep.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/rd_rep.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/rd_rep.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -151,7 +151,7 @@
     krb5_error_code 	  retval;
     krb5_ap_rep 	* reply;
     krb5_data 	 	  scratch;
-    krb5_ap_rep_enc_part *repl;
+    krb5_ap_rep_enc_part *repl = NULL;
 
     if (!krb5_is_ap_rep(inbuf))
 	return KRB5KRB_AP_ERR_MSG_TYPE;

Modified: branches/mkey_migrate/src/lib/krb5/krb/rd_req_dec.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/rd_req_dec.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/rd_req_dec.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -349,7 +349,13 @@
 	tktauthent.ticket = req->ticket;	
 	tktauthent.authenticator = (*auth_context)->authentp;
 	if (!(retval = krb5_auth_to_rep(context, &tktauthent, &rep))) {
-	    retval = krb5_rc_store(context, (*auth_context)->rcache, &rep);
+	    retval = krb5_rc_hash_message(context,
+					  &req->authenticator.ciphertext,
+					  &rep.msghash);
+	    if (!retval) {
+		retval = krb5_rc_store(context, (*auth_context)->rcache, &rep);
+		krb5_xfree(rep.msghash);
+	    }
 	    krb5_xfree(rep.server);
 	    krb5_xfree(rep.client);
 	}
@@ -421,7 +427,6 @@
 	desired_etypes[desired_etypes_len++] = (*auth_context)->authentp->subkey->enctype;
     }
     desired_etypes[desired_etypes_len++] = req->ticket->enc_part2->session->enctype;
-    desired_etypes[desired_etypes_len++] = req->ticket->enc_part.enctype;
     desired_etypes[desired_etypes_len] = ENCTYPE_NULL;
 
     if (((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_PERMIT_ALL) == 0) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/rd_safe.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/rd_safe.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/rd_safe.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -241,6 +241,7 @@
 	    goto error;
 
 	replay.server = "";		/* XXX */
+	replay.msghash = NULL;
 	replay.cusec = replaydata.usec;
 	replay.ctime = replaydata.timestamp;
 	if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {

Modified: branches/mkey_migrate/src/lib/krb5/krb/sendauth.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/krb/sendauth.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/krb/sendauth.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/krb/sendauth.c
  *
- * Copyright 1991 by the Massachusetts Institute of Technology.
+ * Copyright 1991, 2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -38,14 +38,19 @@
 static const char sendauth_version[] = "KRB5_SENDAUTH_V1.0";
 
 krb5_error_code KRB5_CALLCONV
-krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal client, krb5_principal server, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache, krb5_error **error, krb5_ap_rep_enc_part **rep_result, krb5_creds **out_creds)
+krb5_sendauth(krb5_context context, krb5_auth_context *auth_context,
+	      krb5_pointer fd, char *appl_version, krb5_principal client,
+	      krb5_principal server, krb5_flags ap_req_options,
+	      krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache,
+	      krb5_error **error, krb5_ap_rep_enc_part **rep_result,
+	      krb5_creds **out_creds)
 {
 	krb5_octet		result;
 	krb5_creds 		creds;
 	krb5_creds		 * credsp = NULL;
 	krb5_creds		 * credspout = NULL;
 	krb5_error_code		retval = 0;
-	krb5_data		inbuf, outbuf;
+	krb5_data		inbuf, outbuf[2];
 	int			len;
 	krb5_ccache		use_ccache = 0;
 
@@ -58,14 +63,12 @@
 	 * over the length of the application version strings followed
 	 * by the string itself.  
 	 */
-	outbuf.length = strlen(sendauth_version) + 1;
-	outbuf.data = (char *) sendauth_version;
-	if ((retval = krb5_write_message(context, fd, &outbuf)))
+	outbuf[0].length = strlen(sendauth_version) + 1;
+	outbuf[0].data = (char *) sendauth_version;
+	outbuf[1].length = strlen(appl_version) + 1;
+	outbuf[1].data = appl_version;
+	if ((retval = krb5int_write_messages(context, fd, outbuf, 2)))
 		return(retval);
-	outbuf.length = strlen(appl_version) + 1;
-	outbuf.data = appl_version;
-	if ((retval = krb5_write_message(context, fd, &outbuf)))
-		return(retval);
 	/*
 	 * Now, read back a byte: 0 means no error, 1 means bad sendauth
 	 * version, 2 means bad application version
@@ -154,15 +157,15 @@
 
 	if ((retval = krb5_mk_req_extended(context, auth_context,
 					   ap_req_options, in_data, credsp,
-					   &outbuf)))
+					   &outbuf[0])))
 	    goto error_return;
 
 	/*
 	 * First write the length of the AP_REQ message, then write
 	 * the message itself.
 	 */
-	retval = krb5_write_message(context, fd, &outbuf);
-	free(outbuf.data);
+	retval = krb5_write_message(context, fd, &outbuf[0]);
+	free(outbuf[0].data);
 	if (retval)
 	    goto error_return;
 

Modified: branches/mkey_migrate/src/lib/krb5/libkrb5.exports
===================================================================
--- branches/mkey_migrate/src/lib/krb5/libkrb5.exports	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/libkrb5.exports	2009-01-21 19:16:22 UTC (rev 21769)
@@ -401,6 +401,7 @@
 krb5_rc_get_lifespan
 krb5_rc_get_name
 krb5_rc_get_type
+krb5_rc_hash_message
 krb5_rc_initialize
 krb5_rc_io_close
 krb5_rc_io_creat
@@ -414,6 +415,7 @@
 krb5_rc_io_unmark
 krb5_rc_io_write
 krb5_rc_recover
+krb5_rc_recover_or_initialize
 krb5_rc_register_type
 krb5_rc_resolve
 krb5_rc_resolve_full

Modified: branches/mkey_migrate/src/lib/krb5/os/accessor.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/accessor.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/accessor.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -53,6 +53,7 @@
 #endif
 	    S (free_addrlist, krb5int_free_addrlist),
 	    S (krb5_hmac, krb5_hmac),
+	    S (krb5_auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype),
 	    S (md5_hash_provider, &krb5int_hash_md5),
 	    S (arcfour_enc_provider, &krb5int_enc_arcfour),
 	    S (sendto_udp, &krb5int_sendto),

Modified: branches/mkey_migrate/src/lib/krb5/os/deps
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/deps	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/deps	2009-01-21 19:16:22 UTC (rev 21769)
@@ -277,7 +277,7 @@
   $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
   $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
   $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h net_write.c
+  $(SRCTOP)/include/socket-utils.h net_write.c os-proto.h
 osconfig.so osconfig.po $(OUTPRE)osconfig.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -429,7 +429,7 @@
   $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
   $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
   $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h write_msg.c
+  $(SRCTOP)/include/socket-utils.h os-proto.h write_msg.c
 t_an_to_ln.so t_an_to_ln.po $(OUTPRE)t_an_to_ln.$(OBJEXT): \
   $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/krb5.h \
   t_an_to_ln.c

Modified: branches/mkey_migrate/src/lib/krb5/os/hst_realm.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/hst_realm.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/hst_realm.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/os/hst_realm.c
  *
- * Copyright 1990,1991,2002 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2002,2008 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -208,7 +208,9 @@
     printf("get_host_realm(host:%s) called\n",host);
 #endif
 
-    krb5int_clean_hostname(context, host, local_host, sizeof local_host);
+    retval = krb5int_clean_hostname(context, host, local_host, sizeof local_host);
+    if (retval)
+        return retval;
 
     /*
        Search for the best match for the host or domain.
@@ -350,7 +352,9 @@
     printf("get_fallback_host_realm(host >%s<) called\n",host);
 #endif
 
-    krb5int_clean_hostname(context, host, local_host, sizeof local_host);
+    retval = krb5int_clean_hostname(context, host, local_host, sizeof local_host);
+    if (retval)
+        return retval;
 
     /*
      * Try looking up a _kerberos.<hostname> TXT record in DNS.  This

Modified: branches/mkey_migrate/src/lib/krb5/os/net_write.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/net_write.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/net_write.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/os/net_write.c
  *
- * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1987, 1988, 1990, 2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -26,6 +26,7 @@
  */
 
 #include "k5-int.h"
+#include "os-proto.h"
 
 /*
  * krb5_net_write() writes "len" bytes from "buf" to the file
@@ -37,25 +38,45 @@
  */
 
 int
-krb5_net_write(krb5_context context, int fd, register const char *buf, int len)
+krb5_net_write(krb5_context context, int fd, const char *buf, int len)
 {
-    int cc;
-    register int wrlen = len;
-    do {
-	cc = SOCKET_WRITE((SOCKET)fd, buf, wrlen);
+    sg_buf sg;
+    SG_SET(&sg, buf, len);
+    return krb5int_net_writev(context, fd, &sg, 1);
+}
+
+int
+krb5int_net_writev(krb5_context context, int fd, sg_buf *sgp, int nsg)
+{
+    int cc, len = 0;
+    SOCKET_WRITEV_TEMP tmp;
+
+    while (nsg > 0) {
+	/* Skip any empty data blocks.  */
+	if (SG_LEN(sgp) == 0) {
+	    sgp++, nsg--;
+	    continue;
+	}
+	cc = SOCKET_WRITEV((SOCKET)fd, sgp, nsg, tmp);
 	if (cc < 0) {
 	    if (SOCKET_ERRNO == SOCKET_EINTR)
 		continue;
 
-		/* XXX this interface sucks! */
-        errno = SOCKET_ERRNO;           
-
-	    return(cc);
+	    /* XXX this interface sucks! */
+	    errno = SOCKET_ERRNO;           
+	    return -1;
 	}
-	else {
-	    buf += cc;
-	    wrlen -= cc;
+	len += cc;
+	while (cc > 0) {
+	    if ((unsigned)cc < SG_LEN(sgp)) {
+		SG_ADVANCE(sgp, (unsigned)cc);
+		cc = 0;
+	    } else {
+		cc -= SG_LEN(sgp);
+		sgp++, nsg--;
+		assert(nsg > 0 || cc == 0);
+	    }
 	}
-    } while (wrlen > 0);
-    return(len);
+    }
+    return len;
 }

Modified: branches/mkey_migrate/src/lib/krb5/os/os-proto.h
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/os-proto.h	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/os-proto.h	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/os/os-proto.h
  *
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -62,6 +62,9 @@
 int _krb5_use_dns_kdc (krb5_context);
 int _krb5_conf_boolean (const char *);
 
+/* The io vector is *not* const here, unlike writev()!  */
+int krb5int_net_writev (krb5_context, int, sg_buf *, int);
+
 #include "k5-thread.h"
 extern k5_mutex_t krb5int_us_time_mutex;
 

Modified: branches/mkey_migrate/src/lib/krb5/os/write_msg.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/os/write_msg.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/os/write_msg.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/os/write_msg.c
  *
- * Copyright 1991 by the Massachusetts Institute of Technology.
+ * Copyright 1991, 2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -29,19 +29,48 @@
 
 #include "k5-int.h"
 #include <errno.h>
+#include "os-proto.h"
 
+/* Try to write a series of messages with as few write(v) system calls
+   as possible, to avoid Nagle/DelayedAck problems.  Cheating here a
+   little -- I know the only cases we have at the moment will send one
+   or two messages in a call.  Sending more will work, but not as
+   efficiently.  */
 krb5_error_code
-krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf)
+krb5int_write_messages(krb5_context context, krb5_pointer fdp, krb5_data *outbuf, int nbufs)
 {
-	krb5_int32	len;
-	int		fd = *( (int *) fdp);
+    int fd = *( (int *) fdp);
 
-	len = htonl(outbuf->length);
-	if (krb5_net_write(context, fd, (char *)&len, 4) < 0) {
-		return(errno);
+    while (nbufs) {
+	int nbufs1;
+	sg_buf sg[4];
+	krb5_int32 len[2];
+
+	if (nbufs > 1)
+	    nbufs1 = 2;
+	else
+	    nbufs1 = 1;
+	len[0] = htonl(outbuf[0].length);
+	SG_SET(&sg[0], &len[0], 4);
+	SG_SET(&sg[1], outbuf[0].length ? outbuf[0].data : NULL,
+	       outbuf[0].length);
+	if (nbufs1 == 2) {
+	    len[1] = htonl(outbuf[1].length);
+	    SG_SET(&sg[2], &len[1], 4);
+	    SG_SET(&sg[3], outbuf[1].length ? outbuf[1].data : NULL,
+		   outbuf[1].length);
 	}
-	if (outbuf->length && (krb5_net_write(context, fd, outbuf->data, outbuf->length) < 0)) {
-		return(errno);
+	if (krb5int_net_writev(context, fd, sg, nbufs1 * 2) < 0) {
+	    return errno;
 	}
-	return(0);
+	outbuf += nbufs1;
+	nbufs -= nbufs1;
+    }
+    return(0);
 }
+
+krb5_error_code
+krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf)
+{
+    return krb5int_write_messages(context, fdp, outbuf, 1);
+}

Modified: branches/mkey_migrate/src/lib/krb5/rcache/Makefile.in
===================================================================
--- branches/mkey_migrate/src/lib/krb5/rcache/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/rcache/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -2,6 +2,8 @@
 myfulldir=lib/krb5/rcache
 mydir=lib/krb5/rcache
 BUILDTOP=$(REL)..$(S)..$(S)..
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
 DEFS=
 
 ##DOS##BUILDTOP = ..\..\..
@@ -36,12 +38,18 @@
 	$(srcdir)/rc_none.c	\
 	$(srcdir)/rc_conv.c	\
 	$(srcdir)/ser_rc.c	\
-	$(srcdir)/rcfns.c
+	$(srcdir)/rcfns.c	\
+	$(srcdir)/t_replay.c
 
 ##DOS##LIBOBJS = $(OBJS)
 
 all-unix:: all-libobjs
 clean-unix:: clean-libobjs
 
+T_REPLAY_OBJS= t_replay.o
+
+t_replay: $(T_REPLAY_OBJS) $(KRB5_BASE_DEPLIBS)
+	$(CC_LINK) -o t_replay $(T_REPLAY_OBJS) $(KRB5_BASE_LIBS)
+
 @libobj_frag@
 

Modified: branches/mkey_migrate/src/lib/krb5/rcache/deps
===================================================================
--- branches/mkey_migrate/src/lib/krb5/rcache/deps	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/rcache/deps	2009-01-21 19:16:22 UTC (rev 21769)
@@ -81,3 +81,13 @@
   $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
   rc-int.h rcfns.c
+t_replay.so t_replay.po $(OUTPRE)t_replay.$(OBJEXT): \
+  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+  $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
+  $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
+  $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
+  $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+  $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h t_replay.c

Modified: branches/mkey_migrate/src/lib/krb5/rcache/rc_conv.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/rcache/rc_conv.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/rcache/rc_conv.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -36,3 +36,44 @@
     }
     return 0;
 }
+
+/*
+ * Generate a printable hash value for a message for use in a replay
+ * record.  It is not necessary for this hash function to be
+ * collision-proof (the only thing you can do with a second preimage
+ * is produce a false replay error) but it is necessary for the
+ * function to be consistent across implementations.  We do an unkeyed
+ * MD5 hash of the message and convert it into uppercase hex
+ * representation.
+ */
+krb5_error_code
+krb5_rc_hash_message(krb5_context context, const krb5_data *message,
+                     char **out)
+{
+    krb5_error_code retval;
+    krb5_checksum cksum;
+    char *hash, *ptr;
+    unsigned int i;
+
+    *out = NULL;
+
+    /* Calculate the binary checksum. */
+    retval = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0,
+                                  message, &cksum);
+    if (retval)
+        return retval;
+
+    /* Convert the checksum into printable form. */
+    hash = malloc(cksum.length * 2 + 1);
+    if (!hash) {
+        krb5_free_checksum_contents(context, &cksum);
+        return KRB5_RC_MALLOC;
+    }
+    ptr = hash;
+    for (i = 0, ptr = hash; i < cksum.length; i++, ptr += 2)
+        snprintf(ptr, 3, "%02X", cksum.contents[i]);
+    *ptr = '\0';
+    *out = hash;
+    krb5_free_checksum_contents(context, &cksum);
+    return 0;
+}

Modified: branches/mkey_migrate/src/lib/krb5/rcache/rc_dfl.c
===================================================================
--- branches/mkey_migrate/src/lib/krb5/rcache/rc_dfl.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/krb5/rcache/rc_dfl.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -10,7 +10,6 @@
 /*
  * An implementation for the default replay cache type.
  */
-#define FREE(x) ((void) free((char *) (x)))
 #include "rc_base.h"
 #include "rc_dfl.h"
 #include "rc_io.h"
@@ -85,8 +84,12 @@
     if ((old->cusec == new1->cusec) && /* most likely to distinguish */
         (old->ctime == new1->ctime) &&
         (strcmp(old->client, new1->client) == 0) &&
-        (strcmp(old->server, new1->server) == 0)) /* always true */
-        return CMP_REPLAY;
+        (strcmp(old->server, new1->server) == 0)) { /* always true */
+        /* If both records include message hashes, compare them as well. */
+        if (old->msghash == NULL || new1->msghash == NULL ||
+            strcmp(old->msghash, new1->msghash) == 0)
+            return CMP_REPLAY;
+    }
     return CMP_HOHUM;
 }
 
@@ -128,7 +131,7 @@
 
 static int
 rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep,
-         krb5_int32 now)
+         krb5_int32 now, krb5_boolean fromfile)
 {
     struct dfl_data *t = (struct dfl_data *)id->data;
     unsigned int rephash;
@@ -140,7 +143,20 @@
         switch(cmp(&ta->rep, rep, t->lifespan))
         {
         case CMP_REPLAY:
-            return CMP_REPLAY;
+            if (fromfile) {
+                /*
+                 * This is an expected collision between a hash
+                 * extension record and a normal-format record.  Make
+                 * sure the message hash is included in the stored
+                 * record and carry on.
+                 */
+                if (!ta->rep.msghash && rep->msghash) {
+                    if (!(ta->rep.msghash = strdup(rep->msghash)))
+                        return CMP_MALLOC;
+                }
+                return CMP_HOHUM;
+            } else
+                return CMP_REPLAY;
         case CMP_HOHUM:
             if (alive(now, &ta->rep, t->lifespan) == CMP_EXPIRED)
                 t->nummisses++;
@@ -154,20 +170,26 @@
 
     if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
         return CMP_MALLOC;
+    ta->rep = *rep;
+    ta->rep.client = ta->rep.server = ta->rep.msghash = NULL;
+    if (!(ta->rep.client = strdup(rep->client)))
+        goto error;
+    if (!(ta->rep.server = strdup(rep->server)))
+        goto error;
+    if (rep->msghash && !(ta->rep.msghash = strdup(rep->msghash)))
+        goto error;
     ta->na = t->a; t->a = ta;
     ta->nh = t->h[rephash]; t->h[rephash] = ta;
-    ta->rep = *rep;
-    if (!(ta->rep.client = strdup(rep->client))) {
-        FREE(ta);
-        return CMP_MALLOC;
-    }
-    if (!(ta->rep.server = strdup(rep->server))) {
-        FREE(ta->rep.client);
-        FREE(ta);
-        return CMP_MALLOC;
-    }
-
     return CMP_HOHUM;
+error:
+    if (ta->rep.client)
+        free(ta->rep.client);
+    if (ta->rep.server)
+        free(ta->rep.server);
+    if (ta->rep.msghash)
+        free(ta->rep.msghash);
+    free(ta);
+    return CMP_MALLOC;
 }
 
 char * KRB5_CALLCONV
@@ -233,20 +255,22 @@
     struct dfl_data *t = (struct dfl_data *)id->data;
     struct authlist *q;
 
-    FREE(t->h);
+    free(t->h);
     if (t->name)
-        FREE(t->name);
+        free(t->name);
     while ((q = t->a))
     {
         t->a = q->na;
-        FREE(q->rep.client);
-        FREE(q->rep.server);
-        FREE(q);
+        free(q->rep.client);
+        free(q->rep.server);
+        if (q->rep.msghash)
+            free(q->rep.msghash);
+        free(q);
     }
 #ifndef NOIOSTUFF
     (void) krb5_rc_io_close(context, &t->d);
 #endif
-    FREE(t);
+    free(t);
     return 0;
 }
 
@@ -328,16 +352,112 @@
     {
         if (rp->client)
             free(rp->client);
-
         if (rp->server)
             free(rp->server);
+        if (rp->msghash)
+            free(rp->msghash);
         rp->client = NULL;
         rp->server = NULL;
+        rp->msghash = NULL;
         free(rp);
     }
 }
 
+/*
+ * Parse a string in the format <len>:<data>, with the length
+ * represented in ASCII decimal.  On parse failure, return 0 but set
+ * *result to NULL.
+ */
 static krb5_error_code
+parse_counted_string(char **strptr, char **result)
+{
+    char *str = *strptr, *end;
+    unsigned long len;
+
+    *result = NULL;
+
+    /* Parse the length, expecting a ':' afterwards. */
+    errno = 0;
+    len = strtoul(str, &end, 10);
+    if (errno != 0 || *end != ':' || len > strlen(end + 1))
+        return 0;
+
+    /* Allocate space for *result and copy the data. */
+    *result = malloc(len + 1);
+    if (!*result)
+        return KRB5_RC_MALLOC;
+    memcpy(*result, end + 1, len);
+    (*result)[len] = '\0';
+    *strptr = end + 1 + len;
+    return 0;
+}
+
+/*
+ * Hash extension records have the format:
+ *  client = <empty string>
+ *  server = HASH:<msghash> <clientlen>:<client> <serverlen>:<server>
+ * Spaces in the client and server string are represented with 
+ * with backslashes.  Client and server lengths are represented in
+ * ASCII decimal (which is different from the 32-bit binary we use
+ * elsewhere in the replay cache).
+ *
+ * On parse failure, we leave the record unmodified.
+ */
+static krb5_error_code
+check_hash_extension(krb5_donot_replay *rep)
+{
+    char *msghash = NULL, *client = NULL, *server = NULL, *str, *end;
+    krb5_error_code retval = 0;
+
+    /* Check if this appears to match the hash extension format. */
+    if (*rep->client)
+        return 0;
+    if (strncmp(rep->server, "HASH:", 5) != 0)
+        return 0;
+
+    /* Parse out the message hash. */
+    str = rep->server + 5;
+    end = strchr(str, ' ');
+    if (!end)
+        return 0;
+    msghash = malloc(end - str + 1);
+    if (!msghash)
+        return KRB5_RC_MALLOC;
+    memcpy(msghash, str, end - str);
+    msghash[end - str] = '\0';
+    str = end + 1;
+
+    /* Parse out the client and server. */
+    retval = parse_counted_string(&str, &client);
+    if (retval != 0 || client == NULL)
+        goto error;
+    if (*str != ' ')
+        goto error;
+    str++;
+    retval = parse_counted_string(&str, &server);
+    if (retval != 0 || server == NULL)
+        goto error;
+    if (*str)
+        goto error;
+
+    free(rep->client);
+    free(rep->server);
+    rep->client = client;
+    rep->server = server;
+    rep->msghash = msghash;
+    return 0;
+
+error:
+    if (msghash)
+        free(msghash);
+    if (client)
+        free(client);
+    if (server)
+        free(server);
+    return retval;
+}
+
+static krb5_error_code
 krb5_rc_io_fetch(krb5_context context, struct dfl_data *t,
                  krb5_donot_replay *rep, int maxlen)
 {
@@ -345,7 +465,7 @@
     unsigned int len;
     krb5_error_code retval;
 
-    rep->client = rep->server = 0;
+    rep->client = rep->server = rep->msghash = NULL;
 
     retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len2,
                              sizeof(len2));
@@ -395,6 +515,10 @@
     if (retval)
         goto errout;
 
+    retval = check_hash_extension(rep);
+    if (retval)
+        goto errout;
+
     return 0;
 
 errout:
@@ -402,6 +526,8 @@
         krb5_xfree(rep->client);
     if (rep->server)
         krb5_xfree(rep->server);
+    if (rep->msghash)
+        krb5_xfree(rep->msghash);
     rep->client = rep->server = 0;
     return retval;
 }
@@ -443,8 +569,7 @@
         retval = KRB5_RC_MALLOC;
         goto io_fail;
     }
-    rep->client = NULL;
-    rep->server = NULL;
+    rep->client = rep->server = rep->msghash = NULL;
 
     if (krb5_timeofday(context, &now))
         now = 0;
@@ -463,21 +588,22 @@
         else if (retval != 0)
             goto io_fail;
 
-
         if (alive(now, rep, t->lifespan) != CMP_EXPIRED) {
-            if (rc_store(context, id, rep, now) == CMP_MALLOC) {
+            if (rc_store(context, id, rep, now, TRUE) == CMP_MALLOC) {
                 retval = KRB5_RC_MALLOC; goto io_fail;
             }
         } else {
             expired_entries++;
         }
+
         /*
          *  free fields allocated by rc_io_fetch
          */
-        FREE(rep->server);
-        FREE(rep->client);
-        rep->server = 0;
-        rep->client = 0;
+        free(rep->server);
+        free(rep->client);
+        if (rep->msghash)
+            free(rep->msghash);
+        rep->client = rep->server = rep->msghash = NULL;
     }
     retval = 0;
     krb5_rc_io_unmark(context, &t->d);
@@ -529,27 +655,65 @@
 krb5_rc_io_store(krb5_context context, struct dfl_data *t,
                  krb5_donot_replay *rep)
 {
-    unsigned int clientlen, serverlen, len;
-    char *buf, *ptr;
+    size_t clientlen, serverlen;
+    unsigned int len;
     krb5_error_code ret;
+    struct k5buf buf;
+    char *ptr;
 
-    clientlen = strlen(rep->client) + 1;
-    serverlen = strlen(rep->server) + 1;
-    len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
-        sizeof(rep->cusec) + sizeof(rep->ctime);
-    buf = malloc(len);
-    if (buf == 0)
+    clientlen = strlen(rep->client);
+    serverlen = strlen(rep->server);
+
+    if (rep->msghash) {
+        /*
+         * Write a hash extension record, to be followed by a record
+         * in regular format (without the message hash) for the
+         * benefit of old implementations.
+         */
+        struct k5buf extbuf;
+        char *extstr;
+
+        /* Format the extension value so we know its length. */
+        krb5int_buf_init_dynamic(&extbuf);
+        krb5int_buf_add_fmt(&extbuf, "HASH:%s %lu:%s %lu:%s", rep->msghash,
+                            (unsigned long) clientlen, rep->client,
+                            (unsigned long) serverlen, rep->server);
+        extstr = krb5int_buf_data(&extbuf);
+        if (!extstr)
+            return KRB5_RC_MALLOC;
+
+        /*
+         * Put the extension value into the server field of a
+         * regular-format record, with an empty client field.
+         */
+        krb5int_buf_init_dynamic(&buf);
+        len = 1;
+        krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
+        krb5int_buf_add_len(&buf, "", 1);
+        len = strlen(extstr) + 1;
+        krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
+        krb5int_buf_add_len(&buf, extstr, len);
+        krb5int_buf_add_len(&buf, (char *) &rep->cusec, sizeof(rep->cusec));
+        krb5int_buf_add_len(&buf, (char *) &rep->ctime, sizeof(rep->ctime));
+        free(extstr);
+    } else  /* No extension record needed. */
+        krb5int_buf_init_dynamic(&buf);
+
+    len = clientlen + 1;
+    krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
+    krb5int_buf_add_len(&buf, rep->client, len);
+    len = serverlen + 1;
+    krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
+    krb5int_buf_add_len(&buf, rep->server, len);
+    krb5int_buf_add_len(&buf, (char *) &rep->cusec, sizeof(rep->cusec));
+    krb5int_buf_add_len(&buf, (char *) &rep->ctime, sizeof(rep->ctime));
+
+    ptr = krb5int_buf_data(&buf);
+    if (ptr == NULL)
         return KRB5_RC_MALLOC;
-    ptr = buf;
-    memcpy(ptr, &clientlen, sizeof(clientlen)); ptr += sizeof(clientlen);
-    memcpy(ptr, rep->client, clientlen); ptr += clientlen;
-    memcpy(ptr, &serverlen, sizeof(serverlen)); ptr += sizeof(serverlen);
-    memcpy(ptr, rep->server, serverlen); ptr += serverlen;
-    memcpy(ptr, &rep->cusec, sizeof(rep->cusec)); ptr += sizeof(rep->cusec);
-    memcpy(ptr, &rep->ctime, sizeof(rep->ctime)); ptr += sizeof(rep->ctime);
 
-    ret = krb5_rc_io_write(context, &t->d, buf, len);
-    free(buf);
+    ret = krb5_rc_io_write(context, &t->d, ptr, krb5int_buf_len(&buf));
+    krb5int_free_buf(&buf);
     return ret;
 }
 
@@ -570,7 +734,7 @@
     if (ret)
         return ret;
 
-    switch(rc_store(context, id, rep, now)) {
+    switch(rc_store(context, id, rep, now, FALSE)) {
     case CMP_MALLOC:
         k5_mutex_unlock(&id->lock);
         return KRB5_RC_MALLOC;
@@ -626,9 +790,11 @@
     for (q = &t->a; *q; q = qt) {
         qt = &(*q)->na;
         if (alive(now, &(*q)->rep, t->lifespan) == CMP_EXPIRED) {
-            FREE((*q)->rep.client);
-            FREE((*q)->rep.server);
-            FREE(*q);
+            free((*q)->rep.client);
+            free((*q)->rep.server);
+            if ((*q)->rep.msghash)
+                free((*q)->rep.msghash);
+            free(*q);
             *q = *qt; /* why doesn't this feel right? */
         }
     }

Copied: branches/mkey_migrate/src/lib/krb5/rcache/t_replay.c (from rev 21767, trunk/src/lib/krb5/rcache/t_replay.c)

Modified: branches/mkey_migrate/src/lib/rpc/unit-test/Makefile.in
===================================================================
--- branches/mkey_migrate/src/lib/rpc/unit-test/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/rpc/unit-test/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -49,7 +49,7 @@
 PASS=@PASS@
 unit-test-body:
 	$(RM) krb5cc_rpc_test_*
-	$(ENV_SETUP) $(START_SERVERS)
+	$(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
 	RPC_TEST_SRVTAB=/tmp/rpc_test_v5srvtab.$$$$ ; export RPC_TEST_SRVTAB ; \
 	trap "echo Failed, cleaning up... ; rm -f $$RPC_TEST_SRVTAB ; $(ENV_SETUP) $(STOP_SERVERS) ; trap '' 0 ; exit 1" 0 1 2 3 14 15 ; \
 	if $(ENV_SETUP) \

Modified: branches/mkey_migrate/src/lib/rpc/xdr.c
===================================================================
--- branches/mkey_migrate/src/lib/rpc/xdr.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/lib/rpc/xdr.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -54,6 +54,10 @@
 #define XDR_TRUE	((long) 1)
 #define LASTUNSIGNED	((u_int) 0-1)
 
+#ifdef USE_VALGRIND
+#include <valgrind/memcheck.h>
+#endif
+
 /*
  * for unit alignment
  */
@@ -93,6 +97,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*ip);
+#endif
 		if (*ip > 0x7fffffffL || *ip < -0x7fffffffL - 1L)
 			return (FALSE);
 
@@ -126,6 +133,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*up);
+#endif
 		if (*up > 0xffffffffUL)
 			return (FALSE);
 
@@ -158,6 +168,9 @@
 
 	switch (xdrs->x_op) {
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*lp);
+#endif
 		if (*lp > 0x7fffffffL || *lp < -0x7fffffffL - 1L)
 			return (FALSE);
 
@@ -181,6 +194,9 @@
 
 	switch (xdrs->x_op) {
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*ulp);
+#endif
 		if (*ulp > 0xffffffffUL)
 			return (FALSE);
 
@@ -206,6 +222,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*sp);
+#endif
 		l = (long) *sp;
 		return (XDR_PUTLONG(xdrs, &l));
 
@@ -236,6 +255,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*usp);
+#endif
 		l = (u_long) *usp;
 		return (XDR_PUTLONG(xdrs, (long *) &l));
 
@@ -261,6 +283,15 @@
 {
 	int i;
 
+#ifdef USE_VALGRIND
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		VALGRIND_CHECK_DEFINED(*cp);
+		break;
+	default:
+		break;
+	}
+#endif
 	i = (*cp);
 	if (!xdr_int(xdrs, &i)) {
 		return (FALSE);
@@ -277,6 +308,15 @@
 {
 	u_int u;
 
+#ifdef USE_VALGRIND
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		VALGRIND_CHECK_DEFINED(*cp);
+		break;
+	default:
+		break;
+	}
+#endif
 	u = (*cp);
 	if (!xdr_u_int(xdrs, &u)) {
 		return (FALSE);
@@ -296,6 +336,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*bp);
+#endif
 		lb = *bp ? XDR_TRUE : XDR_FALSE;
 		return (XDR_PUTLONG(xdrs, &lb));
 
@@ -324,6 +367,15 @@
 	/*
 	 * enums are treated as ints
 	 */
+#ifdef USE_VALGRIND
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		VALGRIND_CHECK_DEFINED(*ep);
+		break;
+	default:
+		break;
+	}
+#endif
 	if (sizeof (enum sizecheck) == sizeof (long)) {
 		return (xdr_long(xdrs, (long *)ep));
 	} else if (sizeof (enum sizecheck) == sizeof (int)) {
@@ -373,6 +425,9 @@
 	}
 
 	if (xdrs->x_op == XDR_ENCODE) {
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_READABLE((volatile void *)cp, cnt);
+#endif
 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
 			return (FALSE);
 		}
@@ -463,6 +518,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*ip);
+#endif
 		l = *ip;
 		return (xdr_long(xdrs, &l));    
 
@@ -487,6 +545,9 @@
 	switch (xdrs->x_op) {
 
 	case XDR_ENCODE:
+#ifdef USE_VALGRIND
+		VALGRIND_CHECK_DEFINED(*up);
+#endif
 		ul = *up;
 		return (xdr_u_long(xdrs, &ul));    
 

Modified: branches/mkey_migrate/src/tests/asn.1/Makefile.in
===================================================================
--- branches/mkey_migrate/src/tests/asn.1/Makefile.in	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/tests/asn.1/Makefile.in	2009-01-21 19:16:22 UTC (rev 21769)
@@ -8,7 +8,7 @@
 
 RUN_SETUP = @KRB5_RUN_ENV@
 
-SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_encode_test.c \
+SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \
 	$(srcdir)/ktest.c $(srcdir)/ktest_equal.c $(srcdir)/utility.c \
 	$(srcdir)/trval.c $(srcdir)/t_trval.c
 

Modified: branches/mkey_migrate/src/tests/asn.1/deps
===================================================================
--- branches/mkey_migrate/src/tests/asn.1/deps	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/tests/asn.1/deps	2009-01-21 19:16:22 UTC (rev 21769)
@@ -13,6 +13,18 @@
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h \
   $(SRCTOP)/lib/krb5/asn.1/krbasn1.h debug.h krb5_encode_test.c \
   ktest.h utility.h
+$(OUTPRE)krb5_decode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \
+  $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
+  $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
+  $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
+  $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/kdb.h \
+  $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+  $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h \
+  $(SRCTOP)/lib/krb5/asn.1/krbasn1.h debug.h krb5_decode_test.c \
+  ktest.h ktest_equal.h utility.h
 $(OUTPRE)ktest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \

Modified: branches/mkey_migrate/src/tests/threads/t_rcache.c
===================================================================
--- branches/mkey_migrate/src/tests/threads/t_rcache.c	2009-01-21 18:23:58 UTC (rev 21768)
+++ branches/mkey_migrate/src/tests/threads/t_rcache.c	2009-01-21 19:16:22 UTC (rev 21769)
@@ -62,6 +62,7 @@
 	     buf);
     r.server = buf;
     r.client = (t->my_cusec & 7) + "abcdefgh at ATHENA.MIT.EDU";
+    r.msghash = NULL;
     if (t->now != t->my_ctime) {
 	if (t->my_ctime != 0) {
 	    snprintf(buf2, sizeof(buf2), "%3d: %ld %5d\n", t->idx,




More information about the cvs-krb5 mailing list