* Makefile.in (OBJS, SRCS): Add strnlen.o, strnlen.c
authorTom Yu <tlyu@mit.edu>
Wed, 8 Nov 2000 23:14:56 +0000 (23:14 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 8 Nov 2000 23:14:56 +0000 (23:14 +0000)
* cr_auth_repl.c: Audit.  Fix up copyright.  Use new KRB4_PUT*
macros for encoding so output is always big-endian.  Precompute
string lengths for better length-checking.

* cr_ciph.c: Audit.  Fix up copyright.  Use new KRB4_PUT* macros
for encoding so that output is always big-endian.  Precompute
string lengths for better length-checking.  Zero out the key
schedule after encrypting.

* cr_death_pkt.c: Audit.  Fix up copyright.  Precompute string
lengths for better length-checking.

* cr_err_repl.c: Audit.  Fix up copyright.  Use moving pointer to
do encoding.  Precompute string lengths for better
length-checking.  Use KRB4_PUT* macros so that output is always
big-endian.

* cr_tkt.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
encoding so that output is always big-endian.  Zero out the key
schedule after encrypting.

* decomp_tkt.c: Audit.  Fix up copyright.  Use krb_strnlen() for
actually detecting string length errors.  Use a struct in_addr to
retrieve the IP address and assign it to paddress for return.  Use
KRB4_GET* macros for decoding to avoid byteswapping problems.
Zero out session key and decrypted ticket on error.

* g_ad_tkt.c: Audit.  Fix up copyright.  Break out parsing of
decrypted KDC reply packet into a separate function to simplify
error handling somewhat.  Precompute string lengths for better
length-checking.  Use KRB4_PUT* macros for encoding so that output
is always big-endian.  Use KRB4_GET* macros for decoding to avoid
byteswapping problems.  Stomp on session key on error conditions.

* g_in_tkt.c: Audit.  Fix up copyright.  Precompute string lengths
for better length-checking.  Use KRB4_PUT* macros for encoding so
output is always big-endian.  Use KRB4_GET* macros for decoding to
avoid byteswapping problems.  Use krb_strnlen() to actually detect
string length errors.  Zero out session key and decrypted KDC
reply once they're no longer useful.

* mk_auth.c: Audit.  Fix up copyright.  Use moving pointer for
encoding.  Use KRB4_PUT* macros for encoding to avoid alignment
issues with using memcpy().  Use KRB4_GET* macros for decoding to
avoid alignment issues with using memcpy().

* mk_err.c: Audit.  Fix up copyright.  Precompute string length.
Use KRB4_PUT* macros to always encode as big-endian.

* mk_preauth.c: Audit.  Zero out key schedule after encryption.

* mk_priv.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
encoding so output is always big-endian.

* mk_req.c: Audit.  Fix up copyright.  Use moving pointer for
encoding.  Precompute string lengths for better length-checking.
Use KRB4_PUT* macros for encoding so output is always big-endian.
Zero out session key after encryption.

* mk_safe.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
encoding so output is always big-endian.

* rd_err.c: Audit.  Fix up copyright.  Use KRB4_GET* macros to
avoid alignment issues.

* rd_preauth.c: Audit.  Zero key schedule after decrypting.

* rd_priv.c: Audit.  Fix up copyright.  Use KRB4_GET* macros to
avoid alignment issues.

* rd_req.c: Audit.  Fix up copyright.

* send_to_kdc.c (send_recv): Actually set rpkt->length, since some
callers actually use it now to do length-checking.

* strnlen.c: New file; compute string length, bounded by a
maximum.  If the maximum number of characters has been read
without encountering a NUL character, return -1.  This makes
overflow checking of strings in buffers much easier.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12859 dc483132-0cff-0310-8789-dd5450dbe970

23 files changed:
src/lib/krb4/ChangeLog
src/lib/krb4/Makefile.in
src/lib/krb4/cr_auth_repl.c
src/lib/krb4/cr_ciph.c
src/lib/krb4/cr_death_pkt.c
src/lib/krb4/cr_err_repl.c
src/lib/krb4/cr_tkt.c
src/lib/krb4/decomp_tkt.c
src/lib/krb4/g_ad_tkt.c
src/lib/krb4/g_in_tkt.c
src/lib/krb4/mk_auth.c
src/lib/krb4/mk_err.c
src/lib/krb4/mk_preauth.c
src/lib/krb4/mk_priv.c
src/lib/krb4/mk_req.c
src/lib/krb4/mk_safe.c
src/lib/krb4/rd_err.c
src/lib/krb4/rd_preauth.c
src/lib/krb4/rd_priv.c
src/lib/krb4/rd_req.c
src/lib/krb4/rd_safe.c
src/lib/krb4/send_to_kdc.c
src/lib/krb4/strnlen.c [new file with mode: 0644]

index bcf59906dacef33b079b506f789430393724a9c7..d3b8f6ef5a1b70fc2fc19db043fd93abce030460 100644 (file)
@@ -1,3 +1,87 @@
+2000-11-08  Tom Yu  <tlyu@mit.edu>
+
+       * Makefile.in (OBJS, SRCS): Add strnlen.o, strnlen.c.
+
+       * cr_auth_repl.c: Audit.  Fix up copyright.  Use new KRB4_PUT*
+       macros for encoding so output is always big-endian.  Precompute
+       string lengths for better length-checking.
+
+       * cr_ciph.c: Audit.  Fix up copyright.  Use new KRB4_PUT* macros
+       for encoding so that output is always big-endian.  Precompute
+       string lengths for better length-checking.  Zero out the key
+       schedule after encrypting.
+
+       * cr_death_pkt.c: Audit.  Fix up copyright.  Precompute string
+       lengths for better length-checking.
+
+       * cr_err_repl.c: Audit.  Fix up copyright.  Use moving pointer to
+       do encoding.  Precompute string lengths for better
+       length-checking.  Use KRB4_PUT* macros so that output is always
+       big-endian.
+
+       * cr_tkt.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
+       encoding so that output is always big-endian.  Zero out the key
+       schedule after encrypting.
+
+       * decomp_tkt.c: Audit.  Fix up copyright.  Use krb_strnlen() for
+       actually detecting string length errors.  Use a struct in_addr to
+       retrieve the IP address and assign it to paddress for return.  Use
+       KRB4_GET* macros for decoding to avoid byteswapping problems.
+       Zero out session key and decrypted ticket on error.
+
+       * g_ad_tkt.c: Audit.  Fix up copyright.  Break out parsing of
+       decrypted KDC reply packet into a separate function to simplify
+       error handling somewhat.  Precompute string lengths for better
+       length-checking.  Use KRB4_PUT* macros for encoding so that output
+       is always big-endian.  Use KRB4_GET* macros for decoding to avoid
+       byteswapping problems.  Stomp on session key on error conditions.
+
+       * g_in_tkt.c: Audit.  Fix up copyright.  Precompute string lengths
+       for better length-checking.  Use KRB4_PUT* macros for encoding so
+       output is always big-endian.  Use KRB4_GET* macros for decoding to
+       avoid byteswapping problems.  Use krb_strnlen() to actually detect
+       string length errors.  Zero out session key and decrypted KDC
+       reply once they're no longer useful.
+
+       * mk_auth.c: Audit.  Fix up copyright.  Use moving pointer for
+       encoding.  Use KRB4_PUT* macros for encoding to avoid alignment
+       issues with using memcpy().  Use KRB4_GET* macros for decoding to
+       avoid alignment issues with using memcpy().
+
+       * mk_err.c: Audit.  Fix up copyright.  Precompute string length.
+       Use KRB4_PUT* macros to always encode as big-endian.
+
+       * mk_preauth.c: Audit.  Zero out key schedule after encryption.
+
+       * mk_priv.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
+       encoding so output is always big-endian.
+
+       * mk_req.c: Audit.  Fix up copyright.  Use moving pointer for
+       encoding.  Precompute string lengths for better length-checking.
+       Use KRB4_PUT* macros for encoding so output is always big-endian.
+       Zero out session key after encryption.
+
+       * mk_safe.c: Audit.  Fix up copyright.  Use KRB4_PUT* macros for
+       encoding so output is always big-endian.
+
+       * rd_err.c: Audit.  Fix up copyright.  Use KRB4_GET* macros to
+       avoid alignment issues.
+
+       * rd_preauth.c: Audit.  Zero key schedule after decrypting.
+
+       * rd_priv.c: Audit.  Fix up copyright.  Use KRB4_GET* macros to
+       avoid alignment issues.
+
+       * rd_req.c: Audit.  Fix up copyright.
+
+       * send_to_kdc.c (send_recv): Actually set rpkt->length, since some
+       callers actually use it now to do length-checking.
+
+       * strnlen.c: New file; compute string length, bounded by a
+       maximum.  If the maximum number of characters has been read
+       without encountering a NUL character, return -1.  This makes
+       overflow checking of strings in buffers much easier.
+
 2000-11-01  Ezra Peisach  <epeisach@mit.edu>
 
        * configure.in: Use AC_C_CONST and AC_CHECK_FUNCS instead of
index 33206ad0b76261d9c1e45756a39ff248f2a6e5ab..3afd33ced09448f1777631480534c994c45c53ca 100644 (file)
@@ -60,6 +60,7 @@ OBJS  = \
        $(OUTPRE)rd_safe.$(OBJEXT) \
        $(OUTPRE)send_to_kdc.$(OBJEXT) \
        $(OUTPRE)stime.$(OBJEXT) \
+       $(OUTPRE)strnlen.$(OBJEXT) \
        $(OUTPRE)rd_preauth.$(OBJEXT) \
        $(OUTPRE)mk_preauth.$(OBJEXT) \
        $(OSOBJS) $(CACHEOBJS) $(SETENVOBJS) $(STRCASEOBJS) $(SHMOBJS) \
@@ -96,6 +97,7 @@ SRCS = \
        $(srcdir)/rd_safe.c \
        $(srcdir)/send_to_kdc.c \
        $(srcdir)/stime.c \
+       $(srcdir)/strnlen.c \
        $(srcdir)/rd_preauth.c \
        $(srcdir)/mk_preauth.c \
        $(srcdir)/unix_time.c \
index a0562d96f359a37e10928c90257a84b73cb4dfec..16482908ee12d369a2cd969e797bbb9f7131d41a 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * cr_auth_repl.c
+ * lib/krb4/cr_auth_repl.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "prot.h"
 #include <string.h>
@@ -58,7 +73,7 @@
  */
 
 KTEXT
-create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
+create_auth_reply(pname, pinst, prealm, time_ws, n, x_date, kvno, cipher)
     char *pname;                /* Principal's name */
     char *pinst;                /* Principal's instance */
     char *prealm;               /* Principal's authentication domain */
@@ -69,54 +84,53 @@ create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
     KTEXT cipher;               /* Cipher text with tickets and
                                 * session keys */
 {
-    static  KTEXT_ST pkt_st;
+    static KTEXT_ST pkt_st;
     KTEXT pkt = &pkt_st;
-    unsigned char *v =  pkt->dat; /* Prot vers number */
-    unsigned char *t = (pkt->dat+1); /* Prot message type */
-    short w_l;                 /* Cipher length */
+    unsigned char *p;
+    size_t pnamelen, pinstlen, prealmlen;
 
     /* Create fixed part of packet */
-    *v = (unsigned char) KRB_PROT_VERSION;
-    *t = (unsigned char) AUTH_MSG_KDC_REPLY;
-    *t |= HOST_BYTE_ORDER;
-
+    p = pkt->dat;
+    /* This is really crusty. */
     if (n != 0)
-       *v = 3;
+       *p++ = 3;
+    else
+       *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_KDC_REPLY; /* always big-endian */
 
     /* Make sure the response will actually fit into its buffer. */
-    if(sizeof(pkt->dat) < 3 + strlen(pname) +
-                         1 + strlen(pinst) +
-                         1 + strlen(prealm) +
-                         4 + 1 + 4 +
-                         1 + 2 + cipher->length) {
+    pnamelen = strlen(pname) + 1;
+    pinstlen = strlen(pinst) + 1;
+    prealmlen = strlen(prealm) + 1;
+    if (sizeof(pkt->dat) < (1 + 1 + pnamelen + pinstlen + prealmlen
+                           + 4 + 1 + 4 + 1 + 2 + cipher->length)
+       || cipher->length > 65535 || cipher->length < 0) {
        pkt->length = 0;
         return NULL;
     }
-                         
     /* Add the basic info */
-    (void) strcpy((char *) (pkt->dat+2), pname);
-    pkt->length = 3 + strlen(pname);
-    (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
-    pkt->length += 1 + strlen(pinst);
-    (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
-    pkt->length += 1 + strlen(prealm);
+    memcpy(p, pname, pnamelen);
+    p += pnamelen;
+    memcpy(p, pinst, pinstlen);
+    p += pinstlen;
+    memcpy(p, prealm, prealmlen);
+    p += prealmlen;
+
     /* Workstation timestamp */
-    memcpy((char *) (pkt->dat+pkt->length), (char *) &time_ws, 4);
-    pkt->length += 4;
-    *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+    KRB4_PUT32(p, time_ws);
+
+    *p++ = n;
+
     /* Expiration date */
-    memcpy((char *) (pkt->dat+pkt->length), (char *) &x_date, 4);
-    pkt->length += 4;
+    KRB4_PUT32(p, x_date);
 
     /* Now send the ciphertext and info to help decode it */
-    *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
-    w_l = (short) cipher->length;
-    memcpy((char *) (pkt->dat+pkt->length), (char *) &w_l, 2);
-    pkt->length += 2;
-    memcpy((char *) (pkt->dat+pkt->length), (char *) (cipher->dat), 
-          cipher->length);
-    pkt->length += cipher->length;
+    *p++ = kvno;
+    KRB4_PUT16(p, cipher->length);
+    memcpy(p, cipher->dat, (size_t)cipher->length);
+    p += cipher->length;
 
     /* And return the packet */
+    pkt->length = p - pkt->dat;
     return pkt;
 }
index d9c751271f077667db31bfbc5d07c034bed762de..a2bbdff5c4ddf6a820dfbe4909da0628c11e6e29 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * cr_ciph.c
+ * lib/krb4/cr_ciph.c
  *
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "des.h"
 #include <string.h>
@@ -53,6 +68,7 @@
  *
  */
 
+int
 create_ciph(c, session, service, instance, realm, life, kvno, tkt,
            kdc_time, key)
     KTEXT           c;         /* Text block to hold ciphertext */
@@ -66,54 +82,54 @@ create_ciph(c, session, service, instance, realm, life, kvno, tkt,
     unsigned long   kdc_time;  /* KDC time */
     C_Block         key;       /* Key to encrypt ciphertext with */
 {
-    char            *ptr;
+    unsigned char   *ptr;
+    size_t          servicelen, instancelen, realmlen;
     Key_schedule    key_s;
 
-    ptr = (char *) c->dat;
+    ptr = c->dat;
 
-    if(sizeof(c->dat) / 8 < (8 +
-                            strlen(service) + 1 +
-                            strlen(instance) + 1 +
-                            strlen(realm) + 1 +
-                            1 + 1 + 1 +
-                            tkt->length + 4 +
-                            7) / 8) {
+    /* Validate lengths. */
+    servicelen = strlen(service) + 1;
+    instancelen = strlen(instance) + 1;
+    realmlen = strlen(realm) + 1;
+    if (sizeof(c->dat) / 8 < ((8 + servicelen + instancelen + realmlen
+                              + 1 + 1 + 1 + tkt->length
+                              + 4 + 7) / 8)
+       || tkt->length > 255 || tkt->length < 0) {
         c->length = 0;
-        return(KFAILURE);
+        return KFAILURE;
     }
 
-    memcpy(ptr, (char *) session, 8);
+    memcpy(ptr, session, 8);
     ptr += 8;
 
-    (void) strcpy(ptr,service);
-    ptr += strlen(service) + 1;
-
-    (void) strcpy(ptr,instance);
-    ptr += strlen(instance) + 1;
-
-    (void) strcpy(ptr,realm);
-    ptr += strlen(realm) + 1;
+    memcpy(ptr, service, servicelen);
+    ptr += servicelen;
+    memcpy(ptr, instance, instancelen);
+    ptr += instancelen;
+    memcpy(ptr, realm, realmlen);
+    ptr += realmlen;
 
-    *(ptr++) = (unsigned char) life;
-    *(ptr++) = (unsigned char) kvno;
-    *(ptr++) = (unsigned char) tkt->length;
+    *ptr++ = life;
+    *ptr++ = kvno;
+    *ptr++ = tkt->length;
 
-    memcpy(ptr, (char *)(tkt->dat), tkt->length);
+    memcpy(ptr, tkt->dat, (size_t)tkt->length);
     ptr += tkt->length;
 
-    memcpy(ptr, (char *) &kdc_time, 4);
-    ptr += 4;
+    KRB4_PUT32(ptr, kdc_time);
 
     /* guarantee null padded encrypted data to multiple of 8 bytes */
     memset(ptr, 0, 7);
 
-    c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+    c->length = (((ptr - c->dat) + 7) / 8) * 8;
 
 #ifndef NOENCRYPTION
-    key_sched(key,key_s);
-    pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,
-                (long) c->length,key_s,(C_Block*) key,ENCRYPT);
+    key_sched(key, key_s);
+    pcbc_encrypt((C_Block *)c->dat, (C_Block *)c->dat,
+                (long)c->length, key_s, (C_Block*)key, ENCRYPT);
+    memset(key_s, 0, sizeof(key_s));
 #endif /* NOENCRYPTION */
 
-    return(KSUCCESS);
+    return KSUCCESS;
 }
index c3562675dca529ad2e74dd6e3f3e69ede3af6ce7..63d756277e4300d224bbaceea4e1be16859dfc3b 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * cr_death_pkt.c
+ * lib/krb4/cr_death_pkt.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "prot.h"
 #include <string.h>
@@ -46,15 +61,18 @@ krb_create_death_packet(a_name)
 {
     static KTEXT_ST pkt_st;
     KTEXT pkt = &pkt_st;
+    unsigned char *p;
+    size_t namelen;
 
-    unsigned char *v =  pkt->dat;
-    unsigned char *t =  (pkt->dat+1);
-    *v = (unsigned char) KRB_PROT_VERSION;
-    *t = (unsigned char) AUTH_MSG_DIE;
-    *t |= HOST_BYTE_ORDER;
-    (void) strncpy((char *) (pkt->dat+2),a_name,sizeof(pkt->dat) - 3);
-    pkt->dat[sizeof(pkt->dat) - 1] = '\0';
-    pkt->length = 3 + strlen(pkt->dat+2);
+    p = pkt->dat;
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_DIE;
+    namelen = strlen(a_name) + 1;
+    if (1 + 1 + namelen > sizeof(pkt->dat))
+       return NULL;
+    memcpy(p, a_name, namelen);
+    p += namelen;
+    pkt->length = p - pkt->dat;
     return pkt;
 }
 #endif /* DEBUG */
index 54e87d82ed6898f880c8cb27c59d7168a79bbed8..35196df49efb85d4c6ec775166ee1b72ef930495 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * cr_err_repl.c
+ * lib/krb4/cr_err_repl.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "prot.h"
 #include <string.h>
@@ -66,44 +81,39 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
     u_long e;                  /* Error code */
     char *e_string;            /* Text of error */
 {
-    u_char *v = (u_char *) pkt->dat; /* Prot vers number */
-    u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */
+    unsigned char *p;
+    size_t pnamelen, pinstlen, prealmlen, e_stringlen;
 
-    /* Create fixed part of packet */
-#if 0
-    *v = (unsigned char) req_act_vno; /* KRB_PROT_VERSION; */
-#else
-    *v = (unsigned char) KRB_PROT_VERSION;
-#endif
-    *t = (unsigned char) AUTH_MSG_ERR_REPLY;
-    *t |= HOST_BYTE_ORDER;
+    p = pkt->dat;
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_ERR_REPLY;
 
     /* Make sure the reply will fit into the buffer. */
-    if(sizeof(pkt->dat) < 3 + strlen(pname) +
-                         1 + strlen(pinst) +
-                         1 + strlen(prealm) +
-                         4 + 4 +
-                         1 + strlen(e_string)) {
+    pnamelen = strlen(pname) + 1;
+    pinstlen = strlen(pinst) + 1;
+    prealmlen = strlen(prealm) + 1;
+    e_stringlen = strlen(e_string) + 1;
+    if(sizeof(pkt->dat) < (1 + 1 + pnamelen + pinstlen + prealmlen
+                          + 4 + 4 + e_stringlen)) {
         pkt->length = 0;
        return;
     }
     /* Add the basic info */
-    (void) strcpy((char *) (pkt->dat+2),pname);
-    pkt->length = 3 + strlen(pname);
-    (void) strcpy((char *)(pkt->dat+pkt->length),pinst);
-    pkt->length += 1 + strlen(pinst);
-    (void) strcpy((char *)(pkt->dat+pkt->length),prealm);
-    pkt->length += 1 + strlen(prealm);
+    memcpy(p, pname, pnamelen);
+    p += pnamelen;
+    memcpy(p, pinst, pinstlen);
+    p += pinstlen;
+    memcpy(p, prealm, prealmlen);
+    p += prealmlen;
     /* ws timestamp */
-    memcpy((char *)(pkt->dat+pkt->length), (char *) &time_ws, 4);
-    pkt->length += 4;
+    KRB4_PUT32(p, time_ws);
     /* err code */
-    memcpy((char *)(pkt->dat+pkt->length), (char *) &e, 4);
-    pkt->length += 4;
+    KRB4_PUT32(p, e);
     /* err text */
-    (void) strcpy((char *)(pkt->dat+pkt->length),e_string);
-    pkt->length += 1 + strlen(e_string);
+    memcpy(p, e_string, e_stringlen);
+    p += e_stringlen;
 
     /* And return */
+    pkt->length = p - pkt->dat;
     return;
 }
index 62d5b5438168e8ac148926277adaa0cb1d9c9317..46753d820d131694a9fae6f68467b7c4672a7594 100644 (file)
@@ -1,14 +1,29 @@
-/* 
- * cr_tkt.c
+/*
+ * lib/krb4/cr_tkt.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "des.h"
 #include "krb.h"
 #include "prot.h"
@@ -22,7 +37,6 @@ krb_cr_tkt_int PROTOTYPE((KTEXT tkt, unsigned int flags_in, char *pname,
                          char *sname, char *sinstance, C_Block key, 
                          krb5_keyblock *k5key));
 
-
 /*
  * Create ticket takes as arguments information that should be in a
  * ticket, and the KTEXT object in which the ticket should be
@@ -140,60 +154,61 @@ krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress,
     krb5_keyblock *k5key;      /* NULL if not present */
 {
     Key_schedule key_s;
-    register char *data;        /* running index into ticket */
-    unsigned char flags = flags_in & 0xFF; /* Must be 1 byte */
+    register unsigned char *data; /* running index into ticket */
+    size_t pnamelen, pinstlen, prealmlen, snamelen, sinstlen;
+    struct in_addr paddr;
+
+    /* Be really paranoid. */
+    if (sizeof(paddr.s_addr) != 4)
+       return KFAILURE;
 
     tkt->length = 0;            /* Clear previous data  */
 
     /* Check length of ticket */
-    if (sizeof(tkt->dat) < (sizeof(flags) +
-                            1 + strlen(pname) +
-                            1 + strlen(pinstance) +
-                            1 + strlen(prealm) +
-                            4 +                         /* address */
-                           8 +                         /* session */
-                           1 +                         /* life */
-                           4 +                         /* issue time */
-                            1 + strlen(sname) +
-                            1 + strlen(sinstance) +
-                           7) / 8) {                   /* roundoff */
+    pnamelen = strlen(pname) + 1;
+    pinstlen = strlen(pinstance) + 1;
+    prealmlen = strlen(prealm) + 1;
+    snamelen = strlen(sname) + 1;
+    sinstlen = strlen(sinstance) + 1;
+    if (sizeof(tkt->dat) / 8 < ((1 + pnamelen + pinstlen + prealmlen
+                                + 4 /* address */
+                                + 8 /* session */
+                                + 1 /* life */
+                                + 4 /* issue time */
+                                + snamelen + sinstlen
+                                + 7) / 8) /* roundoff */
+       || life > 255 || life < 0) {
         memset(tkt->dat, 0, sizeof(tkt->dat));
         return KFAILURE /* XXX */;
     }
 
-    flags |= HOST_BYTE_ORDER;   /* ticket byte order   */
-    memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags));
-    data = ((char *)tkt->dat) + sizeof(flags);
-    (void) strcpy(data, pname);
-    data += 1 + strlen(pname);
-    (void) strcpy(data, pinstance);
-    data += 1 + strlen(pinstance);
-    (void) strcpy(data, prealm);
-    data += 1 + strlen(prealm);
-    memcpy(data, (char *) &paddress, 4);
-    data += 4;
-
-    memcpy(data, (char *) session, 8);
+    data = tkt->dat;
+    *data++ = flags_in;
+    memcpy(data, pname, pnamelen);
+    data += pnamelen;
+    memcpy(data, pinstance, pinstlen);
+    data += pinstlen;
+    memcpy(data, prealm, prealmlen);
+    data += prealmlen;
+
+    paddr.s_addr = paddress;
+    memcpy(data, &paddr.s_addr, sizeof(paddr.s_addr));
+    data += sizeof(paddr.s_addr);
+
+    memcpy(data, session, 8);
     data += 8;
-    *(data++) = (char) life;
+    *data++ = life;
     /* issue time */
-    memcpy(data, (char *) &time_sec, 4);
-    data += 4;
-    (void) strcpy(data, sname);
-    data += 1 + strlen(sname);
-    (void) strcpy(data, sinstance);
-    data += 1 + strlen(sinstance);
+    KRB4_PUT32(data, time_sec);
+
+    memcpy(data, sname, snamelen);
+    data += snamelen;
+    memcpy(data, sinstance, sinstlen);
+    data += sinstlen;
 
     /* guarantee null padded ticket to multiple of 8 bytes */
     memset(data, 0, 7);
-    tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
-
-    /* Check length of ticket */
-    if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
-        memset(tkt->dat, 0, tkt->length);
-        tkt->length = 0;
-        return KFAILURE /* XXX */;
-    }
+    tkt->length = ((data - tkt->dat + 7) / 8) * 8;
 
 #ifndef NOENCRYPTION
     /* Encrypt the ticket in the services key */
@@ -205,7 +220,7 @@ krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress,
        size_t enclen;
 
        in.length = tkt->length;
-       in.data = tkt->dat;
+       in.data = (char *)tkt->dat;
        /* XXX assumes context arg is ignored */
        ret = krb5_c_encrypt_length(NULL, k5key->enctype,
                                    (size_t)in.length, &enclen);
@@ -229,9 +244,10 @@ krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress,
            free(out.ciphertext.data);
        }
     } else {
-       key_sched(key,key_s);
-       pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,
-                    (long) tkt->length,key_s,(C_Block *)key,1);
+       key_sched(key, key_s);
+       pcbc_encrypt((C_Block *)tkt->dat, (C_Block *)tkt->dat,
+                    (long)tkt->length, key_s, (C_Block *)key, 1);
+       memset(key_s, 0, sizeof(key_s));
     }
 #endif /* !NOENCRYPTION */
     return 0;
index 06e9e316c516a400f5680f0f37bd260023c87c4b..c74cdba3eee9501b41a5f7ac8b631841a512da1d 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * decomp_tkt.c
- * 
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * lib/krb4/decomp_tkt.c
+ *
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "des.h"
 #include "krb.h"
 #include "prot.h"
@@ -123,9 +138,14 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
     Key_schedule key_s;                /* The precomputed key schedule */
     krb5_keyblock *k5key;      /* krb5 keyblock of service */
 {
-    static int tkt_swap_bytes;
-    unsigned char *uptr;
-    char *ptr = (char *)tkt->dat;
+    int tkt_le;                        /* little-endian ticket? */
+    unsigned char *ptr = tkt->dat;
+    int kret, len;
+    struct in_addr paddr;
+
+    /* Be really paranoid. */
+    if (sizeof(paddr.s_addr) != 4)
+       return KFAILURE;
 
 #ifndef NOENCRYPTION
     /* Do the decryption */
@@ -150,9 +170,9 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
        in.enctype = k5key->enctype;
        in.kvno = 0;
        in.ciphertext.length = tkt->length;
-       in.ciphertext.data = tkt->dat;
+       in.ciphertext.data = (char *)tkt->dat;
        out.length = tkt->length;
-       out.data = malloc(tkt->length);
+       out.data = malloc((size_t)tkt->length);
        if (out.data == NULL)
            return KFAILURE;    /* XXX maybe ENOMEM? */
 
@@ -169,8 +189,8 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
            free(out.data);
        }
     } else {
-       pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,
-                    (long) tkt->length,key_s,(C_Block *) key,0);
+       pcbc_encrypt((C_Block *)tkt->dat, (C_Block *)tkt->dat,
+                    (long)tkt->length, key_s, (C_Block *)key, 0);
     }
 #endif /* ! NOENCRYPTION */
 #ifdef KRB_CRYPT_DEBUG
@@ -186,58 +206,70 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
     }
 #endif
 
-    *flags = *ptr;              /* get flags byte */
-    ptr += sizeof(*flags);
-    tkt_swap_bytes = 0;
-    if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
-        tkt_swap_bytes++;
-
-    if (strlen(ptr) >= ANAME_SZ)
-        return(KFAILURE);
-    (void) strcpy(pname,ptr);   /* pname */
-    ptr += strlen(pname) + 1;
-
-    if (strlen(ptr) >= INST_SZ)
-        return(KFAILURE);
-    (void) strcpy(pinstance,ptr); /* instance */
-    ptr += strlen(pinstance) + 1;
-
-    if (strlen(ptr) >= REALM_SZ)
-        return(KFAILURE);
-    (void) strcpy(prealm,ptr);  /* realm */
-    ptr += strlen(prealm) + 1;
+#define TKT_REMAIN (tkt->length - (ptr - tkt->dat))
+    kret = KFAILURE;
+    if (TKT_REMAIN < 1)
+       goto cleanup;
+    *flags = *ptr++;
+    tkt_le = (*flags >> K_FLAG_ORDER) & 1;
+
+    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    if (len <= 0 || len > ANAME_SZ)
+       goto cleanup;
+    memcpy(pname, ptr, (size_t)len);
+    ptr += len;
+
+    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       goto cleanup;
+    memcpy(pinstance, ptr, (size_t)len);
+    ptr += len;
+
+    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    if (len <= 0 || len > REALM_SZ)
+       goto cleanup;
+    memcpy(prealm, ptr, (size_t)len);
+    ptr += len;
+
     /* temporary hack until realms are dealt with properly */
-    if (*prealm == 0)
-        (void) strcpy(prealm,KRB_REALM);
+    if (*prealm == '\0')
+        strcpy(prealm, KRB_REALM);
 
-    memcpy((char *)paddress, ptr, 4); /* net address */
-    ptr += 4;
+    /*
+     * Ensure there's enough remaining in the ticket to get the
+     * fixed-size stuff.
+     */
+    if (TKT_REMAIN < 4 + 8 + 1 + 4)
+       goto cleanup;
 
-    memcpy((char *)session, ptr, 8); /* session key */
-    ptr+= 8;
+    memcpy(&paddr.s_addr, ptr, sizeof(paddr.s_addr));
+    ptr += sizeof(paddr.s_addr);
+    *paddress = paddr.s_addr;
+
+    memcpy(session, ptr, 8); /* session key */
+    memset(ptr, 0, 8);
+    ptr += 8;
 #ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
     if (tkt_swap_bytes)
         swap_C_Block(session);
 #endif
 
-    /* get lifetime, being certain we don't get negative lifetimes */
-    uptr = (unsigned char *) ptr++;
-    *life = (int) *uptr;
+    *life = *ptr++;
 
-    memcpy((char *) time_sec, ptr, 4); /* issue time */
-    ptr += 4;
-    if (tkt_swap_bytes)
-        *time_sec = krb4_swab32(*time_sec);
+    KRB4_GET32(*time_sec, ptr, tkt_le);
 
-    if (strlen(ptr) >= ANAME_SZ)
-       return KFAILURE;
-    (void) strcpy(sname,ptr);   /* service name */
-    ptr += 1 + strlen(sname);
+    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    if (len <= 0 || len > SNAME_SZ)
+       goto cleanup;
+    memcpy(sname, ptr, (size_t)len);
+    ptr += len;
 
-    if (strlen (ptr) >= INST_SZ)
-       return KFAILURE;
-    (void) strcpy(sinstance,ptr); /* instance */
-    ptr += 1 + strlen(sinstance);
+    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       goto cleanup;
+    memcpy(sinstance, ptr, (size_t)len);
+    ptr += len;
+    kret = KSUCCESS;
 
 #ifdef KRB_CRYPT_DEBUG
     if (krb_debug) {
@@ -247,5 +279,11 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
     }
 #endif
 
-    return(KSUCCESS);
+cleanup:
+    if (kret != KSUCCESS) {
+       memset(session, 0, sizeof(session));
+       memset(tkt->dat, 0, (size_t)tkt->length);
+       return kret;
+    }
+    return KSUCCESS;
 }
index afcd0c6f8b301581f6a7201f7a2116392dcb61ab..092be7a225002e47b1839ae350837af489f7126e 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * g_ad_tkt.c
+ * lib/krb4/g_ad_tkt.c
  *
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "des.h"
 #include "prot.h"
 extern int krb_debug;
 extern int swap_bytes;
 
-/* Return the length of the string if a NUL is found within the first
- * max_len bytes, otherwise, -1. */
-static int krb_strnlen(const char *str, int max_len)
-{
-    int i;
-    for(i = 0; i < max_len; i++) {
-        if(str[i] == '\0') {
-            return i;
-        }
-    }
-    return -1;
-}
-
 /*
  * get_ad_tkt obtains a new service ticket from Kerberos, using
  * the ticket-granting ticket which must be in the ticket file.
@@ -65,41 +67,193 @@ static int krb_strnlen(const char *str, int max_len)
  * extraction macros like pkt_version(), pkt_msg_type(), etc.
  */
 
-get_ad_tkt(service,sinstance,realm,lifetime)
+/*
+ * g_ad_tk_parse()
+ *
+ * Parse the returned packet from the KDC.
+ *
+ * Note that the caller is responsible for clearing the returned
+ * session key if there is an error; that makes the error handling
+ * code a little less hairy.
+ */
+static int
+g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses,
+              char *s_name, char *s_instance, char *rlm,
+              char *service, char *sinstance, char *realm,
+              int *lifetime, int *kvno, KTEXT tkt,
+              unsigned KRB4_32 *kdc_time,
+              KRB4_32 *t_local)
+{
+    unsigned char *ptr;
+    unsigned int t_switch;
+    int msg_byte_order;
+    unsigned long rep_err_code;
+    unsigned long cip_len;
+    KTEXT_ST cip_st;
+    KTEXT cip = &cip_st;       /* Returned Ciphertext */
+    Key_schedule key_s;
+    int len, i;
+    KRB4_32 t_diff;            /* Difference between timestamps */
+
+    ptr = rpkt->dat;
+#define RPKT_REMAIN (rpkt->length - (ptr - rpkt->dat))
+    if (RPKT_REMAIN < 1 + 1)
+       return INTK_PROT;
+    /* check packet version of the returned packet */
+    if (*ptr++ != KRB_PROT_VERSION)
+       return INTK_PROT;
+
+    /* This used to be
+         switch (pkt_msg_type(rpkt) & ~1) {
+       but SCO 3.2v4 cc compiled that incorrectly.  */
+    t_switch = *ptr++;
+    /* Check byte order (little-endian == 1) */
+    msg_byte_order = t_switch & 1;
+    t_switch &= ~1;
+    switch (t_switch) {
+    case AUTH_MSG_KDC_REPLY:
+       break;
+    case AUTH_MSG_ERR_REPLY:
+       if (RPKT_REMAIN < 4)
+           return INTK_PROT;
+       KRB4_GET32(rep_err_code, ptr, msg_byte_order);
+       return rep_err_code;
+
+    default:
+       return INTK_PROT;
+    }
+    /*
+     * Skip over some stuff (3 strings and various integers -- see
+     * cr_auth_repl.c for details).  Maybe we should actually verify
+     * these?
+     */
+    for (i = 0; i < 3; i++) {
+       len = krb_strnlen((char *)ptr, RPKT_REMAIN) + 1;
+       if (len <= 0)
+           return INTK_PROT;
+       ptr += len;
+    }
+    if (RPKT_REMAIN < 4 + 1 + 4 + 1)
+       return INTK_PROT;
+    ptr += 4 + 1 + 4 + 1;
+
+    /* Extract the ciphertext */
+    if (RPKT_REMAIN < 2)
+       return INTK_PROT;
+    KRB4_GET16(cip_len, ptr, msg_byte_order);
+    if (RPKT_REMAIN < cip_len)
+       return INTK_PROT;
+    /*
+     * RPKT_REMAIN will always be non-negative and at most the maximum
+     * possible value of cip->length, so this assignment is safe.
+     */
+    cip->length = cip_len;
+    memcpy(cip->dat, ptr, (size_t)cip->length);
+    ptr += cip->length;
+
+#ifndef NOENCRYPTION
+    /* Attempt to decrypt it */
+
+    key_sched(tgtses, key_s);
+    DEB (("About to do decryption ..."));
+    pcbc_encrypt((C_Block *)cip->dat, (C_Block *)cip->dat,
+                 (long)cip->length, key_s, (C_Block *)tgtses, 0);
+#endif /* !NOENCRYPTION */
+    /*
+     * Stomp on key schedule.  Caller should stomp on tgtses.
+     */
+    memset(key_s, 0, sizeof(key_s));
+
+    ptr = cip->dat;
+#define CIP_REMAIN (cip->length - (ptr - cip->dat))
+    if (CIP_REMAIN < 8)
+       return RD_AP_MODIFIED;
+    memcpy(ses, ptr, 8);
+    /*
+     * Stomp on decrypted session key immediately after copying it.
+     */
+    memset(ptr, 0, 8);
+    ptr += 8;
+
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > SNAME_SZ)
+       return RD_AP_MODIFIED;
+    memcpy(s_name, ptr, (size_t)len);
+    ptr += len;
+
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       return RD_AP_MODIFIED;
+    memcpy(s_instance, ptr, (size_t)len);
+    ptr += len;
+
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > REALM_SZ)
+       return RD_AP_MODIFIED;
+    memcpy(rlm, ptr, (size_t)len);
+    ptr += len;
+
+    if (strcmp(s_name, service) || strcmp(s_instance, sinstance)
+       || strcmp(rlm, realm))  /* not what we asked for */
+       return INTK_ERR;        /* we need a better code here XXX */
+
+    if (CIP_REMAIN < 1 + 1 + 1)
+       return RD_AP_MODIFIED;
+    *lifetime = *ptr++;
+    *kvno = *ptr++;
+    tkt->length = *ptr++;
+
+    if (CIP_REMAIN < tkt->length)
+       return RD_AP_MODIFIED;
+    memcpy(tkt->dat, ptr, (size_t)tkt->length);
+    ptr += tkt->length;
+
+    /* Time (coarse) */
+    if (CIP_REMAIN < 4)
+       return RD_AP_MODIFIED;
+    KRB4_GET32(*kdc_time, ptr, msg_byte_order);
+
+    /* check KDC time stamp */
+    *t_local = TIME_GMT_UNIXSEC;
+    t_diff = *t_local - *kdc_time;
+    if (t_diff < 0)
+       t_diff = -t_diff;       /* Absolute value of difference */
+    if (t_diff > CLOCK_SKEW)
+       return RD_AP_TIME;      /* XXX should probably be better code */
+
+    return 0;
+}
+
+int
+get_ad_tkt(service, sinstance, realm, lifetime)
     char    *service;
     char    *sinstance;
     char    *realm;
     int     lifetime;
 {
-    unsigned long rep_err_code;
-
     KTEXT_ST pkt_st;
     KTEXT pkt = & pkt_st;      /* Packet to KDC */
     KTEXT_ST rpkt_st;
     KTEXT rpkt = &rpkt_st;     /* Returned packet */
-    KTEXT_ST cip_st;
-    KTEXT cip = &cip_st;       /* Returned Ciphertext */
     KTEXT_ST tkt_st;
     KTEXT tkt = &tkt_st;       /* Current ticket */
     C_Block ses;                /* Session key for tkt */
     CREDENTIALS cr;
     int kvno;                  /* Kvno for session key */
+    int kerror;
     char lrealm[REALM_SZ];
-    Key_schedule key_s;
     KRB4_32 time_ws = 0;
     char s_name[SNAME_SZ];
     char s_instance[INST_SZ];
-    int msg_byte_order;
-    int kerror;
     char rlm[REALM_SZ];
-    char *ptr;
-    unsigned KRB4_32 t_local;  /* Must be 4 bytes long for memcpy below! */
-    KRB4_32 t_diff;            /* Difference between timestamps */
+    unsigned char *ptr;
+    KRB4_32 t_local;
     unsigned KRB4_32 kdc_time;   /* KDC time */
-    unsigned int t_switch;
+    size_t snamelen, sinstlen;
 
-    if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
-       return(kerror);
+    kerror = krb_get_tf_realm(TKT_FILE, lrealm);
+    if (kerror != KSUCCESS)
+       return kerror;
 
     /* Create skeleton of packet to be sent */
     pkt->length = 0;
@@ -118,157 +272,95 @@ get_ad_tkt(service,sinstance,realm,lifetime)
      * If that succeeds, the ticket will be in ticket cache, get it
      * into the "cr" structure by calling krb_get_cred().
      */
-    
-    if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+    kerror = krb_get_cred("krbtgt", realm, lrealm, &cr);
+    if (kerror != KSUCCESS) {
        /*
         * If realm == lrealm, we have no hope, so let's not even try.
         */
-       if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
-           return(AD_NOTGT);
-       else{
-           if ((kerror = 
-                get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS) {
+       if (strncmp(realm, lrealm, sizeof(lrealm)) == 0)
+           return AD_NOTGT;
+       else {
+           kerror = get_ad_tkt("krbtgt", realm, lrealm, lifetime);
+           if (kerror != KSUCCESS) {
                if (kerror == KDC_PR_UNKNOWN)   /* no cross-realm ticket */
                    return AD_NOTGT;            /* So call it no ticket */
-               return(kerror);
+               return kerror;
            }
-           if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
-               return(kerror);
+           kerror = krb_get_cred("krbtgt",realm,lrealm,&cr);
+           if (kerror != KSUCCESS)
+               return kerror;
        }
     }
-    
+
     /*
      * Make up a request packet to the "krbtgt.realm@lrealm".
      * Start by calling krb_mk_req() which puts ticket+authenticator
      * into "pkt".  Then tack other stuff on the end.
      */
-    
-    kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+    kerror = krb_mk_req(pkt, "krbtgt", realm, lrealm, 0L);
+    if (kerror) {
+       /* stomp stomp stomp */
+       memset(cr.session, 0, sizeof(cr.session));
+       return AD_NOTGT;
+    }
 
-    if (kerror)
-       return(AD_NOTGT);
+    ptr = pkt->dat + pkt->length;
+
+    snamelen = strlen(service) + 1;
+    sinstlen = strlen(sinstance) + 1;
+    if (sizeof(pkt->dat) - (ptr - pkt->dat) < (4 + 1
+                                              + snamelen
+                                              + sinstlen)) {
+       /* stomp stomp stomp */
+       memset(cr.session, 0, sizeof(cr.session));
+       return INTK_ERR;
+    }
 
     /* timestamp */   /* FIXME -- always 0 now, should we fill it in??? */
-    if(pkt->length + 4 > sizeof(pkt->dat))
-        return(INTK_ERR);
-    memcpy((char *) (pkt->dat+pkt->length), (char *) &time_ws, 4);
-    pkt->length += 4;
+    KRB4_PUT32(ptr, time_ws);
 
-    if(pkt->length + 1 > sizeof(pkt->dat))
-        return(INTK_ERR);
-    *(pkt->dat+(pkt->length)++) = (char) lifetime;
+    *ptr++ = lifetime;
 
-    if(pkt->length + 1 + strlen(service) > sizeof(pkt->dat))
-        return(INTK_ERR);
-    (void) strcpy((char *) (pkt->dat+pkt->length),service);
-    pkt->length += 1 + strlen(service);
+    memcpy(ptr, service, snamelen);
+    ptr += snamelen;
+    memcpy(ptr, sinstance, sinstlen);
+    ptr += sinstlen;
 
-    if(pkt->length + 1 + strlen(sinstance) > sizeof(pkt->dat))
-        return(INTK_ERR);
-    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
-    pkt->length += 1 + strlen(sinstance);
-
-    rpkt->length = 0;
+    pkt->length = ptr - pkt->dat;
 
     /* Send the request to the local ticket-granting server */
-    if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
-
-    /* check packet version of the returned packet */
-    if (pkt_version(rpkt) != KRB_PROT_VERSION )
-        return(INTK_PROT);
-
-    /* Check byte order */
-    msg_byte_order = pkt_msg_type(rpkt) & 1;
-    swap_bytes = 0;
-    if (msg_byte_order != HOST_BYTE_ORDER)
-       swap_bytes++;
-
-    /* This used to be
-         switch (pkt_msg_type(rpkt) & ~1) {
-       but SCO 3.2v4 cc compiled that incorrectly.  */
-    t_switch = pkt_msg_type(rpkt);
-    t_switch &= ~1;
-    switch (t_switch) {
-    case AUTH_MSG_KDC_REPLY:
-       break;
-    case AUTH_MSG_ERR_REPLY:
-       memcpy((char *) &rep_err_code, pkt_err_code(rpkt), 4);
-       if (swap_bytes)
-           rep_err_code = krb4_swab32(rep_err_code);
-       return(rep_err_code);
-
-    default:
-       return(INTK_PROT);
+    rpkt->length = 0;
+    kerror = send_to_kdc(pkt, rpkt, realm);
+
+    if (!kerror) {
+       /* No error; parse return packet from KDC. */
+       kerror = g_ad_tkt_parse(rpkt, cr.session, ses,
+                               s_name, s_instance, rlm,
+                               service, sinstance, realm,
+                               &lifetime, &kvno, tkt,
+                               &kdc_time, &t_local);
     }
-
-    /* Extract the ciphertext */
-    cip->length = pkt_clen(rpkt);       /* let clen do the swap */
-
-    memcpy((char *) (cip->dat), (char *) pkt_cipher(rpkt), cip->length);
-
-#ifndef NOENCRYPTION
-    /* Attempt to decrypt it */
-
-    key_sched(cr.session,key_s);
-    DEB (("About to do decryption ..."));
-    pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
-                 (long) cip->length,key_s,(C_Block *)cr.session,0);
-#endif /* !NOENCRYPTION */
-    /* Get rid of all traces of key */
-    memset((char *) cr.session, 0, sizeof(cr.session));
-    memset((char *) key_s, 0, sizeof(key_s));
-
-    ptr = (char *) cip->dat;
-
-    memcpy((char *)ses, ptr, 8);
-    ptr += 8;
-
-    if(krb_strnlen(ptr, sizeof(s_name)) < 0)
-        return RD_AP_MODIFIED;
-    (void) strncpy(s_name,ptr,sizeof(s_name) - 1);
-    s_name[sizeof(s_name) - 1] = '\0';
-    ptr += strlen(s_name) + 1;
-
-    if(krb_strnlen(ptr, sizeof(s_instance)) < 0)
-        return RD_AP_MODIFIED;
-    (void) strncpy(s_instance,ptr,sizeof(s_instance)-1);
-    s_instance[sizeof(s_instance)-1] = '\0';
-    ptr += strlen(s_instance) + 1;
-
-    if(krb_strnlen(ptr, sizeof(rlm)) < 0)
-        return RD_AP_MODIFIED;
-    (void) strncpy(rlm,ptr,sizeof(rlm) - 1);
-    rlm[sizeof(rlm)-1];
-    ptr += strlen(rlm) + 1;
-
-    lifetime = (unsigned char) ptr[0];
-    kvno = (unsigned char) ptr[1];
-    tkt->length = (unsigned char) ptr[2];
-    ptr += 3;
-    memcpy((char *)(tkt->dat), ptr, tkt->length);
-    ptr += tkt->length;
-
-    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
-        strcmp(rlm, realm))    /* not what we asked for */
-       return(INTK_ERR);       /* we need a better code here XXX */
-
-    /* check KDC time stamp */
-    memcpy((char *)&kdc_time, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) kdc_time = krb4_swab32(kdc_time);
-
-    ptr += 4;
-
-    t_local = TIME_GMT_UNIXSEC;
-    t_diff = t_local - kdc_time;
-    if (t_diff < 0) t_diff = -t_diff;  /* Absolute value of difference */
-    if (t_diff > CLOCK_SKEW) {
-        return(RD_AP_TIME);            /* XXX should probably be better
-                                          code */
+    /*
+     * Unconditionally stomp on cr.session because we don't need it
+     * anymore.
+     */
+    memset(cr.session, 0, sizeof(cr.session));
+    if (kerror) {
+       /*
+        * Stomp on ses for good measure, since g_ad_tkt_parse()
+        * doesn't do that for us.
+        */
+       memset(ses, 0, sizeof(ses));
+       return kerror;
     }
 
-    if (kerror = krb_save_credentials(s_name,s_instance,rlm,ses,lifetime,
-                                 kvno,tkt,t_local))
-       return(kerror);
-
-    return(AD_OK);
+    kerror = krb_save_credentials(s_name, s_instance, rlm,
+                                 ses, lifetime, kvno, tkt, t_local);
+    /*
+     * Unconditionally stomp on ses because we don't need it anymore.
+     */
+    memset(ses, 0, sizeof(ses));
+    if (kerror)
+       return kerror;
+    return AD_OK;
 }
index 361273c9d73fc5cdd43161c7b99e6a5d016ae063..b7ab0dfc433e5efe20f9c985cedb75dcb33e54e8 100644 (file)
@@ -1,22 +1,35 @@
 /*
- * g_in_tkt.c
+ * lib/krb4/g_in_tkt.c
  *
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "des.h"
 #include "prot.h"
 
 #include <string.h>
 
-extern int     swap_bytes;
-
 /* Define a couple of function types including parameters.  These
    are needed on MS-Windows to convert arguments of the function pointers
    to the proper types during calls.  These declarations are found
@@ -39,40 +52,36 @@ typedef int (*decrypt_tkt_type) PROTOTYPE ((char *, char *, char *, char *,
 
 static int
 decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
-  char *user;
-  char *instance;
-  char *realm;
-  char *arg;
-  key_proc_type key_proc;
-  KTEXT *cipp;
+    char *user;
+    char *instance;
+    char *realm;
+    char *arg;
+    key_proc_type key_proc;
+    KTEXT *cipp;
 {
     KTEXT cip = *cipp;
     C_Block key;               /* Key for decrypting cipher */
     Key_schedule key_s;
+    register int rc;
 
 #ifndef NOENCRYPTION
     /* Attempt to decrypt it */
 #endif
-    
     /* generate a key from the supplied arg or password.  */
-    
-    {
-       register int rc;
-       rc = (*key_proc) (user,instance,realm,arg,key);
-       if (rc)
-           return(rc);
-    }
-    
+    rc = (*key_proc)(user, instance, realm, arg, key);
+    if (rc)
+       return rc;
+
 #ifndef NOENCRYPTION
-    key_sched(key,key_s);
-    pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
-                (long) cip->length,key_s,(C_Block *)key,0);
+    key_sched(key, key_s);
+    pcbc_encrypt((C_Block *)cip->dat, (C_Block *)cip->dat,
+                (long)cip->length, key_s, (C_Block *)key, 0);
 #endif /* !NOENCRYPTION */
     /* Get rid of all traces of key */
-    memset((char *)key, 0,sizeof(key));
-    memset((char *)key_s, 0,sizeof(key_s));
+    memset(key, 0, sizeof(key));
+    memset(key_s, 0, sizeof(key_s));
 
-    return(0);
+    return 0;
 }
 
 /*
@@ -118,7 +127,7 @@ decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
 
 int
 krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
-                     preauth_p, preauth_len, cip)
+                     preauth_p, preauth_len, cip, byteorder)
     char *user;
     char *instance;
     char *realm;
@@ -128,13 +137,15 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
     char *preauth_p;
     int   preauth_len;
     KTEXT cip;
+    int  *byteorder;
 {
     KTEXT_ST pkt_st;
     KTEXT pkt = &pkt_st;       /* Packet to KDC */
     KTEXT_ST rpkt_st;
     KTEXT rpkt = &rpkt_st;     /* Returned packet */
-    unsigned char *v = pkt->dat; /* Prot vers no */
-    unsigned char *t = (pkt->dat+1); /* Prot msg type */
+    unsigned char *p;
+    size_t userlen, instlen, realmlen, servicelen, sinstlen;
+    unsigned KRB4_32 t_local;
 
     int msg_byte_order;
     int kerror;
@@ -142,112 +153,127 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
     unsigned long exp_date;
 #endif
     unsigned long rep_err_code;
+    unsigned long cip_len;
     unsigned int t_switch;
-    unsigned KRB4_32 t_local;  /* Must be 4 bytes long for memcpy below! */
+    int i, len;
 
     /* BUILD REQUEST PACKET */
 
-    /* Set up the fixed part of the packet */
-    *v = (unsigned char) KRB_PROT_VERSION;
-    *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
-    *t |= HOST_BYTE_ORDER;
+    p = pkt->dat;
 
+    userlen = strlen(user) + 1;
+    instlen = strlen(instance) + 1;
+    realmlen = strlen(realm) + 1;
+    servicelen = strlen(service) + 1;
+    sinstlen = strlen(sinstance) + 1;
     /* Make sure the ticket data will fit into the buffer. */
-    if(sizeof(pkt->dat) < 2 +                  /* protocol version + flags */
-                         3 + strlen(user) +
-                         1 + strlen(instance) +
-                         1 + strlen(realm) +
-                         4 +                   /* timestamp */
-                         1 +                   /* lifetime */
-                         1 + strlen(service) +
-                         1 + strlen(sinstance) +
-                         preauth_len) {
+    if (sizeof(pkt->dat) < (1 + 1 + userlen + instlen + realmlen
+                           + 4 + 1 + servicelen + sinstlen
+                           + preauth_len)) {
         pkt->length = 0;
        return INTK_ERR;
     }
 
+    /* Set up the fixed part of the packet */
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_KDC_REQUEST;
+
     /* Now for the variable info */
-    (void) strcpy((char *)(pkt->dat+2),user); /* aname */
-    pkt->length = 3 + strlen(user);
-    (void) strcpy((char *)(pkt->dat+pkt->length),
-                 instance);    /* instance */
-    pkt->length += 1 + strlen(instance);
-    (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
-    pkt->length += 1 + strlen(realm);
+    memcpy(p, user, userlen);
+    p += userlen;
+    memcpy(p, instance, instlen);
+    p += instlen;
+    memcpy(p, realm, realmlen);
+    p += realmlen;
 
     /* timestamp */
     t_local = TIME_GMT_UNIXSEC;
-    memcpy((char *)(pkt->dat+pkt->length), (char *)&t_local, 4);
-    pkt->length += 4;
+    KRB4_PUT32(p, t_local);
 
-    *(pkt->dat+(pkt->length)++) = (char) life;
-    (void) strcpy((char *)(pkt->dat+pkt->length),service);
-    pkt->length += 1 + strlen(service);
-    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+    *p++ = life;
 
-    pkt->length += 1 + strlen(sinstance);
+    memcpy(p, service, servicelen);
+    p += servicelen;
+    memcpy(p, sinstance, sinstlen);
+    p += sinstlen;
 
     if (preauth_len)
-       memcpy((char *)(pkt->dat+pkt->length), preauth_p, preauth_len);
-    pkt->length += preauth_len;
+       memcpy(p, preauth_p, (size_t)preauth_len);
+    p += preauth_len;
 
-    rpkt->length = 0;
+    pkt->length = p - pkt->dat;
 
     /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+    rpkt->length = 0;
+    kerror = send_to_kdc(pkt, rpkt, realm);
+    if (kerror)
+       return kerror;
 
-    if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+    p = rpkt->dat;
+#define RPKT_REMAIN (rpkt->length - (p - rpkt->dat))
 
     /* check packet version of the returned packet */
-    if (pkt_version(rpkt) != KRB_PROT_VERSION)
-        return(INTK_PROT);
-
-    /* Check byte order */
-    msg_byte_order = pkt_msg_type(rpkt) & 1;
-    swap_bytes = 0;
-    if (msg_byte_order != HOST_BYTE_ORDER) {
-        swap_bytes++;
-    }
+    if (RPKT_REMAIN < 1 + 1)
+       return INTK_PROT;
+    if (*p++ != KRB_PROT_VERSION)
+        return INTK_PROT;
 
     /* This used to be
          switch (pkt_msg_type(rpkt) & ~1) {
        but SCO 3.2v4 cc compiled that incorrectly.  */
-    t_switch = pkt_msg_type(rpkt);
+    t_switch = *p++;
+    /* Check byte order */
+    msg_byte_order = t_switch & 1;
     t_switch &= ~1;
     switch (t_switch) {
     case AUTH_MSG_KDC_REPLY:
         break;
     case AUTH_MSG_ERR_REPLY:
-        memcpy((char *) &rep_err_code, pkt_err_code(rpkt), 4);
-        if (swap_bytes) rep_err_code = krb4_swab32(rep_err_code);
-        return((int)rep_err_code);
+       if (RPKT_REMAIN < 4)
+           return INTK_PROT;
+       KRB4_GET32(rep_err_code, p, msg_byte_order);
+       return rep_err_code;
     default:
-        return(INTK_PROT);
+        return INTK_PROT;
     }
 
     /* EXTRACT INFORMATION FROM RETURN PACKET */
 
-#if 0
-    /* not used */
-    /* get the principal's expiration date */
-    memcpy((char *) &exp_date, pkt_x_date(rpkt), sizeof(exp_date));
-    if (swap_bytes) exp_data = krb4_swab32(exp_date);
-#endif
+    /*
+     * Skip over some stuff (3 strings and various integers -- see
+     * cr_auth_repl.c for details).
+     */
+    for (i = 0; i < 3; i++) {
+       len = krb_strnlen((char *)p, RPKT_REMAIN) + 1;
+       if (len <= 0)
+           return INTK_PROT;
+       p += len;
+    }
+    if (RPKT_REMAIN < 4 + 1 + 4 + 1)
+       return INTK_PROT;
+    p += 4 + 1 + 4 + 1;
 
     /* Extract the ciphertext */
-    cip->length = pkt_clen(rpkt);       /* let clen do the swap */
-
-    if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
-       return(INTK_ERR);               /* no appropriate error code
-                                          currently defined for INTK_ */
-    /* copy information from return packet into "cip" */
-    memcpy((char *)(cip->dat), (char *) pkt_cipher(rpkt), cip->length);
-
+    if (RPKT_REMAIN < 2)
+       return INTK_PROT;
+    KRB4_GET16(cip_len, p, msg_byte_order);
+    if (RPKT_REMAIN < cip_len)
+       return INTK_ERR;
+    /*
+     * RPKT_REMAIN will always be non-negative and at most the maximum
+     * possible value of cip->length, so this assignment is safe.
+     */
+    cip->length = cip_len;
+    memcpy(cip->dat, p, (size_t)cip->length);
+    p += cip->length;
+
+    *byteorder = msg_byte_order;
     return INTK_OK;
 }
 
-
 int
-krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
+krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip,
+                byteorder)
     char *user;
     char *instance;
     char *realm;
@@ -255,9 +281,11 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
     char *sinstance;
     int life;
     KTEXT cip;
+    int byteorder;
 {
-    char *ptr;
+    unsigned char *ptr;
     C_Block ses;                /* Session key for tkt */
+    int len;
     int kvno;                  /* Kvno for session key */
     char s_name[SNAME_SZ];
     char s_instance[INST_SZ];
@@ -270,79 +298,80 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
     int kerror;
     int lifetime;
 
-    ptr = (char *) cip->dat;
+    ptr = cip->dat;
+    /* Assume that cip->length >= 0 for now. */
+#define CIP_REMAIN (cip->length - (ptr - cip->dat))
 
-    /* extract session key */
-    memcpy((char *)ses, ptr, 8);
+    /* Skip session key for now */
+    if (CIP_REMAIN < 8)
+       return INTK_BADPW;
     ptr += 8;
 
-    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
-       return(INTK_BADPW);
-
     /* extract server's name */
-    (void) strncpy(s_name,ptr, sizeof(s_name)-1);
-    s_name[sizeof(s_name)-1] = '\0';
-    ptr += strlen(s_name) + 1;
-
-    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
-       return(INTK_BADPW);
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > sizeof(s_name))
+       return INTK_BADPW;
+    memcpy(s_name, ptr, (size_t)len);
+    ptr += len;
 
     /* extract server's instance */
-    (void) strncpy(s_instance,ptr, sizeof(s_instance)-1);
-    s_instance[sizeof(s_instance)-1] = '\0';
-    ptr += strlen(s_instance) + 1;
-
-    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
-       return(INTK_BADPW);
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > sizeof(s_instance))
+       return INTK_BADPW;
+    memcpy(s_instance, ptr, (size_t)len);
+    ptr += len;
 
     /* extract server's realm */
-    (void) strncpy(rlm,ptr, sizeof(rlm));
-    rlm[sizeof(rlm)-1] = '\0';
-    ptr += strlen(rlm) + 1;
+    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    if (len <= 0 || len > sizeof(rlm))
+       return INTK_BADPW;
+    memcpy(rlm, ptr, (size_t)len);
+    ptr += len;
 
     /* extract ticket lifetime, server key version, ticket length */
     /* be sure to avoid sign extension on lifetime! */
-    lifetime = (unsigned char) ptr[0];
-    kvno = (unsigned char) ptr[1];
-    tkt->length = (unsigned char) ptr[2];
-    ptr += 3;
-    
-    if ((tkt->length < 0) ||
-       ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
-       return(INTK_BADPW);
+    if (CIP_REMAIN < 3)
+       return INTK_BADPW;
+    lifetime = *ptr++;
+    kvno = *ptr++;
+    tkt->length = *ptr++;
 
     /* extract ticket itself */
-    memcpy((char *)(tkt->dat), ptr, tkt->length);
+    if (CIP_REMAIN < tkt->length)
+       return INTK_BADPW;
+    memcpy(tkt->dat, ptr, (size_t)tkt->length);
     ptr += tkt->length;
 
-    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
-        strcmp(rlm, realm))    /* not what we asked for */
-       return(INTK_ERR);       /* we need a better code here XXX */
+    if (strcmp(s_name, service) || strcmp(s_instance, sinstance)
+       || strcmp(rlm, realm))  /* not what we asked for */
+       return INTK_ERR;        /* we need a better code here XXX */
 
     /* check KDC time stamp */
-    memcpy((char *)&kdc_time, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) kdc_time = krb4_swab32(kdc_time);
-
-    ptr += 4;
+    if (CIP_REMAIN < 4)
+       return INTK_BADPW;
+    KRB4_GET32(kdc_time, ptr, byteorder);
 
     t_local = TIME_GMT_UNIXSEC;
     t_diff = t_local - kdc_time;
-    if (t_diff < 0) t_diff = -t_diff;  /* Absolute value of difference */
+    if (t_diff < 0)
+       t_diff = -t_diff;       /* Absolute value of difference */
     if (t_diff > CLOCK_SKEW) {
-        return(RD_AP_TIME);            /* XXX should probably be better
-                                          code */
+        return RD_AP_TIME;     /* XXX should probably be better code */
     }
 
     /* initialize ticket cache */
     if (in_tkt(user,instance) != KSUCCESS)
-       return(INTK_ERR);
-
+       return INTK_ERR;
     /* stash ticket, session key, etc. for future use */
-    if (kerror = krb_save_credentials(s_name, s_instance, rlm, ses,
-                                     lifetime, kvno, tkt, t_local))
-       return(kerror);
+    memcpy(ses, cip->dat, 8);
+    kerror = krb_save_credentials(s_name, s_instance, rlm, ses,
+                                 lifetime, kvno,
+                                 tkt, (KRB4_32)t_local);
+    memset(ses, 0, 8);
+    if (kerror)
+       return kerror;
 
-    return(INTK_OK);
+    return INTK_OK;
 }
 
 int
@@ -363,21 +392,26 @@ krb_get_in_tkt_preauth(user, instance, realm, service, sinstance, life,
     KTEXT_ST cip_st;
     KTEXT cip = &cip_st;       /* Returned Ciphertext */
     int kerror;
-    if (kerror = krb_mk_in_tkt_preauth(user, instance, realm, 
-                                      service, sinstance,
-                                      life, preauth_p, preauth_len, cip))
-       return kerror;
+    int byteorder;
 
+    kerror = krb_mk_in_tkt_preauth(user, instance, realm, 
+                                  service, sinstance,
+                                  life, preauth_p, preauth_len,
+                                  cip, &byteorder);
+    if (kerror)
+       return kerror;
     /* Attempt to decrypt the reply. */
     if (decrypt_proc == NULL)
        decrypt_tkt (user, instance, realm, arg, key_proc, &cip);
     else
        (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
-    
-    return
-       krb_parse_in_tkt(user, instance, realm, service, sinstance, 
-                        life, cip);
 
+    kerror = krb_parse_in_tkt(user, instance, realm,
+                             service, sinstance,
+                             life, cip, byteorder);
+    /* stomp stomp stomp */
+    memset(cip->dat, 0, (size_t)cip->length);
+    return kerror;
 }
 
 int
@@ -395,7 +429,6 @@ krb_get_in_tkt(user, instance, realm, service, sinstance, life,
 {
     return krb_get_in_tkt_preauth(user, instance, realm,
                                  service, sinstance, life,
-                                 key_proc, decrypt_proc, arg, (char *)0, 0);
-
+                                 key_proc, decrypt_proc, arg,
+                                 (char *)NULL, 0);
 }
-
index 45952c0f202f9381b0d32e5c62bed4af89413333..45415fed333756bca2426bb9909fded785a42d98 100644 (file)
@@ -1,16 +1,31 @@
 /*
- * mk_auth.c
+ * lib/krb4/mk_auth.c
  *
- * CopKRB4_32right 1987, 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  *
  * Derived from sendauth.c by John Gilmore, 10 October 1994.
  */
 
-#include "mit-copyright.h"
-
 #define        DEFINE_SOCKADDR         /* Ask for sockets declarations from krb.h. */
 #include <stdio.h>
 #include "krb.h"
@@ -110,30 +125,35 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
      char FAR *version;                /* version string */
      KTEXT buf;                        /* Output buffer to fill  */
 {
-    int rem, i;
+    int rem;
     char krb_realm[REALM_SZ];
-    KRB4_32 tkt_len;
+    char *phost;
+    int phostlen;
+    unsigned char *p;
 
-    rem=KSUCCESS;
+    rem = KSUCCESS;
 
     /* get current realm if not passed in */
     if (!realm) {
        rem = krb_get_lrealm(krb_realm,1);
        if (rem != KSUCCESS)
-           return(rem);
+           return rem;
        realm = krb_realm;
     }
 
     if (!(options & KOPT_DONT_CANON)) {
-       (void) strncpy(inst, krb_get_phost(inst), INST_SZ - 1);
-       inst[INST_SZ-1] = 0;
+       phost = krb_get_phost(inst);
+       phostlen = krb_strnlen(phost, INST_SZ) + 1;
+       if (phostlen <= 0 || phostlen > INST_SZ)
+           return KFAILURE;
+       memcpy(inst, phost, (size_t)phostlen);
     }
 
     /* get the ticket if desired */
     if (!(options & KOPT_DONT_MK_REQ)) {
-       rem = krb_mk_req(ticket, service, inst, realm, checksum);
+       rem = krb_mk_req(ticket, service, inst, realm, (KRB4_32)checksum);
        if (rem != KSUCCESS)
-           return(rem);
+           return rem;
     }
 
 #ifdef ATHENA_COMPAT
@@ -146,32 +166,33 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
     }
 #endif /* ATHENA_COMPAT */
 
+    /* Check buffer size */
+    if (sizeof(buf->dat) < (KRB_SENDAUTH_VLEN + KRB_SENDAUTH_VLEN
+                           + 4 + ticket->length)
+       || ticket->length < 0)
+       return KFAILURE;
+
     /* zero the buffer */
-    (void) memset(buf->dat, 0, MAX_KTXT_LEN);
+    memset(buf->dat, 0, sizeof(buf->dat));
+    p = buf->dat;
 
     /* insert version strings */
-    (void) strncpy((char *)buf->dat, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
-    (void) strncpy((char *)buf->dat+KRB_SENDAUTH_VLEN, version,
-               KRB_SENDAUTH_VLEN);
-
-    /* increment past vers strings */
-    i = 2*KRB_SENDAUTH_VLEN;
+    strncpy((char *)p, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+    p += KRB_SENDAUTH_VLEN;
+    strncpy((char *)p, version, KRB_SENDAUTH_VLEN);
+    p += KRB_SENDAUTH_VLEN;
 
     /* put ticket length into buffer */
-    tkt_len = htonl((unsigned KRB4_32) ticket->length);
-    (void) memcpy(buf->dat+i, (char *) &tkt_len, sizeof(tkt_len));
-    i += sizeof(tkt_len);
+    KRB4_PUT32(p, ticket->length);
 
     /* put ticket into buffer */
-    (void) memcpy(buf->dat+i, (char *) ticket->dat, ticket->length);
-    i += ticket->length;
+    memcpy(p, ticket->dat, (size_t)ticket->length);
+    p += ticket->length;
 
-    buf->length = i;
+    buf->length = p - buf->dat;
     return KSUCCESS;
 }
 
-
-
 /*
  * For mutual authentication using mk_auth, check the server's response
  * to validate that we're really talking to the server which holds the
@@ -199,22 +220,31 @@ krb_check_auth (buf, checksum, msg_data, session, schedule, laddr, faddr)
 {
     int cc;
     unsigned KRB4_32 cksum;
+    unsigned char *p;
 
     /* decrypt it */
 #ifndef NOENCRYPTION
     key_sched(session, schedule);
 #endif /* !NOENCRYPTION */
-    if (cc = krb_rd_priv(buf->dat, buf->length, schedule,
-                        (C_Block *)session, faddr, laddr, msg_data))
-       return(cc);
-
-    /* fetch the (incremented) checksum that we supplied in the request */
-    (void) memcpy((char *)&cksum, (char *)msg_data->app_data, 
-                 sizeof(cksum));
-    cksum = ntohl(cksum);
+    if (buf->length < 0)
+       return KFAILURE;
+    cc = krb_rd_priv(buf->dat, (unsigned KRB4_32)buf->length, schedule,
+                    (C_Block *)session, faddr, laddr, msg_data);
+    memset(schedule, 0, sizeof(schedule));
+    if (cc)
+       return cc;
+
+    /*
+     * Fetch the (incremented) checksum that we supplied in the
+     * request.
+     */
+    if (msg_data->app_length < 4)
+       return KFAILURE;
+    p = msg_data->app_data;
+    KRB4_GET32BE(cksum, p);
 
     /* if it doesn't match, fail -- reply wasn't from our real server.  */
     if (cksum != checksum + 1)
-       return(KFAILURE);        /* XXX */
-    return(KSUCCESS);
+       return KFAILURE;        /* XXX */
+    return KSUCCESS;
 }
index 029aa9f9c70e1c4ddca8d65bfaaa0ccb292e246d..8fcb2ed21b1efb4c65f6460a0034d90f35c240e0 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * mk_err.c
+ * lib/krb4/mk_err.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "krb.h"
 #include "prot.h"
 #include <string.h>
  */
 
 KRB5_DLLIMP long KRB5_CALLCONV
-krb_mk_err(p,e,e_string)
+krb_mk_err(p, e, e_string)
     u_char FAR *p;             /* Where to build error packet */
     KRB4_32 e;                 /* Error code */
     char FAR *e_string;                /* Text of error */
 {
     u_char      *start;
+    size_t     e_len;
+
+    e_len = strlen(e_string) + 1;
 
     /* Just return the buffer length if p is NULL, because writing to the
      * buffer would be a bad idea.  Note that this feature is a change from
      * previous versions, and can therefore only be used safely in this
      * source tree, where we know this function supports it. */
-    if(p == NULL) {
-        return 2 + sizeof(e) + strlen(e_string);
+    if (p == NULL) {
+        return 1 + 1 + 4 + e_len;
     }
 
     start = p;
 
     /* Create fixed part of packet */
-    *p++ = (unsigned char) KRB_PROT_VERSION;
-    *p = (unsigned char) AUTH_MSG_APPL_ERR;
-    *p++ |= HOST_BYTE_ORDER;
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_APPL_ERR;
 
     /* Add the basic info */
-    memcpy((char *)p, (char *)&e, 4); /* err code */
-    p += sizeof(e);
-    (void) strcpy((char *)p,e_string); /* err text */
-    p += strlen(e_string);
+    KRB4_PUT32(p, e);
+    memcpy(p, e_string, e_len); /* err text */
+    p += e_len;
 
     /* And return the length */
-    return p-start;
+    return p - start;
 }
index 949fd1d2538d53c0ef74fd4bd611a5fe741d300c..5295b22552300a26080033b04b47b453d733cb58 100644 (file)
 extern char *malloc(), *calloc(), *realloc();
 #endif
 
-
 int
 krb_mk_preauth(preauth_p, preauth_len,
-              key_proc,aname,inst,realm,password,key)
+              key_proc, aname, inst, realm, password, key)
     char **preauth_p;
     int  *preauth_len;
     key_proc_type key_proc;
@@ -35,15 +34,15 @@ krb_mk_preauth(preauth_p, preauth_len,
     C_Block key;
 {
 #ifdef NOENCRYPTION
-    *preauth_len = strlen(aname)+1;    /* include the trailing 0 */
+    *preauth_len = strlen(aname) + 1; /* include the trailing 0 */
     *preauth_p = malloc(*preauth_len);
-    strcpy(*preauth_p, aname);         /* this will copy the trailing 0 */
+    strcpy(*preauth_p, aname); /* this will copy the trailing 0 */
 #else
     des_key_schedule key_s;
     int sl = strlen(aname);
 #endif
 
-    (*key_proc)(aname,inst,realm,password,key);
+    (*key_proc)(aname, inst, realm, password, key);
 
 #ifndef NOENCRYPTION
     /* 
@@ -52,17 +51,18 @@ krb_mk_preauth(preauth_p, preauth_len,
      */
     *preauth_len = (((sl + 1) / 8) + 1) * 8;
     /* allocate memory for preauth_p and fill it with 0 */
-    *preauth_p = (char*) malloc(*preauth_len);
+    *preauth_p = malloc((size_t)*preauth_len);
     /* create the key schedule */
     if (des_key_sched(key, key_s)) {
-      return 1;
+       return 1;
     }
     /* 
      * encrypt aname using key_s as the key schedule and key as the
      * initialization vector.
      */
-    des_pcbc_encrypt((des_cblock *) aname, (des_cblock *) *preauth_p,
-                    (long) (sl + 1), key_s, (des_cblock *) key, DES_ENCRYPT);
+    des_pcbc_encrypt((des_cblock *)aname, (des_cblock *)*preauth_p,
+                    (long)(sl + 1), key_s, (des_cblock *)key, DES_ENCRYPT);
+    memset(key_s, 0, sizeof(key_s));
 #endif
     return 0;
 }
@@ -72,6 +72,6 @@ krb_free_preauth(preauth_p, preauth_len)
      char *preauth_p;
      int preauth_len;
 {
-  free(preauth_p);
-  return;
+    free(preauth_p);
+    return;
 }
index e8ce33358ff156d413d8892d202508b5c9a83e00..0c355480850985d64c1ed9fdb9082e43030d103f 100644 (file)
@@ -1,11 +1,27 @@
 /*
- * mk_priv.c
+ * lib/krb4/mk_priv.c
  *
- * CopKRB4_32right 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  *
  * This routine constructs a Kerberos 'private msg', i.e.
  * cryptographically sealed with a private session key.
@@ -15,8 +31,6 @@
  * Steve Miller    Project Athena  MIT/DEC
  */
 
-#include "mit-copyright.h"
-
 #include <stdio.h>
 #include <string.h>
 
@@ -80,7 +94,7 @@ extern int krb_debug;
  */
 
 KRB5_DLLIMP long KRB5_CALLCONV
-krb_mk_priv(in,out,length,schedule,key,sender,receiver)
+krb_mk_priv(in, out, length, schedule, key, sender, receiver)
     u_char FAR *in;            /* application data */
     u_char FAR *out;           /* put msg here, leave room for
                                 * header! breaks if in and out
@@ -95,27 +109,31 @@ krb_mk_priv(in,out,length,schedule,key,sender,receiver)
     u_char *c_length_ptr;
     extern int private_msg_ver; /* in krb_rd_priv.c */
 
-    unsigned KRB4_32 c_length;
+    unsigned KRB4_32 c_length, c_length_raw;
     u_char msg_time_5ms;
     unsigned KRB4_32 msg_time_sec;
     unsigned KRB4_32 msg_time_usec;
 
+    /* Be really paranoid. */
+    if (sizeof(sender->sin_addr.s_addr) != 4)
+       return -1;
     /*
      * get the current time to use instead of a sequence #, since
      * process lifetime may be shorter than the lifetime of a session
      * key.
      */
-    msg_time_sec = TIME_GMT_UNIXSEC_US (&msg_time_usec);
-    msg_time_5ms = msg_time_usec/5000; /* 5ms quanta */
+    msg_time_sec = TIME_GMT_UNIXSEC_US(&msg_time_usec);
+    msg_time_5ms = msg_time_usec / 5000; /* 5ms quanta */
 
     p = out;
 
-    *p++ = private_msg_ver?private_msg_ver:KRB_PROT_VERSION;
-    *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+    /* Cruftiness below! */
+    *p++ = private_msg_ver ? private_msg_ver : KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_PRIVATE;
 
-    /* calculate cipher length */
+    /* save ptr to cipher length */
     c_length_ptr = p;
-    p += sizeof(c_length);
+    p += 4;
 
 #ifndef NOENCRYPTION
     /* start for encrypted stuff */
@@ -123,23 +141,21 @@ krb_mk_priv(in,out,length,schedule,key,sender,receiver)
     q = p;
 
     /* stuff input length */
-    memcpy((char *)p, (char *)&length, sizeof(length));
-    p += sizeof(length);
+    KRB4_PUT32(p, length);
 
 #ifdef NOENCRYPTION
     /* make all the stuff contiguous for checksum */
 #else
     /* make all the stuff contiguous for checksum and encryption */
 #endif
-    memcpy((char *)p, (char *)in, (int) length);
+    memcpy(p, in, (size_t)length);
     p += length;
 
     /* stuff time 5ms */
-    memcpy((char *)p, (char *)&msg_time_5ms, sizeof(msg_time_5ms));
-    p += sizeof(msg_time_5ms);
+    *p++ = msg_time_5ms;
 
     /* stuff source address */
-    memcpy((char *)p, (char *)&sender->sin_addr.s_addr, 
+    memcpy(p, &sender->sin_addr.s_addr,
           sizeof(sender->sin_addr.s_addr));
     p += sizeof(sender->sin_addr.s_addr);
 
@@ -150,15 +166,15 @@ krb_mk_priv(in,out,length,schedule,key,sender,receiver)
     /* For compatibility with broken old code, compares are done in VAX 
        byte order (LSBFIRST) */ 
     if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ 
-                         receiver->sin_addr.s_addr)==-1) 
-        msg_time_sec =  -msg_time_sec; 
-    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
-                               receiver->sin_addr.s_addr)==0) 
-        if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) 
-            msg_time_sec = -msg_time_sec; 
+                         receiver->sin_addr.s_addr) == -1)
+        msg_time_sec = -msg_time_sec;
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+                               receiver->sin_addr.s_addr) == 0)
+        if (lsb_net_ushort_less(sender->sin_port,
+                               receiver->sin_port) == -1)
+            msg_time_sec = -msg_time_sec;
     /* stuff time sec */
-    memcpy((char *)p, (char *)&msg_time_sec, sizeof(msg_time_sec));
-    p += sizeof(msg_time_sec);
+    KRB4_PUT32(p, msg_time_sec);
 
     /*
      * All that for one tiny bit!  Heaven help those that talk to
@@ -170,10 +186,10 @@ krb_mk_priv(in,out,length,schedule,key,sender,receiver)
      * calculate the checksum of the length, address, sequence, and
      * inp data
      */
-    cksum =  quad_cksum(q,NULL,p-q,0,key);
+    cksum = quad_cksum(q,NULL,p-q,0,key);
     DEB (("\ncksum = %u",cksum));
     /* stuff checksum */
-    memcpy((char *) p, (char *) &cksum, sizeof(cksum));
+    memcpy(p, &cksum, sizeof(cksum));
     p += sizeof(cksum);
 #endif
 
@@ -189,17 +205,18 @@ krb_mk_priv(in,out,length,schedule,key,sender,receiver)
      */
 #endif
 
-    c_length = p - q;
-    c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
-        sizeof(C_Block);
+    c_length_raw = p - q;
+    c_length = ((c_length_raw + sizeof(C_Block) -1)
+               / sizeof(C_Block)) * sizeof(C_Block);
     /* stuff the length */
-    memcpy((char *)c_length_ptr, (char *) &c_length, sizeof(c_length));
+    p = c_length_ptr;
+    KRB4_PUT32(p, c_length);
 
 #ifndef NOENCRYPTION
     /* pcbc encrypt, pad as needed, use key as ivec */
-    pcbc_encrypt((C_Block *) q,(C_Block *) q, (long) (p-q), schedule,
-                 key, ENCRYPT);
+    pcbc_encrypt((C_Block *)q,(C_Block *)q, (long)c_length_raw,
+                schedule, key, ENCRYPT);
 #endif /* NOENCRYPTION */
 
-    return (q - out + c_length);        /* resulting size */
+    return q - out + c_length; /* resulting size */
 }
index 468dccdb6df5d673aa304cb293861cbdffc6f1aa..2d5d240efcf05be67d3c6c7a282ba78813996022 100644 (file)
@@ -1,15 +1,30 @@
 /*
- * mk_req.c
+ * lib/krb4/mk_req.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
 #define        DEFINE_SOCKADDR
-#include "mit-copyright.h"
 #include "krb.h"
 #include "prot.h"
 #include "des.h"
@@ -69,7 +84,7 @@ static int lifetime = 255;            /* Default based on the TGT */
  */
 
 KRB5_DLLIMP int KRB5_CALLCONV
-krb_mk_req(authent,service,instance,realm,checksum)
+krb_mk_req(authent, service, instance, realm, checksum)
     register   KTEXT authent;  /* Place to build the authenticator */
     char       FAR *service;   /* Name of the service */
     char       FAR *instance;  /* Service instance */
@@ -78,36 +93,27 @@ krb_mk_req(authent,service,instance,realm,checksum)
 {
     KTEXT_ST req_st; /* Temp storage for req id */
     KTEXT req_id = &req_st;
-    unsigned char *v = authent->dat; /* Prot version number */
-    unsigned char *t = (authent->dat+1); /* Message type */
-    unsigned char *kv = (authent->dat+2); /* Key version no */
-    unsigned char *tl;         /* Tkt len */
-    unsigned char *idl;                /* Reqid len */
+    unsigned char *p, *q, *reqid_lenp;
+    int tl;                    /* Tkt len */
+    int idl;                   /* Reqid len */
     CREDENTIALS cr;             /* Credentials used by retr */
     register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
     int retval;                 /* Returned by krb_get_cred */
     Key_schedule  key_s;
     char krb_realm[REALM_SZ];  /* Our local realm, if not specified */
     char myrealm[REALM_SZ];    /* Realm of our TGT */
+    size_t realmlen, pnamelen, pinstlen, myrealmlen;
     unsigned KRB4_32 time_secs;
     unsigned KRB4_32 time_usecs;
 
-    /* The fixed parts of the authenticator */
-    *v = (unsigned char) KRB_PROT_VERSION;
-    *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
-    *t |= HOST_BYTE_ORDER;
-
     /* get current realm if not passed in */
-    if (!realm) {
-       retval = krb_get_lrealm(krb_realm,1);
+    if (realm == NULL) {
+       retval = krb_get_lrealm(krb_realm, 1);
        if (retval != KSUCCESS)
-           return(retval);
+           return retval;
        realm = krb_realm;
     }
 
-    tl = (authent->dat+4+strlen(realm)); /* Tkt len */
-    idl = (authent->dat+5+strlen(realm)); /* Reqid len */
-
     /* Get the ticket and move it into the authenticator */
     if (krb_ap_req_debug)
         DEB (("Realm: %s\n",realm));
@@ -116,97 +122,121 @@ krb_mk_req(authent,service,instance,realm,checksum)
      * KDC from which we are requesting tickets so it knows what to
      * with our session key.
      */
-    if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
-       return(retval);
-    
-    retval = krb_get_cred(service,instance,realm,&cr);
+    retval = krb_get_tf_realm(TKT_FILE, myrealm);
+    if (retval != KSUCCESS)
+       return retval;
 
+    retval = krb_get_cred(service, instance, realm, &cr);
     if (retval == RET_NOTKT) {
-        if (retval = get_ad_tkt(service,instance,realm,lifetime))
-            return(retval);
-        if (retval = krb_get_cred(service,instance,realm,&cr))
-           return(retval);
+       retval = get_ad_tkt(service, instance, realm, lifetime);
+        if (retval)
+            return retval;
+       retval = krb_get_cred(service, instance, realm, &cr);
+        if (retval)
+           return retval;
     }
+    if (retval != KSUCCESS)
+       return retval;
 
-    if (retval != KSUCCESS) return (retval);
-
-    if(sizeof(authent->dat) / 8 < (3 +
-                                  strlen(realm) + 1 + 2 +
-                                  3 + ticket->length +
-                                  strlen(cr.pname) + 1 +
-                                  strlen(cr.pinst) + 1 +
-                                  strlen(myrealm) + 1 +
-                                  4 +                          /* checksum */
-                                  4 +                          /* timestamp */
-                                  7) / 8) {                    /* round-up */
-           authent->length = 0;
-           return KFAILURE;
+    realmlen = strlen(realm) + 1;
+    if (sizeof(authent->dat) < (1 + 1 + 1
+                               + realmlen
+                               + 1 + 1 + ticket->length)
+       || ticket->length < 0 || ticket->length > 255) {
+       authent->length = 0;
+       memset(cr.session, 0, sizeof(cr.session));
+       return KFAILURE;
     }
 
     if (krb_ap_req_debug)
         DEB (("%s %s %s %s %s\n", service, instance, realm,
                cr.pname, cr.pinst));
-    *kv = (unsigned char) cr.kvno;
-    (void) strcpy((char *)(authent->dat+3),realm);
-    *tl = (unsigned char) ticket->length;
-    memcpy((char *)(authent->dat+6+strlen(realm)), (char *)(ticket->dat), 
-          ticket->length);
-    authent->length = 6 + strlen(realm) + ticket->length;
+
+    p = authent->dat;
+
+    /* The fixed parts of the authenticator */
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_APPL_REQUEST;
+    *p++ = cr.kvno;
+
+    memcpy(p, realm, realmlen);
+    p += realmlen;
+
+    tl = ticket->length;
+    *p++ = tl;
+    /* Save ptr to where req_id->length goes. */
+    reqid_lenp = p;
+    p++;
+    memcpy(p, ticket->dat, (size_t)tl);
+    p += tl;
+
     if (krb_ap_req_debug)
         DEB (("Ticket->length = %d\n",ticket->length));
     if (krb_ap_req_debug)
         DEB (("Issue date: %d\n",cr.issue_date));
 
+    pnamelen = strlen(cr.pname) + 1;
+    pinstlen = strlen(cr.pinst) + 1;
+    myrealmlen = strlen(myrealm) + 1;
+    if (sizeof(req_id->dat) / 8 < (pnamelen + pinstlen + myrealmlen
+                                  + 4 + 1 + 4 + 7) / 8) {
+       memset(cr.session, 0, sizeof(cr.session));
+       return KFAILURE;
+    }
+
+    q = req_id->dat;
+
     /* Build request id */
-    (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
-    req_id->length = strlen(cr.pname)+1;
+    /* Auth name */
+    memcpy(q, cr.pname, pnamelen);
+    q += pnamelen;
     /* Principal's instance */
-    (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
-    req_id->length += strlen(cr.pinst)+1;
+    memcpy(q, cr.pinst, pinstlen);
+    q += pinstlen;    
     /* Authentication domain */
-    (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
-    req_id->length += strlen(myrealm)+1;
+    memcpy(q, myrealm, myrealmlen);
+    q += myrealmlen;
     /* Checksum */
-    memcpy((char *)(req_id->dat+req_id->length), (char *)&checksum, 4);
-    req_id->length += 4;
+    KRB4_PUT32(q, checksum);
 
     /* Fill in the times on the request id */
-       
     time_secs = TIME_GMT_UNIXSEC_US (&time_usecs);
-    *(req_id->dat+(req_id->length)++) =
-        (unsigned char) time_usecs;
+    *q++ = time_usecs;         /* time_usecs % 255 */
     /* Time (coarse) */
-    memcpy((char *)(req_id->dat+req_id->length), 
-          (char *) &time_secs , 4);
-    req_id->length += 4;
+    KRB4_PUT32(q, time_secs);
 
     /* Fill to a multiple of 8 bytes for DES */
-    req_id->length = ((req_id->length+7)/8)*8;
+    req_id->length = ((q - req_id->dat + 7) / 8) * 8;
 
 #ifndef NOENCRYPTION
     /* Encrypt the request ID using the session key */
-    key_sched(cr.session,key_s);
-    pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
-                 (long) req_id->length,key_s, &cr.session,1);
+    key_sched(cr.session, key_s);
+    pcbc_encrypt((C_Block *)req_id->dat, (C_Block *)req_id->dat,
+                 (long)req_id->length, key_s, &cr.session, 1);
     /* clean up */
-    memset((char *) key_s, 0, sizeof(key_s));
+    memset(key_s, 0, sizeof(key_s));
+    memset(cr.session, 0, sizeof(cr.session));
 #endif /* NOENCRYPTION */
 
     /* Copy it into the authenticator */
-    memcpy((char *)(authent->dat+authent->length), (char *)(req_id->dat), 
-          req_id->length);
-    authent->length += req_id->length;
-    /* And set the id length */
-    *idl = (unsigned char) req_id->length;
+    idl = req_id->length;
+    if (idl > 255)
+       return KFAILURE;
+    *reqid_lenp = idl;
+    memcpy(p, req_id->dat, (size_t)idl);
+    p += idl;
+
+    authent->length = p - authent->dat;
+
     /* clean up */
-    memset((char *)req_id, 0, sizeof(*req_id));
+    memset(req_id, 0, sizeof(*req_id));
 
     if (krb_ap_req_debug)
         DEB (("Authent->length = %d\n",authent->length));
     if (krb_ap_req_debug)
-        DEB (("idl = %d, tl = %d\n",(int) *idl, (int) *tl));
+        DEB (("idl = %d, tl = %d\n", idl, tl));
 
-    return(KSUCCESS);
+    return KSUCCESS;
 }
 
 /* 
@@ -223,5 +253,5 @@ int newval;
     int olife = lifetime;
 
     lifetime = newval;
-    return(olife);
+    return olife;
 }
index 5d810ea50a2eab3a5c45a1a6d05d1742be12de00..1efff995359b3006c29bdfd998128b1f3aefd91c 100644 (file)
@@ -1,11 +1,27 @@
 /*
- * mk_safe.c
+ * lib/krb4/mk_req.c
  *
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  *
  * This routine constructs a Kerberos 'safe msg', i.e. authenticated
  * using a private session key to seed a checksum. Msg is NOT
@@ -16,7 +32,6 @@
  * Steve Miller    Project Athena  MIT/DEC
  */
 
-#include "mit-copyright.h"
 #include <stdio.h>
 #include <string.h>
 
@@ -61,7 +76,7 @@ extern int krb_debug;
  */
 
 KRB5_DLLIMP long KRB5_CALLCONV
-krb_mk_safe(in,out,length,key,sender,receiver)
+krb_mk_safe(in, out, length, key, sender, receiver)
     u_char *in;                        /* application data */
     u_char *out;               /*
                                 * put msg here, leave room for header!
@@ -81,37 +96,38 @@ krb_mk_safe(in,out,length,key,sender,receiver)
     unsigned KRB4_32 msg_usecs;
     u_char msg_time_5ms;
     KRB4_32 msg_time_sec;
+    int i;
 
+    /* Be really paranoid. */
+    if (sizeof(sender->sin_addr.s_addr) != 4)
+       return -1;
     /*
      * get the current time to use instead of a sequence #, since
      * process lifetime may be shorter than the lifetime of a session
      * key.
      */
-        
     msg_secs = TIME_GMT_UNIXSEC_US(&msg_usecs);
     msg_time_sec = msg_secs;
-    msg_time_5ms = msg_usecs/5000; /* 5ms quanta */
+    msg_time_5ms = msg_usecs / 5000; /* 5ms quanta */
 
     p = out;
 
     *p++ = KRB_PROT_VERSION;
-    *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+    *p++ = AUTH_MSG_SAFE;
 
     q = p;                     /* start for checksum stuff */
     /* stuff input length */
-    memcpy((char *)p, (char *)&length, sizeof(length));
-    p += sizeof(length);
+    KRB4_PUT32(p, length);
 
     /* make all the stuff contiguous for checksum */
-    memcpy((char *)p, (char *)in, (int) length);
+    memcpy(p, in, length);
     p += length;
 
     /* stuff time 5ms */
-    memcpy((char *)p, (char *)&msg_time_5ms, sizeof(msg_time_5ms));
-    p += sizeof(msg_time_5ms);
+    *p++ = msg_time_5ms;
 
     /* stuff source address */
-    memcpy((char *)p, (char *) &sender->sin_addr.s_addr, 
+    memcpy(p, &sender->sin_addr.s_addr,
           sizeof(sender->sin_addr.s_addr));
     p += sizeof(sender->sin_addr.s_addr);
 
@@ -122,34 +138,34 @@ krb_mk_safe(in,out,length,key,sender,receiver)
     /* For compatibility with broken old code, compares are done in VAX 
        byte order (LSBFIRST) */ 
     if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ 
-                         receiver->sin_addr.s_addr)==-1) 
-        msg_time_sec =  -msg_time_sec; 
-    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
-                               receiver->sin_addr.s_addr)==0) 
-        if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) 
-            msg_time_sec = -msg_time_sec; 
+                          receiver->sin_addr.s_addr) == -1)
+        msg_time_sec = -msg_time_sec;
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+                               receiver->sin_addr.s_addr) == 0)
+        if (lsb_net_ushort_less(sender->sin_port,
+                               receiver->sin_port) == -1)
+            msg_time_sec = -msg_time_sec;
     /*
      * all that for one tiny bit!  Heaven help those that talk to
      * themselves.
      */
 
     /* stuff time sec */
-    memcpy((char *)p, (char *)&msg_time_sec, sizeof(msg_time_sec));
-    p += sizeof(msg_time_sec);
+    KRB4_PUT32(p, msg_time_sec);
 
 #ifdef NOENCRYPTION
     cksum = 0;
-    memset((char*) big_cksum, 0, sizeof(big_cksum));
+    memset(big_cksum, 0, sizeof(big_cksum));
 #else /* Do encryption */
     /* calculate the checksum of length, timestamps, and input data */
     cksum = quad_cksum(q, (unsigned KRB4_32 *)big_cksum,
-                      p-q, 2, key);
+                      p - q, 2, key);
 #endif /* NOENCRYPTION */
-    DEB (("\ncksum = %u",cksum));
+    DEB(("\ncksum = %u",cksum));
 
     /* stuff checksum */
-    memcpy((char *)p, (char *)big_cksum, sizeof(big_cksum));
-    p += sizeof(big_cksum);
+    for (i = 0; i < 4; i++)
+       KRB4_PUT32(p, big_cksum[i]);
 
-    return ((long)(p - out));  /* resulting size */
+    return p - out;            /* resulting size */
 }
index 80f0d3abdbf6a28efc178eebd98c5bc9886cb538..6ba9a646c737f1cd9428cd151ddab91cb6291768 100644 (file)
@@ -1,17 +1,31 @@
 /*
- * rd_err.c
+ * lib/krb4/rd_err.c
  *
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  *
  * Steve Miller    Project Athena  MIT/DEC
  */
 
-#include "mit-copyright.h"
-
 #include <string.h>
 
 #include "krb.h"
  */
 
 KRB5_DLLIMP int KRB5_CALLCONV
-krb_rd_err(in,in_length,code,m_data)
+krb_rd_err(in, in_length, code, m_data)
     u_char FAR *in;                 /* pointer to the msg received */
     u_long in_length;           /* of in msg */
     long FAR *code;                 /* received error code */
     MSG_DAT FAR *m_data;
 {
     register u_char *p;
-    int swap_bytes = 0;
+    int le;
+    unsigned KRB4_32 raw_code;
+
     p = in;                     /* beginning of message */
 
+    if (in_length < 1 + 1 + 4)
+       return RD_AP_MODIFIED;  /* XXX should have better error code */
     if (*p++ != KRB_PROT_VERSION)
-        return(RD_AP_VERSION);
+        return RD_AP_VERSION;
     if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
-        return(RD_AP_MSG_TYPE);
-    if ((*p++ & 1) != HOST_BYTE_ORDER)
-        swap_bytes++;
+        return RD_AP_MSG_TYPE;
+    le = *p++ & 1;
 
-    /* safely get code */
-    {
-      unsigned KRB4_32 raw_code;
-      
-      memcpy((char *)&raw_code, (char *)p, sizeof(raw_code));
-      if (swap_bytes)
-        raw_code = krb4_swab32(raw_code);
-      p += sizeof(raw_code);         /* skip over */
-      *code = raw_code;
-    }
+    KRB4_GET32(raw_code, p, le);
+    *code = raw_code;          /* XXX unsigned->signed conversion! */
 
     m_data->app_data = p;       /* we're now at the error text
                                  * message */
-    m_data->app_length = in_length;
+    m_data->app_length = p - in;
 
-    return(RD_AP_OK);           /* OK == 0 */
+    return RD_AP_OK;           /* OK == 0 */
 }
index a34d713efebd09171dcdaa35a70f54618436d3ff..a9c219215a0a7ca4f7711ea89d2db19a96667887 100644 (file)
 
 
 int
-krb_rd_preauth(pkt,preauth_p,preauth_len,auth_pr,key)
+krb_rd_preauth(pkt, preauth_p, preauth_len, auth_pr, key)
     KTEXT pkt;
     char *preauth_p;
     int preauth_len;
     Principal *auth_pr;
     des_cblock key;
 {
-   int st;
-   char *name_p;
+    int st;
+    char *name_p;
 
-   name_p = auth_pr->name;
+    name_p = auth_pr->name;
    
 #ifndef NOENCRYPTION
-   /* Decrypt preauth_p using key as the key and initialization vector. */
-   /* check preauth_len */
-   if ((((strlen(name_p) + 1) / 8) + 1) *8 != preauth_len)
-     return KERB_ERR_PREAUTH_SHORT;
-   else {
-     des_key_schedule key_s;
+    /* Decrypt preauth_p using key as the key and initialization vector. */
+    /* check preauth_len */
+    if ((((strlen(name_p) + 1) / 8) + 1) * 8 != preauth_len)
+       return KERB_ERR_PREAUTH_SHORT;
+    else {
+       des_key_schedule key_s;
 
-     if (des_key_sched(key, key_s)) {
-       return 1;
-     }
-     des_pcbc_encrypt((des_cblock *) preauth_p, (des_cblock *) preauth_p,
-                     (long) preauth_len, key_s, (des_cblock *) key, 
-                     DES_DECRYPT);
-   }
+       if (des_key_sched(key, key_s)) {
+           return 1;
+       }
+       des_pcbc_encrypt((des_cblock *)preauth_p, (des_cblock *)preauth_p,
+                        (long)preauth_len, key_s, (des_cblock *)key, 
+                        DES_DECRYPT);
+       memset(key_s, 0, sizeof(key_s));
+    }
 #endif /* R3_NO_MODIFICATIONS */
 
-   /* since the preauth data has the trailing 0, this just works */
-   st = strcmp(preauth_p, name_p);
-   if (st)
+    /* since the preauth data has the trailing 0, this just works */
+    st = strcmp(preauth_p, name_p);
+    if (st)
        return KERB_ERR_PREAUTH_MISMATCH;
-   return 0;
+    return 0;
 }
index 9a2bb26d5f839c16daf15cbcc8f8730d46e4344b..462d91574d98a8f52498906575e2d19f268c8239 100644 (file)
@@ -1,11 +1,27 @@
 /*
- * rd_priv.c
+ * lib/krb4/rd_priv.c
  *
- * CopKRB4_32right 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  *
  * This routine dissects a a Kerberos 'private msg', decrypting it,
  * checking its integrity, and returning a pointer to the application
@@ -18,8 +34,6 @@
  * Steve Miller    Project Athena  MIT/DEC
  */
 
-#include "mit-copyright.h"
-
 /* system include files */
 #include <stdio.h>
 #include <string.h>
@@ -66,7 +80,7 @@ int private_msg_ver = KRB_PROT_VERSION;
  */
 
 KRB5_DLLIMP long KRB5_CALLCONV
-krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
+krb_rd_priv(in, in_length, schedule, key, sender, receiver, m_data)
     u_char *in;                        /* pointer to the msg received */
     unsigned KRB4_32 in_length; /* length of "in" msg */
     Key_schedule schedule;     /* precomputed key schedule */
@@ -76,30 +90,32 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     MSG_DAT *m_data;           /*various input/output data from msg */
 {
     register u_char *p,*q;
-    unsigned KRB4_32 src_addr;
+    int v, t, le;
+    struct in_addr src_addr;
     unsigned KRB4_32 c_length;
     int swap_bytes;
     unsigned KRB4_32 t_local;
     KRB4_32 delta_t;           /* Difference between timestamps */
 
     p = in;                    /* beginning of message */
+#define IN_REMAIN (in_length - (p - in))
     swap_bytes = 0;
 
-    if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+    if (IN_REMAIN < 1 + 1 + 4)
+       return RD_AP_MODIFIED;
+    v = *p++;
+    if (v != KRB_PROT_VERSION && v != 3)
         return RD_AP_VERSION;
-    private_msg_ver = *(p-1);
-    if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+    private_msg_ver = v;
+    t = *p++;
+    if ((t & ~1) != AUTH_MSG_PRIVATE)
         return RD_AP_MSG_TYPE;
-    if ((*p++ & 1) != HOST_BYTE_ORDER)
-        swap_bytes++;
+    le = t & 1;
 
     /* get cipher length */
-    memcpy((char *)&c_length, (char *)p, sizeof(c_length));
-    if (swap_bytes)
-           c_length = krb4_swab32(c_length);
-    p += sizeof(c_length);
+    KRB4_GET32(c_length, p, le);
     /* check for rational length so we don't go comatose */
-    if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+    if (IN_REMAIN < c_length)
         return RD_AP_MODIFIED;
 
 #ifndef NOENCRYPTION
@@ -118,17 +134,10 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
 #endif
 
     /* safely get application data length */
-    memcpy((char *)&(m_data->app_length), (char *) p, 
-          sizeof(m_data->app_length));
-    if (swap_bytes)
-        m_data->app_length = krb4_swab32(m_data->app_length);
-    p += sizeof(m_data->app_length);    /* skip over */
-
-    if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
-        sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
-        sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
-        > in_length)
-        return RD_AP_MODIFIED;
+    KRB4_GET32(m_data->app_length, p, le);
+
+    if (IN_REMAIN < m_data->app_length + 4 + 1 + 4)
+       return RD_AP_MODIFIED;
 
 #ifndef NOENCRYPTION
     /* we're now at the decrypted application data */
@@ -138,25 +147,19 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     p += m_data->app_length;
 
     /* safely get time_5ms */
-    memcpy((char *)&(m_data->time_5ms), (char *) p, 
-          sizeof(m_data->time_5ms));
-    /*  don't need to swap-- one byte for now */
-    p += sizeof(m_data->time_5ms);
+    m_data->time_5ms = *p++;
 
     /* safely get src address */
-    memcpy((char *)&src_addr, (char *) p, sizeof(src_addr));
+    memcpy(&src_addr.s_addr, p, sizeof(src_addr.s_addr));
     /* don't swap, net order always */
-    p += sizeof(src_addr);
+    p += sizeof(src_addr.s_addr);
 
-    if (!krb_ignore_ip_address && src_addr != (u_long) sender->sin_addr.s_addr)
+    if (!krb_ignore_ip_address
+       && src_addr.s_addr != sender->sin_addr.s_addr)
        return RD_AP_MODIFIED;
 
     /* safely get time_sec */
-    memcpy((char *)&(m_data->time_sec), (char *) p, 
-         sizeof(m_data->time_sec));
-    if (swap_bytes) m_data->time_sec = krb4_swab32(m_data->time_sec);
-
-    p += sizeof(m_data->time_sec);
+    KRB4_GET32(m_data->time_sec, p, le);
 
     /* check direction bit is the sign bit */
     /* For compatibility with broken old code, compares are done in VAX 
@@ -166,17 +169,18 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
        back to the receiver, but most higher level protocols can deal
        with that more directly. */
     if (krb_ignore_ip_address) {
-        if (m_data->time_sec <0)
+        if (m_data->time_sec < 0)
             m_data->time_sec = -m_data->time_sec;
     } else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
-                          receiver->sin_addr.s_addr)==-1) 
+                                 receiver->sin_addr.s_addr) == -1)
        /* src < recv */ 
-       m_data->time_sec =  - m_data->time_sec; 
-    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
-                               receiver->sin_addr.s_addr)==0) 
-       if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+       m_data->time_sec = -m_data->time_sec;
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+                               receiver->sin_addr.s_addr) == 0)
+       if (lsb_net_ushort_less(sender->sin_port,
+                               receiver->sin_port) == -1)
            /* src < recv */
-           m_data->time_sec =  - m_data->time_sec; 
+           m_data->time_sec = -m_data->time_sec;
     /*
      * all that for one tiny bit!
      * Heaven help those that talk to themselves.
@@ -185,12 +189,12 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     /* check the time integrity of the msg */
     t_local = TIME_GMT_UNIXSEC;
     delta_t = t_local - m_data->time_sec;
-    if (delta_t < 0) delta_t = -delta_t;  /* Absolute value of difference */
+    if (delta_t < 0)
+       delta_t = -delta_t;     /* Absolute value of difference */
     if (delta_t > CLOCK_SKEW) {
-        return(RD_AP_TIME);            /* XXX should probably be better
-                                          code */
+        return RD_AP_TIME;     /* XXX should probably be better code */
     }
-    DEB (("\ndelta_t = %d",delta_t));
+    DEB(("\ndelta_t = %d", delta_t));
 
     /*
      * caller must check timestamps for proper order and
index 65fe12b0b9a6cf25e1e4df2d9a738e2ffb193e39..542828d79164f9d5f4643a585835a5c36d02ff98 100644 (file)
@@ -1,14 +1,29 @@
 /*
- * rd_req.c
+ * lib/krb4/rd_req.c
  *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Institute of Technology.  All Rights Reserved.
  *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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.
  */
 
-#include "mit-copyright.h"
 #include "des.h"
 #include "krb.h"
 #include "prot.h"
@@ -68,7 +83,7 @@ static int krb5_key;          /* whether krb5 key is used for decrypt */
 static krb5_keyblock srv_k5key;
 
 int
-krb_set_key(key,cvt)
+krb_set_key(key, cvt)
     char *key;
     int cvt;
 {
@@ -81,10 +96,10 @@ krb_set_key(key,cvt)
     return KSUCCESS;
 #else /* Encrypt */
     if (cvt)
-        string_to_key(key,ky);
+        string_to_key(key, ky);
     else
         memcpy((char *)ky, key, 8);
-    return(des_key_sched(ky,serv_key));
+    return des_key_sched(ky,serv_key);
 #endif /* NOENCRYPTION */
 }
 
@@ -108,19 +123,6 @@ krb_clear_key_krb5(ctx)
     krb5_key = 0;
 }
 
-/* A helper function to let us see if a buffer is properly terminated. */
-static int
-krb_strnlen(const char *str, size_t max_len)
-{
-    int i = 0;
-    for(i = 0; i < max_len; i++) {
-        if(str[i] == '\0') {
-            return i;
-       }
-    }
-    return -1;
-}
-
 /*
  * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
  * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
@@ -163,7 +165,7 @@ krb_strnlen(const char *str, size_t max_len)
  */
 
 KRB5_DLLIMP int KRB5_CALLCONV
-krb_rd_req(authent,service,instance,from_addr,ad,fn)
+krb_rd_req(authent, service, instance, from_addr, ad, fn)
     register KTEXT authent;    /* The received message */
     char FAR *service;         /* Service name */
     char FAR *instance;                /* Service instance */
@@ -186,45 +188,48 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
     char r_realm[REALM_SZ];    /* Client realm from authenticator */
     unsigned int r_time_ms;     /* Fine time from authenticator */
     unsigned KRB4_32 r_time_sec;   /* Coarse time from authenticator */
-    register char *ptr;                /* For stepping through */
+    register unsigned char *ptr; /* For stepping through */
     unsigned KRB4_32 t_local;  /* Local time on our side of the protocol */
     KRB4_32 delta_t;           /* Time in authenticator minus local time */
     KRB4_32 tkt_age;           /* Age of ticket */
-    int swap_bytes;            /* Need to swap bytes? */
+    int le;                    /* is little endian? */
     int mutual;                        /* Mutual authentication requested? */
+    int t;                     /* msg type */
     unsigned char s_kvno;      /* Version number of the server's key
                                   Kerberos used to encrypt ticket */
+    int ret;
+    int len;
     krb5_keyblock keyblock;
     int status;
 
     tkt->mbz = req_id->mbz = 0;
 
-    if (authent->length <= 0)
-       return(RD_AP_MODIFIED);
+    if (authent->length < 1 + 1 + 1)
+       return RD_AP_MODIFIED;
 
-    ptr = (char *) authent->dat;
+    ptr = authent->dat;
+#define AUTHENT_REMAIN (authent->length - (ptr - authent->dat))
 
     /* get msg version, type and byte order, and server key version */
 
     /* check version */
-    if (KRB_PROT_VERSION != (unsigned int) *ptr++)
-        return(RD_AP_VERSION);
+    if (KRB_PROT_VERSION != *ptr++)
+        return RD_AP_VERSION;
 
     /* byte order */
-    swap_bytes = 0;
-    if ((*ptr & 1) != HOST_BYTE_ORDER)
-        swap_bytes++;
+    t = *ptr++;
+    le = t & 1;
 
     /* check msg type */
     mutual = 0;
-    switch (*ptr++ & ~1) {
+    switch (t & ~1) {
     case AUTH_MSG_APPL_REQUEST:
         break;
     case AUTH_MSG_APPL_REQUEST_MUTUAL:
         mutual++;
         break;
     default:
-        return(RD_AP_MSG_TYPE);
+        return RD_AP_MSG_TYPE;
     }
 
 #ifdef lint
@@ -234,13 +239,14 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
         mutual = 0;
 #endif /* lint */
     s_kvno = *ptr++;           /* get server key version */
-    if(krb_strnlen(ptr, sizeof(realm)) < 0) {
+    len = krb_strnlen((char *)ptr, AUTHENT_REMAIN) + 1;
+    if (len <= 0 || len > sizeof(realm)) {
        return RD_AP_MODIFIED;  /* must have been modified, the client wouldn't
                                   try to trick us with wacky data */
     }
-    (void) strncpy(realm,ptr,REALM_SZ);        /* And the realm of the issuing KDC */
-    realm[REALM_SZ-1] = '\0';
-    ptr += strlen(realm) + 1;  /* skip the realm "hint" */
+    /* And the realm of the issuing KDC */
+    (void)memcpy(realm, ptr, (size_t)len);
+    ptr += len;                        /* skip the realm "hint" */
 
     /*
      * If "fn" is NULL, key info should already be set; don't
@@ -250,38 +256,50 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
      * from the ticket file.  If "fn" is the null string, use the
      * default ticket file.
      */
-    if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
-               strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
-        if (*fn == 0) fn = KEYFILE;
+    if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance)
+              || strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+        if (*fn == 0)
+           fn = KEYFILE;
         st_kvno = s_kvno;
 #ifndef NOENCRYPTION
-        if (read_service_key(service,instance,realm,(int) s_kvno,
-                            fn,(char *)skey) == 0) {
-               if ((status = krb_set_key((char *)skey,0)))
-                       return(status);
+        if (read_service_key(service,instance,realm, (int)s_kvno,
+                            fn, (char *)skey) == 0) {
+           if ((status = krb_set_key((char *)skey,0)))
+               return(status);
 #ifdef KRB4_USE_KEYTAB
-       } else if (krb54_get_service_keyblock(service,instance,
-                      realm, (int) s_kvno,fn, &keyblock) == 0) {
-               krb_set_key_krb5(krb5__krb4_context, &keyblock);
-               krb5_free_keyblock_contents(krb5__krb4_context, &keyblock);
+       } else if (krb54_get_service_keyblock(service, instance,
+                                             realm, (int)s_kvno,
+                                             fn, &keyblock) == 0) {
+           krb_set_key_krb5(krb5__krb4_context, &keyblock);
+           krb5_free_keyblock_contents(krb5__krb4_context, &keyblock);
 #endif
        } else
-               return(RD_AP_UNDEC);
-       
+           return RD_AP_UNDEC;
 #endif /* !NOENCRYPTION */
-        (void) strncpy(st_rlm,realm, sizeof(st_rlm) - 1);
-       st_rlm[sizeof(st_rlm) - 1] = '\0';
-        (void) strncpy(st_nam,service, sizeof(st_nam) - 1);
-       st_nam[sizeof(st_nam) - 1] = '\0';
-        (void) strncpy(st_inst,instance, sizeof(st_inst) - 1);
-       st_inst[sizeof(st_inst) - 1] = '\0';
+
+       len = krb_strnlen(realm, sizeof(st_rlm)) + 1;
+       if (len <= 0)
+           return KFAILURE;
+       memcpy(st_rlm, realm, (size_t)len);
+       len = krb_strnlen(service, sizeof(st_nam)) + 1;
+       if (len <= 0)
+           return KFAILURE;
+       memcpy(st_nam, service, (size_t)len);
+       len = krb_strnlen(instance, sizeof(st_inst)) + 1;
+       if (len <= 0)
+           return KFAILURE;
+       memcpy(st_inst, instance, (size_t)len);
     }
 
-    /* Get ticket from authenticator */
-    tkt->length = (int) *ptr++ & 0xff;
-    if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
-       return(RD_AP_MODIFIED);
-    memcpy((char *)(tkt->dat), ptr+1, tkt->length);
+    /* Get ticket length */
+    tkt->length = *ptr++;
+    /* Get authenticator length while we're at it. */
+    req_id->length = *ptr++;
+    if (AUTHENT_REMAIN < tkt->length + req_id->length)
+       return RD_AP_MODIFIED;
+    /* Copy ticket */
+    memcpy(tkt->dat, ptr, (size_t)tkt->length);
+    ptr += tkt->length;
 
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug)
@@ -312,7 +330,6 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
        }
     }
 
-
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug) {
         log("Ticket Contents.");
@@ -325,73 +342,81 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
 #endif
 
     /* Extract the authenticator */
-    req_id->length = (int) *(ptr++);
-    if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
-       authent->length)
-       return(RD_AP_MODIFIED);
-    memcpy((char *)(req_id->dat), ptr + tkt->length, req_id->length);
+    memcpy(req_id->dat, ptr, (size_t)req_id->length);
 
 #ifndef NOENCRYPTION
     /* And decrypt it with the session key from the ticket */
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug) log("About to decrypt authenticator");
 #endif
-    key_sched(ad->session,seskey_sched);
-    pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
-                 (long) req_id->length, seskey_sched,&ad->session,DES_DECRYPT);
+
+    key_sched(ad->session, seskey_sched);
+    pcbc_encrypt((C_Block *)req_id->dat, (C_Block *)req_id->dat,
+                 (long)req_id->length,
+                seskey_sched, &ad->session, DES_DECRYPT);
+    memset(seskey_sched, 0, sizeof(seskey_sched));
+
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug) log("Done.");
 #endif
 #endif /* NOENCRYPTION */
 
-#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
-
-    ptr = (char *) req_id->dat;
-    (void) strncpy(r_aname,ptr,ANAME_SZ); /* Authentication name */
-    r_aname[ANAME_SZ-1] = '\0';
-    ptr += strlen(r_aname)+1;
-    check_ptr();
-    (void) strncpy(r_inst,ptr,INST_SZ);        /* Authentication instance */
-    r_inst[INST_SZ-1] = '\0';
-    ptr += strlen(r_inst)+1;
-    check_ptr();
-    (void) strncpy(r_realm,ptr,REALM_SZ); /* Authentication name */
-    r_realm[REALM_SZ-1] = '\0';
-    ptr += strlen(r_realm)+1;
-    check_ptr();
-    memcpy((char *)&ad->checksum, ptr, 4);     /* Checksum */
-    ptr += 4;
-    check_ptr();
-    if (swap_bytes) ad->checksum = krb4_swab32(ad->checksum);
-    r_time_ms = *(ptr++);      /* Time (fine) */
+    ptr = req_id->dat;
+#define REQID_REMAIN (req_id->length - (ptr - req_id->dat))
+
+    ret = RD_AP_MODIFIED;
+
+    len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1;
+    if (len <= 0 || len > ANAME_SZ)
+       goto cleanup;
+    memcpy(r_aname, ptr, (size_t)len); /* Authentication name */
+    ptr += len;
+    len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       goto cleanup;
+    memcpy(r_inst, ptr, (size_t)len); /* Authentication instance */
+    ptr += len;
+    len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1;
+    if (len <= 0 || len > REALM_SZ)
+       goto cleanup;
+    memcpy(r_realm, ptr, (size_t)len); /* Authentication name */
+    ptr += len;
+
+    if (REQID_REMAIN < 4 + 1 + 4)
+       goto cleanup;
+    KRB4_GET32(ad->checksum, ptr, le);
+    r_time_ms = *ptr++;                /* Time (fine) */
 #ifdef lint
     /* XXX r_time_ms is set but not used.  why??? */
     /* this is a crock to get lint to shut up */
     if (r_time_ms)
         r_time_ms = 0;
 #endif /* lint */
-    check_ptr();
-    /* assume sizeof(r_time_sec) == 4 ?? */
-    memcpy((char *)&r_time_sec, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) r_time_sec = krb4_swab32(r_time_sec);
+    /* Time (coarse) */
+    KRB4_GET32(r_time_sec, ptr, le);
 
     /* Check for authenticity of the request */
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug)
         log("Pname:   %s %s",ad->pname,r_aname);
 #endif
+
+    ret = RD_AP_INCON;
     if (strcmp(ad->pname,r_aname) != 0)
-        return(RD_AP_INCON);
+       goto cleanup;
     if (strcmp(ad->pinst,r_inst) != 0)
-        return(RD_AP_INCON);
+       goto cleanup;
+
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug)
         log("Realm:   %s %s",ad->prealm,r_realm);
 #endif
-    if ((strcmp(ad->prealm,r_realm) != 0))
-        return(RD_AP_INCON);
+
+    if (strcmp(ad->prealm,r_realm) != 0)
+       goto cleanup;
 
     /* check the time integrity of the msg */
+    ret = RD_AP_TIME;
     t_local = TIME_GMT_UNIXSEC;
     delta_t = t_local - r_time_sec;
     if (delta_t < 0) delta_t = -delta_t;  /* Absolute value of difference */
@@ -401,11 +426,12 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
             log("Time out of range: %d - %d = %d",
                 time_secs, r_time_sec, delta_t);
 #endif
-        return(RD_AP_TIME);
+       goto cleanup;
     }
 
     /* Now check for expiration of ticket */
 
+    ret = RD_AP_NYV;
     tkt_age = t_local - ad->time_sec;
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug)
@@ -414,21 +440,34 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
 #endif
     if (t_local < ad->time_sec) {
         if ((ad->time_sec - t_local) > CLOCK_SKEW)
-            return(RD_AP_NYV);
+           goto cleanup;
+    } else if (krb_life_to_time((KRB4_32)ad->time_sec, ad->life)
+            < t_local + CLOCK_SKEW) {
+       ret = RD_AP_EXP;
+       goto cleanup;
     }
-    else if (krb_life_to_time((KRB4_32)ad->time_sec, ad->life)
-            < t_local + CLOCK_SKEW)
-        return(RD_AP_EXP);
 
 #ifdef KRB_CRYPT_DEBUG
     if (krb_ap_req_debug)
         log("Address: %d %d",ad->address,from_addr);
 #endif
-    if (!krb_ignore_ip_address && from_addr && (ad->address != from_addr))
-        return(RD_AP_BADD);
+
+    if (!krb_ignore_ip_address
+       && from_addr && (ad->address != from_addr)) {
+       ret = RD_AP_BADD;
+       goto cleanup;
+    }
 
     /* All seems OK */
     ad->reply.length = 0;
+    ret = 0;
+
+cleanup:
+    if (ret) {
+       /* Stomp on session key if there is an error. */
+       memset(ad->session, 0, sizeof(ad->session));
+       return ret;
+    }
 
-    return(RD_AP_OK);
+    return RD_AP_OK;
 }
index cade67b628cd42d6d4e514aee65952b1bf39ebb9..23578a2209647c0ccbf4f69331f421a61fe0602b 100644 (file)
@@ -1,12 +1,28 @@
 /*
- * rd_safe.c
+ * lib/krb4/rd_safe.c
  *
- * CopKRB4_32right 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
- *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology.  All Rights Reserved.
  *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
  * This routine dissects a a Kerberos 'safe msg', checking its
  * integrity, and returning a pointer to the application data
  * contained and its length.
@@ -16,8 +32,6 @@
  * Steve Miller    Project Athena  MIT/DEC
  */
 
-#include "mit-copyright.h"
-
 /* system include files */
 #include <stdio.h>
 #include <string.h>
@@ -57,45 +71,45 @@ krb_rd_safe(in,in_length,key,sender,receiver,m_data)
     struct sockaddr_in FAR *receiver;  /* receiver's address -- me */
     MSG_DAT FAR *m_data;               /* where to put message information */
 {
+    int i;
     unsigned KRB4_32 calc_cksum[4];
     unsigned KRB4_32 big_cksum[4];
-    int swap_bytes;
+    int le;
 
     u_char     *p,*q;
-    unsigned KRB4_32  src_addr; /* Can't send structs since no
-                                  * guarantees on size */
+    int t;
+    struct in_addr src_addr;
     unsigned KRB4_32 t_local;  /* Local time in our machine */
     KRB4_32 delta_t;           /* Difference between timestamps */
 
     /* Be very conservative */
-    if (sizeof(src_addr) != sizeof(struct in_addr)) {
+    if (sizeof(src_addr.s_addr) != 4) {
 #ifdef DEBUG
-        fprintf(stderr,"\n\
-krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
+       fprintf(stderr, "\nkrb_rd_safe protocol err "
+               "sizeof(src_addr.s_addr) != 4\n");
 #endif
-        return RD_AP_VERSION;
+       return RD_AP_VERSION;
     }
 
     p = in;                     /* beginning of message */
-    swap_bytes = 0;
+#define IN_REMAIN (in_length - (p - in))
+    if (IN_REMAIN < 1 + 1 + 4)
+       return RD_AP_MODIFIED;
 
-    if (*p++ != KRB_PROT_VERSION)       return RD_AP_VERSION;
-    if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
-    if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+    if (*p++ != KRB_PROT_VERSION)
+       return RD_AP_VERSION;
+    t = *p++;
+    if ((t & ~1) != AUTH_MSG_SAFE)
+       return RD_AP_MSG_TYPE;
+    le = t & 1;
 
     q = p;                      /* mark start of cksum stuff */
 
     /* safely get length */
-    memcpy((char *)&(m_data->app_length), (char *)p, 
-          sizeof(m_data->app_length));
-    if (swap_bytes) m_data->app_length = krb4_swab32(m_data->app_length);
-    p += sizeof(m_data->app_length); /* skip over */
+    KRB4_GET32(m_data->app_length, p, le);
 
-    if (m_data->app_length + sizeof(in_length)
-        + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
-        + sizeof(big_cksum) + sizeof(src_addr)
-        + VERSION_SZ + MSG_TYPE_SZ > in_length)
-        return(RD_AP_MODIFIED);
+    if (IN_REMAIN < m_data->app_length + 1 + 4 + 4 + 4 * 4)
+       return RD_AP_MODIFIED;
 
     m_data->app_data = p;       /* we're now at the application data */
 
@@ -103,28 +117,19 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
     p += m_data->app_length;
 
     /* safely get time_5ms */
-    memcpy((char *)&(m_data->time_5ms), (char *)p, 
-          sizeof(m_data->time_5ms));
-
-    /* don't need to swap-- one byte for now */
-    p += sizeof(m_data->time_5ms);
+    m_data->time_5ms = *p++;
 
     /* safely get src address */
-    memcpy((char *)&src_addr, (char *)p, sizeof(src_addr));
-
+    (void)memcpy(&src_addr.s_addr, p, sizeof(src_addr.s_addr));
     /* don't swap, net order always */
-    p += sizeof(src_addr);
+    p += sizeof(src_addr.s_addr);
 
-    if (!krb_ignore_ip_address &&
-       src_addr != (unsigned KRB4_32) sender->sin_addr.s_addr)
+    if (!krb_ignore_ip_address
+       && src_addr.s_addr != sender->sin_addr.s_addr)
         return RD_AP_MODIFIED;
 
     /* safely get time_sec */
-    memcpy((char *)&(m_data->time_sec), (char *)p, 
-          sizeof(m_data->time_sec));
-    if (swap_bytes)
-        m_data->time_sec = krb4_swab32(m_data->time_sec);
-    p += sizeof(m_data->time_sec);
+    KRB4_GET32(m_data->time_sec, p, le);
 
     /* check direction bit is the sign bit */
     /* For compatibility with broken old code, compares are done in VAX 
@@ -166,15 +171,6 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
      * and we don't assume tightly synchronized clocks.
      */
 
-    memcpy((char *)big_cksum, (char *)p, sizeof(big_cksum));
-    if (swap_bytes) {
-      /* swap_u_16(big_cksum); */
-      unsigned KRB4_32 *bb;
-      bb = (unsigned KRB4_32*)big_cksum;
-      bb[0] = krb4_swab32(bb[0]);  bb[1] = krb4_swab32(bb[1]);
-      bb[2] = krb4_swab32(bb[2]);  bb[3] = krb4_swab32(bb[3]);
-    }
-
 #ifdef NOENCRYPTION
     memset(calc_cksum, 0, sizeof(calc_cksum));
 #else /* Do encryption */
@@ -183,13 +179,17 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
     quad_cksum(q,calc_cksum,p-q,2,key);
 #endif /* NOENCRYPTION */
 
+    for (i = 0; i < 4; i++)
+       KRB4_GET32(big_cksum[i], p, le);
+
     DEB (("\n0: calc %l big %lx\n1: calc %lx big %lx\n2: calc %lx big %lx\n3: calc %lx big %lx\n",
                calc_cksum[0], big_cksum[0],
                calc_cksum[1], big_cksum[1],
                calc_cksum[2], big_cksum[2],
                calc_cksum[3], big_cksum[3]));
-    if (memcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
-        return(RD_AP_MODIFIED);
+    for (i = 0; i < 4; i++)
+       if (big_cksum[i] != calc_cksum[i])
+           return RD_AP_MODIFIED;
 
-    return(RD_AP_OK);           /* OK == 0 */
+    return RD_AP_OK;           /* OK == 0 */
 }
index f93b9d0793cedbb9d2eb958e2e04f69114e4fcb2..5897f67618e939169562ab1e4b79ca7b1836b57e 100644 (file)
@@ -370,6 +370,7 @@ send_recv(pkt,rpkt,f,_to,addrs)
        DEB (("Recvfrom error %d\n", SOCKET_ERRNO));
         return 0;
     }
+    rpkt->length = recvresult;
 #ifdef DEBUG
     if (krb_debug) {
         printf("received packet from ");
diff --git a/src/lib/krb4/strnlen.c b/src/lib/krb4/strnlen.c
new file mode 100644 (file)
index 0000000..2c9a026
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * lib/krb4/strnlen.c
+ *
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ */
+
+#include <stddef.h>
+#include "krb.h"
+/*
+ * krb_strnlen()
+ *
+ * Return the length of the string if a NUL is found in the first n
+ * bytes, otherwise, -1.
+ */
+
+KRB5_CALLCONV int
+krb_strnlen(const char *s, int n)
+{
+    int i = 0;
+
+    for (i = 0; i < n; i++) {
+        if (s[i] == '\0') {
+            return i;
+       }
+    }
+    return -1;
+}