]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Merge with current head of trunk:
authorWill Fiveash <will.fiveash@oracle.com>
Wed, 21 Jan 2009 19:16:22 +0000 (19:16 +0000)
committerWill Fiveash <will.fiveash@oracle.com>
Wed, 21 Jan 2009 19:16:22 +0000 (19:16 +0000)
svn merge -r21722:HEAD svn+ssh://wfiveash@svn.mit.edu/krb5/trunk

Everything compiles.

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mkey_migrate@21769 dc483132-0cff-0310-8789-dd5450dbe970

64 files changed:
src/include/k5-int.h
src/kadmin/passwd/unit-test/Makefile.in
src/kadmin/passwd/unit-test/config/unix.exp
src/kadmin/server/network.c
src/kdc/do_as_req.c
src/kdc/do_tgs_req.c
src/kdc/kdc_preauth.c
src/kdc/kdc_util.c
src/kdc/kdc_util.h
src/kdc/network.c
src/lib/crypto/cksumtypes.c
src/lib/crypto/cksumtypes.h
src/lib/crypto/etypes.c
src/lib/crypto/etypes.h
src/lib/crypto/string_to_cksumtype.c
src/lib/crypto/string_to_enctype.c
src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/krb5/k5sealv3.c
src/lib/gssapi/krb5/k5sealv3iov.c
src/lib/gssapi/krb5/k5unseal.c
src/lib/gssapi/krb5/k5unsealiov.c
src/lib/gssapi/krb5/util_crypt.c
src/lib/gssapi/libgssapi_krb5.exports
src/lib/gssapi/mechglue/Makefile.in
src/lib/gssapi/mechglue/deps
src/lib/gssapi/mechglue/g_export_name_object.c [deleted file]
src/lib/gssapi/mechglue/g_imp_name_object.c [deleted file]
src/lib/gssapi/mechglue/g_initialize.c
src/lib/gssapi/mechglue/mglueP.h
src/lib/gssapi/spnego/spnego_mech.c
src/lib/kadm5/clnt/client_init.c
src/lib/kadm5/srv/svr_principal.c
src/lib/kadm5/unit-test/Makefile.in
src/lib/kadm5/unit-test/config/unix.exp
src/lib/krb5/krb/auth_con.c
src/lib/krb5/krb/mk_cred.c
src/lib/krb5/krb/mk_priv.c
src/lib/krb5/krb/mk_req_ext.c
src/lib/krb5/krb/mk_safe.c
src/lib/krb5/krb/pac.c
src/lib/krb5/krb/rd_cred.c
src/lib/krb5/krb/rd_priv.c
src/lib/krb5/krb/rd_rep.c
src/lib/krb5/krb/rd_req_dec.c
src/lib/krb5/krb/rd_safe.c
src/lib/krb5/krb/sendauth.c
src/lib/krb5/libkrb5.exports
src/lib/krb5/os/accessor.c
src/lib/krb5/os/deps
src/lib/krb5/os/hst_realm.c
src/lib/krb5/os/net_write.c
src/lib/krb5/os/os-proto.h
src/lib/krb5/os/write_msg.c
src/lib/krb5/rcache/Makefile.in
src/lib/krb5/rcache/deps
src/lib/krb5/rcache/rc_conv.c
src/lib/krb5/rcache/rc_dfl.c
src/lib/krb5/rcache/t_replay.c [new file with mode: 0644]
src/lib/rpc/unit-test/Makefile.in
src/lib/rpc/xdr.c
src/tests/asn.1/Makefile.in
src/tests/asn.1/deps
src/tests/threads/t_rcache.c

index 181ead4f1a95ec1a749faac2b7e9941e1b373218..0b9eae8e58678cc2bf597ed7d5fb66e75abea46e 100644 (file)
@@ -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 @@ struct krb5_aead_provider {
                                    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 @@ void krb5int_free_srv_dns_data(struct srv_dns_entry *);
 /* 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 @@ typedef struct _krb5int_access {
                                   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 @@ typedef struct _krb5_donot_replay {
     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_error_code krb5_auth_to_rep
        (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_error_code krb5_auth_con_getpermetypes
            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 @@ krb5int_server_decrypt_ticket_keyblock
 
 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);
 
index 969ee8207ebd754a12760d830c50a796d1510767..37dfaca33facb7eafd562a3f487c7fd6a08be7df 100644 (file)
@@ -16,10 +16,10 @@ unit-test-body::
        $(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)
index bd8382e19e222289b667a112460e8f033cd8dc3b..479d77243755b8736ed0520e7cf3e14b125a0751 100644 (file)
@@ -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 } {
index d0f8afab896704b89668d8b0ed3663b54585c3ea..df3f01cf063b37326a3e7c9561f5c41602db9f4a 100644 (file)
@@ -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 @@ static const char *paddr (struct sockaddr *sa)
 
 /* 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.  */
@@ -331,10 +334,6 @@ static krb5_error_code add_rpc_service(int port, u_long prognum, u_long versnum,
     return 0;
 }
 
-\f
-#define USE_AF AF_INET
-#define USE_TYPE SOCK_DGRAM
-
 \f
 #define USE_AF AF_INET
 #define USE_TYPE SOCK_DGRAM
@@ -351,7 +350,7 @@ struct socksetup {
 };
 
 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 @@ recv_from_to(int s, void *buf, size_t len, int flags,
             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 @@ recv_from_to(int s, void *buf, size_t len, int flags,
     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 @@ static void process_packet(void *handle,
     }
 #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;
index d0279a0d61854a41a9b1edf230890b32910c5526..0756d4c94441d7df46536e7fcb6aa306ab450bd7 100644 (file)
@@ -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 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     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 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     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 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
 #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 @@ errout:
     /* 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 @@ egress:
        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;
     }
index 3812698808d5bccdc79d55f16e5b6f79bcf5d1d1..9c96734e6abff7847e1c2f7d796dd765b958056d 100644 (file)
@@ -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 @@ tgt_again:
         */
        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 @@ cleanup:
     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;
index d1acf01e1d913e00719f9deb8a438fb6afd346ae..00b8531d86feb7954a39e8fa8c8c8ed58b5a7a87 100644 (file)
@@ -1161,6 +1161,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
      */
     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 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
     /* 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 @@ verify_sam_response(krb5_context context, krb5_db_entry *client,
        /* 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);
index 0d6b96e5071d3ad08529d0b53c58836a42836e65..a9a89636e2b7be349791781a62740073d6a329bd 100644 (file)
@@ -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 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
        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 @@ cleanup:
  */
 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 @@ kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
        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 @@ sign_db_authdata (krb5_context context,
     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 @@ check_allowed_to_delegate_to(krb5_context context,
 
     /* 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;
@@ -2103,84 +2122,6 @@ kdc_check_transited_list(krb5_context context,
     return code;
 }
 
-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,
@@ -2212,10 +2153,12 @@ validate_transit_path(krb5_context context,
 
 /* "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 @@ log_as_req(const krb5_fulladdr *from,
     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 @@ log_tgs_req(const krb5_fulladdr *from,
     /* 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 @@ log_tgs_req(const krb5_fulladdr *from,
                         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 @@ log_tgs_req(const krb5_fulladdr *from,
 
     /* OpenSolaris: audit_krb5kdc_tgs_req(...)  or
        audit_krb5kdc_tgs_req_2ndtktmm(...) */
+    /* ... krb5_db_invoke ... */
 }
 
 void
index 0d8e36bfd2dba537d6173259762745439dba495e..b70f98a6e265a129fb15a6096491679453988176 100644 (file)
@@ -69,6 +69,7 @@ krb5_error_code kdc_process_tgs_req
                   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 @@ validate_transit_path(krb5_context context,
 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 @@ 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);
 void log_tgs_alt_tgt(krb5_principal p);
 
index 98f074cce72deb1ff5a0584f0e6f0e164474c4bf..fffaa1e788e10594a768b11917845c6cf1914bdb 100644 (file)
@@ -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,26 +175,18 @@ static const char *paddr (struct sockaddr *sa)
 
 /* 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;
@@ -316,7 +308,7 @@ struct socksetup {
 };
 
 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 @@ setup_tcp_listener_ports(struct socksetup *data)
 
        /* 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 @@ setup_tcp_listener_ports(struct socksetup *data)
        }
 #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 @@ recv_from_to(int s, void *buf, size_t len, int flags,
             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 @@ recv_from_to(int s, void *buf, size_t len, int flags,
     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 @@ static void accept_tcp_connection(struct connection *conn, const char *prog,
     sockdata.retval = 0;
 
     newconn = add_tcp_data_fd(&sockdata, s);
-    if (newconn == 0)
+    if (newconn == NULL)
        return;
 
     if (getnameinfo((struct sockaddr *)&addr_s, addrlen,
index fca48e29a5fd6763c4a6606725b6cf432f93e16b..037e53f495c319e061be081d93c8c20cb7ad9049 100644 (file)
 
 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)", 
-      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*/
+      "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" },
+      "Microsoft HMAC MD5 (RC4 key)", 
       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 }
 };
index ef23169fab1f3e32df9622b9edf15b65e86dcb99..71409d4272a415be15f89fd11f1847faa7cb4194 100644 (file)
 
 #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;
index de11787d142f83ccc8e30a1a0dc2e6f3ca1f6d9a..c300f3b2c1f92da32a9f4ae3639dece7c16ab2e5 100644 (file)
@@ -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 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       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 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       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 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       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 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       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,25 +88,8 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       &krb5int_aead_raw },
 
     { ENCTYPE_DES3_CBC_SHA1,
-      "des3-cbc-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-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",
+      "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,
@@ -126,7 +99,7 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       &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,8 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       0,
       NULL },
     { ENCTYPE_ARCFOUR_HMAC, 
-      "arcfour-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 */
-      "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", { "rc4-hmac", "arcfour-hmac-md5" },
+      "ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5,
       0,
@@ -171,18 +118,9 @@ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       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",
+    { ENCTYPE_ARCFOUR_HMAC_EXP, 
+      "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
+      "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5,
       0,
@@ -193,16 +131,8 @@ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       &krb5int_aead_arcfour },
 
     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
-      "aes128-cts-hmac-sha1-96", "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_AES128_CTS_HMAC_SHA1_96, /* alias */
-      "aes128-cts", "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,
@@ -211,16 +141,8 @@ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       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",
-      &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 },
-    { ENCTYPE_AES256_CTS_HMAC_SHA1_96, /* alias */
-      "aes256-cts", "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,
index ca94e56ffa72c5d25bd1aacc3a80dd3830ef6d9d..af2718d826188ae3329c3fa8bff8737272abf3c8 100644 (file)
 
 #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;
index a7968514571e3e2788bdf2b7f6339e5b1175d093..5a3c70d731f3151aa577da76701e64c5fbcbfd4b 100644 (file)
 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);
index 9d3245bf012419ad3b70335a57f5033660509bf2..cda66342069458e8aaf3b1fa62582a756b9b2ab9 100644 (file)
 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;
+           }
        }
     }
 
index 2e2433a2a000d6203236f8d908d40d3042b1be55..63ce92c1bbc6712179c7a97955d96bc22e44863c 100644 (file)
@@ -395,6 +395,7 @@ kg_accept_krb5(minor_status, context_handle,
     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 @@ kg_accept_krb5(minor_status, context_handle,
         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;
index 16ab581a9b2558618d9c6d8c0cff8b753ab2a13f..a7f4f9e23d2e8f1e9abf75a5a9d7b68bb81fcfff 100644 (file)
@@ -386,11 +386,13 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
 /*
  * 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 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status,
 
     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 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status,
                                                               data_set);
        }
     }
+#endif
 
     *minor_status = EINVAL;
 
@@ -443,11 +447,13 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status,
 /*
  * 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 @@ krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
            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 @@ krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
                                                                  value);
        }
     }
+#endif
 
     *minor_status = EINVAL;
 
@@ -661,8 +669,6 @@ static struct gss_config krb5_mechanism = {
     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,
index 71e832e15bd5e1b6568a8c474f8df24962a56e3a..b12284fb19a27e507a75f38b0ba23a3413786ad2 100644 (file)
@@ -320,8 +320,8 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
     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;
index 41e6132cd915643e57a233836ba80ec80f3d222d..e39665febe5c21f75d2bf095ede362bd6a99e28e 100644 (file)
@@ -297,8 +297,8 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
     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;
index 4b70fd02ad6bbe95fdd7c4275503c6c3a33e5570..a94ac9ef053782cc45aeaba7388feb4b27c46943 100644 (file)
@@ -494,6 +494,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
     unsigned int bodysize;
     int err;
     int toktype2;
+    int vfyflags = 0;
     OM_uint32 ret;
 
     /* validate the context handle */
@@ -515,26 +516,49 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
 
     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)
-        ret = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
-                           message_buffer, conf_state, qop_state,
-                           toktype);
-    else
+    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);
+       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;
 }
index c72e2db39c38eee66d1b38682bf5c46f8b1becab..a9d4c9effb68d4ec58a4c68e872e45c7d3aa032b 100644 (file)
@@ -172,7 +172,7 @@ kg_unseal_v1_iov(krb5_context context,
                                              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 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
                    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 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
     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 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
            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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
                     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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
     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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
     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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
        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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
        /* 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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
     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 @@ kg_unseal_iov(OM_uint32 *minor_status,
 {
     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 @@ kg_unseal_iov(OM_uint32 *minor_status,
        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;
index d718ae0b18774f3c58490926371fabd88faba425..e2f306e979aed198afc9a25ef661b0f2d4f3bd4f 100644 (file)
 
 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,23 +100,17 @@ kg_setup_keys(krb5_context context,
     *cksumtype = 0;
     ctx->proto = 0;
 
-    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;
+    if (ctx->enc == NULL) {
+       ctx->signalg = -1;
+       ctx->sealalg = -1;
     }
-    code = krb5_copy_keyblock(context, subkey, &ctx->enc);
+        
+    code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION);
     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);
+    code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype,
+                                                   cksumtype);
     if (code != 0)
        return code;
 
@@ -96,6 +118,10 @@ kg_setup_keys(krb5_context context,
     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 @@ kg_setup_keys(krb5_context context,
            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 @@ kg_setup_keys(krb5_context context,
        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;
index 524533843f18b9d533c871bacee793e68b9c9375..69f390e4514a944628eefd76a48f49c6a921d50d 100644 (file)
@@ -23,11 +23,9 @@ gss_display_name
 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
index 13a750b2307681dc255c8df9ef328d36464b4170..927b3755ca96b68bf19df2ab0cb8b68cbbfa105a 100644 (file)
@@ -25,10 +25,8 @@ SRCS = \
        $(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 @@ OBJS = \
        $(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 @@ STLIBOBJS = \
        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 \
index f67f754d01147b0a89d85a1dfc9d60868b46a6cb..c54fae9f2780478882bd32fe26672568d0ec081f 100644 (file)
@@ -105,14 +105,6 @@ g_export_name.so g_export_name.po $(OUTPRE)g_export_name.$(OBJEXT): \
   $(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 @@ g_imp_name.so g_imp_name.po $(OUTPRE)g_imp_name.$(OBJEXT): \
   $(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) \
diff --git a/src/lib/gssapi/mechglue/g_export_name_object.c b/src/lib/gssapi/mechglue/g_export_name_object.c
deleted file mode 100644 (file)
index 4005070..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1996,1997, by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-/* #pragma ident       "@(#)g_export_name.c    1.11    00/07/17 SMI" */
-
-/*
- * glue routine gss_export_name_object_object_object_object
- *
- * Will either call the mechanism defined gss_export_name, or if one is
- * not defined will call a generic_gss_export_name routine.
- */
-
-#include <mglueP.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <errno.h>
-
-OM_uint32 KRB5_CALLCONV
-gss_export_name_object(minor_status,
-                      input_name,
-                      desired_name_type,
-                      output_name)
-OM_uint32 *            minor_status;
-const gss_name_t       input_name;
-gss_OID                        desired_name_type;
-void **                        output_name;
-{
-    gss_union_name_t           union_name;
-    gss_mechanism              mech;
-    OM_uint32                  major_status;
-
-    if (minor_status != NULL)
-       *minor_status = 0;
-
-    if (output_name != NULL)
-       *output_name = NULL;
-
-    if (minor_status == NULL)
-       return GSS_S_CALL_INACCESSIBLE_WRITE;
-
-    if (input_name == NULL)
-       return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
-
-    if (desired_name_type == GSS_C_NO_OID)
-       return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAMETYPE;
-
-    if (output_name == NULL)
-       return GSS_S_CALL_INACCESSIBLE_WRITE;
-
-    union_name = (gss_union_name_t)input_name;
-
-    if (union_name->mech_type == GSS_C_NO_OID)
-       return GSS_S_NAME_NOT_MN;
-
-    mech = gssint_get_mechanism(union_name->mech_type);
-    if (mech == NULL)
-       return GSS_S_BAD_MECH;
-
-    if (mech->gss_export_name_object == NULL)
-       return GSS_S_UNAVAILABLE;
-
-    major_status = mech->gss_export_name_object(minor_status,
-                                               input_name,
-                                               desired_name_type,
-                                               output_name);
-    if (major_status != GSS_S_COMPLETE)
-       map_error(minor_status, mech);
-
-    return major_status;
-}
diff --git a/src/lib/gssapi/mechglue/g_imp_name_object.c b/src/lib/gssapi/mechglue/g_imp_name_object.c
deleted file mode 100644 (file)
index 83f327b..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* #pragma ident       "@(#)g_imp_name.c       1.26    04/02/23 SMI" */
-
-/*
- * Copyright 1996 by Sun Microsystems, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Sun Microsystems not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. Sun Microsystems makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- *  glue routine gss_import_name_object
- *
- */
-
-#include "mglueP.h"
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <errno.h>
-
-static OM_uint32
-val_imp_name_object_args(
-    OM_uint32 *minor_status,
-    void *input_name,
-    gss_OID input_name_type,
-    gss_name_t *output_name)
-{
-    if (minor_status == NULL)
-       return GSS_S_CALL_INACCESSIBLE_WRITE;
-
-    *minor_status = 0;
-
-    if (output_name == NULL)
-       return GSS_S_CALL_INACCESSIBLE_WRITE;
-
-    if (input_name_type == GSS_C_NO_OID)
-       return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAMETYPE;
-
-    if (input_name == NULL)
-       return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
-
-    return GSS_S_COMPLETE;    
-}
-
-OM_uint32 KRB5_CALLCONV
-gss_import_name_object(minor_status,
-                      input_name,
-                      input_name_type,
-                      output_name)
-OM_uint32 *            minor_status;
-void *                 input_name;
-gss_OID                        input_name_type;
-gss_name_t *           output_name;
-{
-    gss_union_name_t       union_name = NULL;
-    gss_mechanism          mech = NULL;
-    gss_name_t             internal_name = GSS_C_NO_NAME;
-    OM_uint32              tmp, major_status = GSS_S_FAILURE;
-    gss_OID_set                    mechlist = GSS_C_NO_OID_SET;
-    size_t                 i;
-
-    major_status = val_imp_name_object_args(minor_status,
-                                           input_name,
-                                           input_name_type,
-                                           output_name);
-    if (major_status != GSS_S_COMPLETE)
-       return major_status;
-
-    major_status = gss_indicate_mechs(minor_status, &mechlist);
-    if (major_status != GSS_S_COMPLETE)
-       return major_status;
-
-    major_status = GSS_S_BAD_NAMETYPE;
-
-    for (i = 0; i < mechlist->count; i++) {
-       mech = gssint_get_mechanism(&mechlist->elements[i]);
-       if (mech == NULL || mech->gss_import_name_object == NULL)
-           continue;
-
-       major_status = mech->gss_import_name_object(minor_status,
-                                                   input_name,
-                                                   input_name_type,
-                                                   &internal_name);
-       if (major_status != GSS_S_BAD_NAMETYPE)
-           break;
-    }
-
-    if (major_status == GSS_S_COMPLETE) {
-       assert(internal_name != GSS_C_NO_NAME);
-
-       major_status = gssint_convert_name_to_union_name(minor_status,
-                                                        mech,
-                                                        internal_name,
-                                                        &union_name);
-       if (major_status != GSS_S_COMPLETE) {
-           if (mech->gss_release_name != NULL)
-               mech->gss_release_name(&tmp, &internal_name);
-       } else
-           *output_name = (gss_name_t)union_name;
-   } else
-       map_error(minor_status, mech);
-
-    generic_gss_release_oid_set(&tmp, &mechlist);
-
-    return major_status;
-}
-
index e762341c5d7b1ab23f39d061df970097bcfd7f36..a6f0bbc8dda3eb5bf6f242d39f8b80e3450a7b6c 100644 (file)
@@ -750,8 +750,6 @@ build_dynamicMech(void *dl, const gss_OID mech_type)
        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);
index 52195f2931aebe19707879cc75b14825174c8cc1..001636146ea57ddffe71e376fabc9e4b1106c018 100644 (file)
@@ -370,21 +370,6 @@ typedef struct gss_config {
                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 */
 
index 44aea26436dc680420a342c83c98b2b7e236bdb9..5321de0befb46197986fec1e6be49d31efbb4a60 100644 (file)
@@ -247,8 +247,6 @@ static struct gss_config spnego_mechanism =
        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 */
index d5fe5b0f129491a3c3588a7cbeb84fcb6af20c62..82bec3c4ef537c8f45b871efc6157524a31e3a42 100644 (file)
@@ -541,8 +541,12 @@ kadm5_gic_iter(kadm5_server_handle_t handle,
             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,
index 9833a2bb49f4709b758cca1ea38a43af9166ac8a..6528133db4fa89b505764d6cd123c725396a5f34 100644 (file)
@@ -38,27 +38,26 @@ static int decrypt_key_data(krb5_context context, krb5_keyblock *mkey,
                            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 @@ kadm5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_pr
             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 @@ kadm5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_pr
     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 @@ kadm5_ret_t krb5_copy_key_data_contents(context, from, to)
    krb5_key_data *from, *to;
 {
      int i, idx;
-     
+
      *to = *from;
 
      idx = (from->key_data_ver == 1 ? 1 : 2);
@@ -170,7 +169,7 @@ static void cleanup_key_data(context, count, data)
    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 @@ kadm5_create_principal_3(void *server_handle,
     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 @@ kadm5_create_principal_3(void *server_handle,
     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 @@ kadm5_create_principal_3(void *server_handle,
     }
     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 @@ kadm5_create_principal_3(void *server_handle,
     return KADM5_OK;
 }
 
-       
+
 kadm5_ret_t
 kadm5_delete_principal(void *server_handle, krb5_principal principal)
 {
@@ -622,7 +621,7 @@ kadm5_modify_principal(void *server_handle,
                                             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 @@ kadm5_modify_principal(void *server_handle,
         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 @@ done:
     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 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
 
     if ((mask & KADM5_PRINCIPAL) &&
        (ret = krb5_copy_principal(handle->context, kdb.princ,
-                                  &entry->principal))) { 
+                                  &entry->principal))) {
        goto done;
     }
 
@@ -800,12 +799,12 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
     /* 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 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
         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 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
              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 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
                        entry->tl_data = tl2;
                        entry->n_tl_data++;
                   }
-                       
+
                   tl = tl->tl_data_next;
              }
         }
@@ -882,7 +881,7 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
                              ret = ENOMEM;
                              goto done;
                      }
-             } else 
+             } else
                      entry->key_data = NULL;
 
              for (i = 0; i < entry->n_key_data; i++)
@@ -907,7 +906,7 @@ kadm5_get_principal(void *server_handle, krb5_principal principal,
              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 @@ check_pw_reuse(krb5_context context,
                                                   &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 create_history_entry(krb5_context context, krb5_keyblock *mkey, int n_key_da
      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 @@ int create_history_entry(krb5_context context, krb5_keyblock *mkey, int n_key_da
                                           &hist->key_data[i]);
         if (ret)
             return ret;
-        
+
         krb5_free_keyblock_contents(context, &key);
         /* krb5_free_keysalt(context, &salt); */
      }
@@ -1127,7 +1126,7 @@ static kadm5_ret_t add_to_history(krb5_context context,
          }
          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 @@ kadm5_set_use_password_server (void)
 #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 @@ kadm5_set_use_password_server (void)
 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 @@ kadm5_launch_task (krb5_context context,
            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 @@ kadm5_chpass_principal_3(void *server_handle,
         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 @@ kadm5_chpass_principal_3(void *server_handle,
     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 @@ kadm5_chpass_principal_3(void *server_handle,
                             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 @@ kadm5_chpass_principal_3(void *server_handle,
 
             ret = kadm5_launch_task (handle->context, path, argv, password);
         }
-        
+
         if (pstring != NULL)
             free (pstring);
-        
+
         if (ret)
             goto done;
     }
@@ -1498,7 +1497,7 @@ done:
     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 @@ kadm5_randkey_principal_3(void *server_handle,
 
     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 @@ kadm5_randkey_principal_3(void *server_handle,
                                         -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 @@ kadm5_randkey_principal_3(void *server_handle,
             if (ret)
                 goto done;
         }
-    }   
-    
+    }
+
     /* key data changed, let the database provider know */
     kdb.mask = KADM5_KEY_DATA /* | KADM5_RANDKEY_USED */;
 
@@ -1694,7 +1693,7 @@ kadm5_setv4key_principal(void *server_handle,
 
     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 @@ kadm5_setv4key_principal(void *server_handle,
 
     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 @@ kadm5_setv4key_principal(void *server_handle,
 
     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 @@ kadm5_setv4key_principal(void *server_handle,
                goto done;
        }
 #endif
-       
+
        if (pol.pw_max_life)
           kdb.pw_expiration = now + pol.pw_max_life;
        else
@@ -1897,7 +1896,7 @@ kadm5_setkey_principal_3(void *server_handle,
 
     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 @@ kadm5_setkey_principal_3(void *server_handle,
        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 @@ kadm5_setkey_principal_3(void *server_handle,
 
     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 @@ kadm5_setkey_principal_3(void *server_handle,
                goto done;
        }
 #endif
-       
+
        if (pol.pw_max_life)
           kdb.pw_expiration = now + pol.pw_max_life;
        else
@@ -2136,7 +2135,7 @@ static int decrypt_key_data(krb5_context context, krb5_keyblock *mkey,
 
      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 @@ kadm5_ret_t kadm5_decrypt_key(void *server_handle,
 
     return KADM5_OK;
 }
-
index 8a3cad51ccab5e0f5a4115a92986f05013c2831a..f7f7fd85fee113d2a7bdf42124cab5a3013128f2 100644 (file)
@@ -87,28 +87,28 @@ unit-test-server: unit-test-server-setup unit-test-server-body \
        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 @@ unit-test-client-body: site.exp test-noauth test-destroy test-handle-client
                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 @@ unit-test-server-body: site.exp test-handle-server lock-test
        $(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
 
index a78515f915bc8e0b8a87cdb407f76e54b9558473..3f366554701ca743c77bafeaedb1e8c96bb9c517 100644 (file)
@@ -14,6 +14,47 @@ if {[info exists exp_version_4]} {
        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 } {
index 7c1858553de238be9f5b1e13fa8f22dbbc7cf491..7af96403f291ddb93e30985e3a97a1949a4f5d9a 100644 (file)
@@ -556,3 +556,13 @@ chk_heimdal_seqnum(krb5_ui_4 exp_seq, krb5_ui_4 in_seq)
     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;
+}
+
index 8611e1409701dc3379c66ffa57d970dc001f7880..a63b07ac69420952c4b6b2961885405682ecf350 100644 (file)
@@ -258,6 +258,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context,
             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))) {
index 08cbee969a05f5d73f030c3bc15bba09dda749c6..2a56bd0971b455fc3f75675131be1e005e4557fc 100644 (file)
@@ -214,6 +214,7 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context,
        }
 
        replay.server = "";             /* XXX */
+       replay.msghash = NULL;
        replay.cusec = replaydata.usec;
        replay.ctime = replaydata.timestamp;
        if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
index 4a9d03551f42582fea62e245003450e2c5d87aad..0d24017ee7bebcb615062e7e038248eedb81608b 100644 (file)
@@ -343,23 +343,15 @@ make_etype_list(krb5_context context,
     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);
index 0517f42750baa43d72462a7afd7c117303e3d112..01abfab96187d89ae45cc27cba4f1ac5d5df4560 100644 (file)
@@ -239,6 +239,7 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context,
        }
 
        replay.server = "";             /* XXX */
+       replay.msghash = NULL;
        replay.cusec = replaydata.usec;
        replay.ctime = replaydata.timestamp;
        if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
index ca7bdce5141899e1fd760bda26c45b51107af6f3..3cfc188c517b6522dc8b128279bc2e03656c8ec1 100644 (file)
@@ -378,7 +378,7 @@ krb5_pac_parse(krb5_context context,
 }
 
 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 @@ k5_pac_validate_client(krb5_context context,
     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);
index 3c76506b2f099dc1d2724dd7663080e271d4da8d..5e159ab8025409eda7056e9957dc604f59fbc301 100644 (file)
@@ -210,6 +210,7 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context,
             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))) {
index 618726efe281700e91f30d2a361f819179417bbd..66b29b0fa3b908457037616d87878b7ea6ffbfae 100644 (file)
@@ -235,6 +235,7 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context,
            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))) {
index 1e6e0e1e82328bf37b3f877a1045e26a3af43bc1..2d495ae8f4855059bc3c4a7b1a0f29e55cbb27ba 100644 (file)
@@ -151,7 +151,7 @@ krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context,
     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;
index bbf7ed6a724ba28e5f9cfd57028a649fc6a07a63..618151100ad3dc707bf0323fa6cf8f42a3f48177 100644 (file)
@@ -349,7 +349,13 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
        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 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
        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) {
index 98d73733c3794afa71fced1bf2f6d567b356bfee..d14d9d4287abb363a28534d2e1d4da742aba1d78 100644 (file)
@@ -241,6 +241,7 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context,
            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))) {
index 5b563430756da1a98d3149760c0b33f00f533a14..35684bebbe355a9fe43b06fd6c27805709474732 100644 (file)
@@ -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
 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,13 +63,11 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
         * 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)))
-               return(retval);
-       outbuf.length = strlen(appl_version) + 1;
-       outbuf.data = appl_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);
        /*
         * Now, read back a byte: 0 means no error, 1 means bad sendauth
@@ -154,15 +157,15 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
 
        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;
 
index 30c198d1cfe8f45c0a3e2a770dcd7aac2f4bb17d..803fac806c921329038d990103c1efb48ae89d73 100644 (file)
@@ -401,6 +401,7 @@ krb5_rc_free_entry
 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_sync
 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
index cdbb5984185252e3f6b487cee1f6b97e804ee7fc..1bf171a6f3451a1201d36cc24512f7ef19adf78d 100644 (file)
@@ -53,6 +53,7 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
 #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),
index d86f8b25bd0acd2af0c7282f16005c73a8c96155..d868ada25cb126385c3bc178b8ea443b30c11b68 100644 (file)
@@ -277,7 +277,7 @@ net_write.so net_write.po $(OUTPRE)net_write.$(OBJEXT): \
   $(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 @@ write_msg.so write_msg.po $(OUTPRE)write_msg.$(OBJEXT): \
   $(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
index 36c0e48608c1ad1df001b3bf577a0558765af1be..fda0dfde2ce4d285a38ace58747f5de313c56205 100644 (file)
@@ -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 @@ krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp)
     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 @@ krb5_get_fallback_host_realm(krb5_context context, krb5_data *hdata, char ***rea
     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
index e4981543aa94ac374df081055afa541e4296927b..35765fb3875406be4bc65ad5e74f0c3f6d6d4810 100644 (file)
@@ -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
  */
 
 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;
 }
index 33acd0c4663e458ae2585db79d9721b2358c0821..bb2e00ec20e6b4c88db241011b9b6b7b1bb7d2cb 100644 (file)
@@ -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_realm (krb5_context);
 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;
 
index d75a32796def19e5edb4128ae6d8bbd8a5052319..e6001e8c67bea792c2777700d7954d1fe19d12b6 100644 (file)
@@ -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
 
 #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);
+
+    while (nbufs) {
+       int nbufs1;
+       sg_buf sg[4];
+       krb5_int32 len[2];
 
-       len = htonl(outbuf->length);
-       if (krb5_net_write(context, fd, (char *)&len, 4) < 0) {
-               return(errno);
+       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);
 }
index d4c13362346182152d605b187b32834200213bb3..abbcc32de67c7e09d916f7d95834ef9cf89790d0 100644 (file)
@@ -2,6 +2,8 @@ thisconfigdir=../../..
 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 @@ SRCS=       \
        $(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@
 
index b2f02ae6cb2bc5b31ba961bc37c387c41b39b79e..e77adf1b5f5f2798869c68fb3e2d5c911ca7c86e 100644 (file)
@@ -81,3 +81,13 @@ rcfns.so rcfns.po $(OUTPRE)rcfns.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(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
index 16ed9e7eb8bf99ad386126b2b9782d7e97d053da..3370f45df0d24827b7bf10d2fa33dba5f3c65945 100644 (file)
@@ -36,3 +36,44 @@ krb5_auth_to_rep(krb5_context context, krb5_tkt_authent *auth, krb5_donot_replay
     }
     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;
+}
index aa0b3a5f98402f9d98e8822d9835d45c5110082e..44013dafc0a6674348bc527c172ca8590fd146df 100644 (file)
@@ -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 @@ cmp(krb5_donot_replay *old, krb5_donot_replay *new1, krb5_deltat t)
     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 @@ struct authlist
 
 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 @@ rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep,
         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 @@ rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep,
 
     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 @@ krb5_rc_dfl_close_no_free(krb5_context context, krb5_rcache id)
     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,15 +352,111 @@ krb5_rc_free_entry(krb5_context context, krb5_donot_replay **rep)
     {
         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 @@ krb5_rc_io_fetch(krb5_context context, struct dfl_data *t,
     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 @@ krb5_rc_io_fetch(krb5_context context, struct dfl_data *t,
     if (retval)
         goto errout;
 
+    retval = check_hash_extension(rep);
+    if (retval)
+        goto errout;
+
     return 0;
 
 errout:
@@ -402,6 +526,8 @@ errout:
         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 @@ krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id)
         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 @@ krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id)
         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 @@ static krb5_error_code
 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);
+    serverlen = strlen(rep->server);
 
-    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)
+    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 @@ krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
     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 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
     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? */
         }
     }
diff --git a/src/lib/krb5/rcache/t_replay.c b/src/lib/krb5/rcache/t_replay.c
new file mode 100644 (file)
index 0000000..427991c
--- /dev/null
@@ -0,0 +1,270 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * test/threads/t_replay.c
+ *
+ * Copyright (C) 2009 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ * t_replay.c: Command-line interfaces to aid testing of replay cache
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "k5-int.h"
+
+static void usage(const char *progname)
+{
+    fprintf(stderr, "%s: Usage:\n", progname);
+    fprintf(stderr, "  %s dump <filename>\n", progname);
+    fprintf(stderr, "  %s store <rc> <cli> <srv> <msg> <tstamp> <usec>"
+            " <now> <now-usec>\n", progname);
+    fprintf(stderr, "  %s expunge <rc> <now> <now-usec>\n", progname);
+    exit(1);
+}
+
+static char *read_counted_string(FILE *fp)
+{
+    unsigned int len;
+    char *str;
+
+    if (fread(&len, sizeof(len), 1, fp) != 1)
+        return NULL;
+    if (len == 0 || len > 10000)
+        return NULL;
+    if ((str = malloc(len)) == NULL)
+        return NULL;
+    if (fread(str, 1, len, fp) != len)
+        return NULL;
+    if (str[len - 1] != 0)
+        return NULL;
+    return str;
+}
+
+static void dump_rcache(const char *filename)
+{
+    FILE *fp;
+    krb5_deltat lifespan;
+    krb5_int16 vno;
+
+    fp = fopen(filename, "r");
+    if (!fp) {
+        fprintf(stderr, "Can't open filename: %s\n", strerror(errno));
+        return;
+    }
+    if (fread(&vno, sizeof(vno), 1, fp) != 1)
+        return;
+    if (fread(&lifespan, sizeof(lifespan), 1, fp) != 1)
+        return;
+    printf("Lifespan: %ld\n", (long) lifespan);
+    while (1) {
+        char *str;
+        krb5_int32 usec;
+        krb5_timestamp timestamp;
+
+        printf("---\n");
+
+        if (!(str = read_counted_string(fp)))
+            return;
+        printf("Client: %s\n", str);
+        free(str);
+
+        if (!(str = read_counted_string(fp)))
+            return;
+        printf("Server: %s\n", str);
+        free(str);
+
+        if (fread(&usec, sizeof(usec), 1, fp) != 1)
+            return;
+        printf("Microseconds: %ld\n", (long) usec);
+
+        if (fread(&timestamp, sizeof(timestamp), 1, fp) != 1)
+            return;
+        printf("Timestamp: %ld\n", (long) timestamp);
+    }
+}
+
+static void store(krb5_context ctx, char *rcspec, char *client, char *server,
+                  char *msg, krb5_timestamp timestamp, krb5_int32 usec,
+                  krb5_timestamp now_timestamp, krb5_int32 now_usec)
+{
+    krb5_rcache rc = NULL;
+    krb5_error_code retval = 0;
+    char *hash = NULL;
+    krb5_donot_replay rep;
+
+    if (now_timestamp > 0)
+        krb5_set_debugging_time(ctx, now_timestamp, now_usec);
+    if ((retval = krb5_rc_resolve_full(ctx, &rc, rcspec)))
+        goto cleanup;
+    if ((retval = krb5_rc_recover_or_initialize(ctx, rc, ctx->clockskew)))
+        goto cleanup;
+    if (msg) {
+        krb5_data d;
+
+        d.data = msg;
+        d.length = strlen(msg);
+        if ((retval = krb5_rc_hash_message(ctx, &d, &hash)))
+            goto cleanup;
+    }
+    rep.client = client;
+    rep.server = server;
+    rep.msghash = hash;
+    rep.cusec = usec;
+    rep.ctime = timestamp;
+    retval = krb5_rc_store(ctx, rc, &rep);
+cleanup:
+    if (retval == KRB5KRB_AP_ERR_REPEAT)
+        printf("Replay\n");
+    else if (!retval)
+        printf("Entry successfully stored\n");
+    else
+        fprintf(stderr, "Failure: %s\n", krb5_get_error_message(ctx, retval));
+    if (rc)
+        krb5_rc_close(ctx, rc);
+    if (hash)
+        free(hash);
+}
+
+static void expunge(krb5_context ctx, char *rcspec,
+                    krb5_timestamp now_timestamp, krb5_int32 now_usec)
+{
+    krb5_rcache rc = NULL;
+    krb5_error_code retval = 0;
+
+    if (now_timestamp > 0)
+        krb5_set_debugging_time(ctx, now_timestamp, now_usec);
+    if ((retval = krb5_rc_resolve_full(ctx, &rc, rcspec)))
+        goto cleanup;
+    if ((retval = krb5_rc_recover_or_initialize(ctx, rc, ctx->clockskew)))
+        goto cleanup;
+    retval = krb5_rc_expunge(ctx, rc);
+cleanup:
+    if (!retval)
+        printf("Cache successfully expunged\n");
+    else
+        fprintf(stderr, "Failure: %s\n", krb5_get_error_message(ctx, retval));
+    if (rc)
+        krb5_rc_close(ctx, rc);
+}
+
+int main(int argc, char **argv)
+{
+    krb5_context ctx;
+    krb5_error_code retval;
+    const char *progname;
+
+    retval = krb5_init_context(&ctx);
+    if (retval) {
+        fprintf(stderr, "krb5_init_context returned error %ld\n",
+                (long) retval);
+        exit(1);
+    }
+    progname = argv[0];
+
+    /* Parse arguments. */
+    argc--; argv++;
+    while (argc) {
+        if (strcmp(*argv, "dump") == 0) {
+            /*
+             * Without going through the rcache interface, dump a
+             * named dfl-format rcache file to stdout.  Takes a full
+             * pathname argument.
+             */
+            const char *filename;
+
+            argc--; argv++;
+            if (!argc) usage(progname);
+            filename = *argv;
+            dump_rcache(filename);
+        } else if (strcmp(*argv, "store") == 0) {
+            /*
+             * Using the rcache interface, store a replay record.
+             * Takes an rcache spec like dfl:host as the first
+             * argument.  If non-empty, the "msg" argument will be
+             * hashed and provided in the replay record.  The
+             * now-timestamp argument can be 0 to use the current
+             * time.
+             */
+            char *rcspec, *client, *server, *msg;
+            krb5_timestamp timestamp, now_timestamp;
+            krb5_int32 usec, now_usec;
+
+            argc--; argv++;
+            if (!argc) usage(progname);
+            rcspec = *argv;
+            argc--; argv++;
+            if (!argc) usage(progname);
+            client = *argv;
+            argc--; argv++;
+            if (!argc) usage(progname);
+            server = *argv;
+            argc--; argv++;
+            if (!argc) usage(progname);
+            msg = (**argv) ? *argv : NULL;
+            argc--; argv++;
+            if (!argc) usage(progname);
+            timestamp = (krb5_timestamp) atol(*argv);
+            argc--; argv++;
+            if (!argc) usage(progname);
+            usec = (krb5_int32) atol(*argv);
+            argc--; argv++;
+            if (!argc) usage(progname);
+            now_timestamp = (krb5_timestamp) atol(*argv);
+            argc--; argv++;
+            if (!argc) usage(progname);
+            now_usec = (krb5_int32) atol(*argv);
+
+            store(ctx, rcspec, client, server, msg, timestamp, usec,
+                  now_timestamp, now_usec);
+        } else if (strcmp(*argv, "expunge") == 0) {
+            /*
+             * Using the rcache interface, expunge a replay cache.
+             * The now-timestamp argument can be 0 to use the current
+             * time.
+             */
+            char *rcspec;
+            krb5_timestamp now_timestamp;
+            krb5_int32 now_usec;
+
+            argc--; argv++;
+            if (!argc) usage(progname);
+            rcspec = *argv;
+            argc--; argv++;
+            if (!argc) usage(progname);
+            now_timestamp = (krb5_timestamp) atol(*argv);
+            argc--; argv++;
+            if (!argc) usage(progname);
+            now_usec = (krb5_int32) atol(*argv);
+            expunge(ctx, rcspec, now_timestamp, now_usec);
+        } else
+            usage(progname);
+        argc--; argv++;
+    }
+
+    krb5_free_context(ctx);
+
+    return 0;
+}
index ee6f66e6038808d0eff03c6444d14a4ed3a9f70a..2b98dbba66bc5a81aa750701909af9469d0e775a 100644 (file)
@@ -49,7 +49,7 @@ unit-test-ok:: unit-test-body
 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) \
index ec0d27717ff6cf71de7ce5b9c1eed03e74bb7830..417786572c46bba86325cf6a317f67ccf29405d5 100644 (file)
@@ -54,6 +54,10 @@ static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
 #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 @@ xdr_int(XDR *xdrs, int *ip)
        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 @@ xdr_u_int(XDR *xdrs, u_int *up)
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
+#ifdef USE_VALGRIND
+               VALGRIND_CHECK_DEFINED(*up);
+#endif
                if (*up > 0xffffffffUL)
                        return (FALSE);
 
@@ -158,6 +168,9 @@ xdr_long(XDR *xdrs, long *lp)
 
        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 @@ xdr_u_long(XDR *xdrs, u_long *ulp)
 
        switch (xdrs->x_op) {
        case XDR_ENCODE:
+#ifdef USE_VALGRIND
+               VALGRIND_CHECK_DEFINED(*ulp);
+#endif
                if (*ulp > 0xffffffffUL)
                        return (FALSE);
 
@@ -206,6 +222,9 @@ xdr_short(register XDR *xdrs, short *sp)
        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 @@ xdr_u_short(register XDR *xdrs, u_short *usp)
        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 @@ xdr_char(XDR *xdrs, char *cp)
 {
        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 @@ xdr_u_char(XDR *xdrs, u_char *cp)
 {
        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 @@ xdr_bool(register XDR *xdrs, bool_t *bp)
        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 @@ xdr_enum(XDR *xdrs, enum_t *ep)
        /*
         * 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 @@ xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
        }
 
        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 @@ xdr_int32(XDR *xdrs, int32_t *ip)
        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 @@ xdr_u_int32(XDR *xdrs, uint32_t *up)
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
+#ifdef USE_VALGRIND
+               VALGRIND_CHECK_DEFINED(*up);
+#endif
                ul = *up;
                return (xdr_u_long(xdrs, &ul));    
 
index 8bfa46e6016a42cd58b3aa5fd1d1f65e7a127566..25f9bdc367ddbb9ac662fea94d9db40985467934 100644 (file)
@@ -8,7 +8,7 @@ LDAP=@LDAP@
 
 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
 
index 13fabb706b596adaed72b8cdb953238f1c6d42a2..4291da6ad83dd0ffcffaed31b794fb9a9ced1811 100644 (file)
@@ -13,6 +13,18 @@ $(OUTPRE)krb5_encode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(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 \
index 06f4d3b194a89f16039b1cfe7a88c14768c8e096..3a654a4b3251fdfff884e288edf4f66765b65913 100644 (file)
@@ -62,6 +62,7 @@ static void try_one (struct tinfo *t)
             buf);
     r.server = buf;
     r.client = (t->my_cusec & 7) + "abcdefgh@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,