* prot_common.c: New file; contains functions to encode/decode
authorTom Yu <tlyu@mit.edu>
Tue, 23 Jan 2001 05:48:06 +0000 (05:48 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 23 Jan 2001 05:48:06 +0000 (05:48 +0000)
string triples for principals.

* prot_kdc.c: New file; contains encoders and decoders
(eventually) for the KDC's use.

* Makefile.in (OBJS, SRCS): Add prot_common.o, prot_kdc.o.

* cr_auth_repl.c: KRB4_PUT{16,32} -> KRB4_PUT{16,32}BE.

* cr_ciph.c: Include prot.h.  KRB4_PUT32 -> KRB4_PUT32BE.

* cr_err_repl.c: KRB4_PUT32 -> KRB4_PUT32BE.

* cr_tkt.c: KRB4_PUT32 -> KRB4_PUT32BE.

* decomp_tkt.c: krb_strnlen -> krb4int_strnlen.

* g_ad_tkt.c: krb_strnlen -> krb4int_strnlen.  KRB4_PUT32 ->
KRB4_PUT32BE.  Properly skip date while parsing error.

* g_in_tkt.c: krb_strnlen -> krb4int_strnlen.  KRB4_PUT32 ->
KRB4_PUT32BE.  Properly skip date while parsing error.

* g_phost.c: Changes from audit.  Actually bail out instead of
failing silently if h->h_name is too long.

* kname_parse.c: Changes from audit.  Check overrun per character
processed.

* mk_auth.c: krb_strnlen -> krb4int_strnlen.  KRB4_PUT32 ->
KRB4_PUT32BE.  Include prot.h.

* mk_err.c: KRB4_PUT32 -> KRB4_PUT32BE.

* mk_priv.c: KRB4_PUT32 -> KRB4_PUT32BE.

* mk_req.c: KRB4_PUT32 -> KRB4_PUT32BE.

* mk_safe.c: KRB4_PUT32 -> KRB4_PUT32BE.

* rd_req.c: krb_strnlen -> krb4int_strnlen.

* strnlen.c: Rename to krb4int_strnlen.  Also include prot.h,
which is where strnlen is declared now.

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

18 files changed:
src/lib/krb4/Makefile.in
src/lib/krb4/cr_auth_repl.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/g_phost.c
src/lib/krb4/kname_parse.c
src/lib/krb4/mk_auth.c
src/lib/krb4/mk_err.c
src/lib/krb4/mk_priv.c
src/lib/krb4/mk_req.c
src/lib/krb4/mk_safe.c
src/lib/krb4/prot_common.c [new file with mode: 0644]
src/lib/krb4/prot_kdc.c [new file with mode: 0644]
src/lib/krb4/rd_req.c
src/lib/krb4/strnlen.c

index 3afd33ced09448f1777631480534c994c45c53ca..917e6424ae321719aad2bd50c8ba054f31fae93c 100644 (file)
@@ -53,6 +53,8 @@ OBJS  = \
        $(OUTPRE)mk_safe.$(OBJEXT) \
        $(OUTPRE)month_sname.$(OBJEXT) \
        $(OUTPRE)one.$(OBJEXT) \
+       $(OUTPRE)prot_common.$(OBJEXT) \
+       $(OUTPRE)prot_kdc.$(OBJEXT) \
        $(OUTPRE)pkt_cipher.$(OBJEXT) \
        $(OUTPRE)pkt_clen.$(OBJEXT) \
        $(OUTPRE)rd_err.$(OBJEXT) \
@@ -92,6 +94,8 @@ SRCS = \
        $(srcdir)/one.c \
        $(srcdir)/pkt_cipher.c \
        $(srcdir)/pkt_clen.c \
+       $(srcdir)/prot_common.c \
+       $(srcdir)/prot_kdc.c \
        $(srcdir)/rd_err.c \
        $(srcdir)/rd_priv.c \
        $(srcdir)/rd_safe.c \
index 16482908ee12d369a2cd969e797bbb9f7131d41a..277d9af8ee44c704a3c0322a0bccb6d538815c78 100644 (file)
@@ -117,16 +117,16 @@ create_auth_reply(pname, pinst, prealm, time_ws, n, x_date, kvno, cipher)
     p += prealmlen;
 
     /* Workstation timestamp */
-    KRB4_PUT32(p, time_ws);
+    KRB4_PUT32BE(p, time_ws);
 
     *p++ = n;
 
     /* Expiration date */
-    KRB4_PUT32(p, x_date);
+    KRB4_PUT32BE(p, x_date);
 
     /* Now send the ciphertext and info to help decode it */
     *p++ = kvno;
-    KRB4_PUT16(p, cipher->length);
+    KRB4_PUT16BE(p, cipher->length);
     memcpy(p, cipher->dat, (size_t)cipher->length);
     p += cipher->length;
 
index 35196df49efb85d4c6ec775166ee1b72ef930495..bfd628a62fc538bed6cc77b7855d2ef4de1d8c64 100644 (file)
@@ -106,9 +106,9 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
     memcpy(p, prealm, prealmlen);
     p += prealmlen;
     /* ws timestamp */
-    KRB4_PUT32(p, time_ws);
+    KRB4_PUT32BE(p, time_ws);
     /* err code */
-    KRB4_PUT32(p, e);
+    KRB4_PUT32BE(p, e);
     /* err text */
     memcpy(p, e_string, e_stringlen);
     p += e_stringlen;
index 46753d820d131694a9fae6f68467b7c4672a7594..f84429d2e87e83f78076f2a833eade80da72b1d0 100644 (file)
@@ -199,7 +199,7 @@ krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress,
     data += 8;
     *data++ = life;
     /* issue time */
-    KRB4_PUT32(data, time_sec);
+    KRB4_PUT32BE(data, time_sec);
 
     memcpy(data, sname, snamelen);
     data += snamelen;
index c74cdba3eee9501b41a5f7ac8b631841a512da1d..597be9ab6bd5c96b93c7ac7fe4b39ddd0ffbb193 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/krb4/decomp_tkt.c
  *
- * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
  * Institute of Technology.  All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -213,19 +213,19 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
     *flags = *ptr++;
     tkt_le = (*flags >> K_FLAG_ORDER) & 1;
 
-    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    len = krb4int_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;
+    len = krb4int_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;
+    len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
     if (len <= 0 || len > REALM_SZ)
        goto cleanup;
     memcpy(prealm, ptr, (size_t)len);
@@ -258,13 +258,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
 
     KRB4_GET32(*time_sec, ptr, tkt_le);
 
-    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
     if (len <= 0 || len > SNAME_SZ)
        goto cleanup;
     memcpy(sname, ptr, (size_t)len);
     ptr += len;
 
-    len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1;
+    len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
     if (len <= 0 || len > INST_SZ)
        goto cleanup;
     memcpy(sinstance, ptr, (size_t)len);
index a1e3b36f0e2dc1778561df401983d5e6b8fda0e3..4f77f2a6ac8b52197aecdb9b95b1cc7cbfb7fc43 100644 (file)
@@ -116,7 +116,7 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses,
      * these?
      */
     for (i = 0; i < 3; i++) {
-       len = krb_strnlen((char *)ptr, RPKT_REMAIN) + 1;
+       len = krb4int_strnlen((char *)ptr, RPKT_REMAIN) + 1;
        if (len <= 0)
            return INTK_PROT;
        ptr += len;
@@ -128,8 +128,9 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses,
        ptr += 4 + 1 + 4 + 1;
        break;
     case AUTH_MSG_ERR_REPLY:
-       if (RPKT_REMAIN < 4)
+       if (RPKT_REMAIN < 8)
            return INTK_PROT;
+       ptr += 4;
        KRB4_GET32(rep_err_code, ptr, msg_byte_order);
        return rep_err_code;
 
@@ -175,19 +176,19 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses,
     memset(ptr, 0, 8);
     ptr += 8;
 
-    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    len = krb4int_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;
+    len = krb4int_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;
+    len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1;
     if (len <= 0 || len > REALM_SZ)
        return RD_AP_MODIFIED;
     memcpy(rlm, ptr, (size_t)len);
@@ -317,7 +318,7 @@ get_ad_tkt(service, sinstance, realm, lifetime)
     }
 
     /* timestamp */   /* FIXME -- always 0 now, should we fill it in??? */
-    KRB4_PUT32(ptr, time_ws);
+    KRB4_PUT32BE(ptr, time_ws);
 
     *ptr++ = lifetime;
 
index 872d3fe2bd45a955bd9ea0610de3f000af93a464..32f51c1cd20d37ed2b05103427a393ea039435fb 100644 (file)
@@ -196,7 +196,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
 
     /* timestamp */
     t_local = TIME_GMT_UNIXSEC;
-    KRB4_PUT32(p, t_local);
+    KRB4_PUT32BE(p, t_local);
 
     *p++ = life;
 
@@ -241,7 +241,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
      * cr_auth_repl.c for details).
      */
     for (i = 0; i < 3; i++) {
-       len = krb_strnlen((char *)p, RPKT_REMAIN) + 1;
+       len = krb4int_strnlen((char *)p, RPKT_REMAIN) + 1;
        if (len <= 0)
            return INTK_PROT;
        p += len;
@@ -253,8 +253,9 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
        p += 4 + 1 + 4 + 1;
         break;
     case AUTH_MSG_ERR_REPLY:
-       if (RPKT_REMAIN < 4)
+       if (RPKT_REMAIN < 8)
            return INTK_PROT;
+       p += 4;
        KRB4_GET32(rep_err_code, p, msg_byte_order);
        return rep_err_code;
     default:
@@ -316,21 +317,21 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip,
     ptr += 8;
 
     /* extract server's name */
-    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    len = krb4int_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 */
-    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    len = krb4int_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 */
-    len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+    len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1;
     if (len <= 0 || len > sizeof(rlm))
        return INTK_BADPW;
     memcpy(rlm, ptr, (size_t)len);
index 8caece37295cf177310bbb94078dd652b01ecb29..15d027974bfef2af9fa266703d6118ff882c04f4 100644 (file)
@@ -1,13 +1,29 @@
 /*
- * g_phost.c
+ * lib/krb4/g_phost.c
  *
- * Copyright 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1988, 2001 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"
 #define        DEFINE_SOCKADDR         /* For struct hostent, <netdb.h>, etc */
 #include "krb.h"
 
@@ -38,6 +54,7 @@ krb_get_phost(alias)
 {
     struct hostent FAR *h;
     char *p;
+    unsigned char *ucp;
     static char hostname_mem[MAXHOSTNAMELEN];
 #ifdef DO_REVERSE_RESOLVE
     char *rev_addr; int rev_type, rev_len;
@@ -60,14 +77,16 @@ krb_get_phost(alias)
 #endif
        /* We don't want to return a FAR *, so we copy to a safe location. */
        strncpy (hostname_mem, h->h_name, sizeof (hostname_mem));
-       hostname_mem[MAXHOSTNAMELEN-1]='\0';
+       /* Bail out if h_name is too long. */
+       if (hostname_mem[MAXHOSTNAMELEN-1] != '\0')
+           return NULL;
        p = strchr( hostname_mem, '.' );
         if (p)
             *p = 0;
-        p = hostname_mem;
+        ucp = (unsigned char *)hostname_mem;
         do {
-            if (isupper(*p)) *p=tolower(*p);
-        } while (*p++);
+            if (isupper(*ucp)) *ucp=tolower(*ucp);
+        } while (*ucp++);
     }
     return(hostname_mem);
 }
index 53d8fb77c60de7bf752f96325c430f69b1a430f7..a8bfbe45daadc74bdbc5c231a31f6764c7454cd1 100644 (file)
@@ -1,19 +1,39 @@
 /*
- * kname_parse.c
+ * lib/krb4/kname_parse.c
  *
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1987, 1988, 2001 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 <stdio.h>
 #include "krb.h"
 #include <string.h>
 
-/* max size of full name */
+/*
+ * max size of full name
+ *
+ * XXX This does not account for backslach quoting, and besides we
+ * might want to use MAX_K_NAME_SZ.
+ */
 #define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
 
 #define NAME    0              /* which field are we in? */
@@ -123,12 +143,29 @@ kname_parse(np, ip, rp, fullname)
         default:
             *wnext++ = c;
         }
+       /*
+        * Paranoia: check length each time through to ensure that we
+        * don't overwrite things.
+        */
+       switch (field) {
+       case NAME:
+           if (wnext - np >= ANAME_SZ)
+               return KNAME_FMT;
+           break;
+       case INST:
+           if (wnext - ip >= INST_SZ)
+               return KNAME_FMT;
+           break;
+       case REALM:
+           if (wnext - rp >= REALM_SZ)
+               return KNAME_FMT;
+           break;
+       default:
+           DEB (("unknown field value\n"));
+           return KNAME_FMT;
+       }
     }
     *wnext = '\0';
-    if ((strlen(np) > ANAME_SZ - 1) ||
-        (strlen(ip) > INST_SZ  - 1) ||
-        (strlen(rp) > REALM_SZ - 1))
-        return KNAME_FMT;
     return KSUCCESS;
 }
 
index 45415fed333756bca2426bb9909fded785a42d98..335324cdca02591ff6fcba7fda709fe65972e88f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/krb4/mk_auth.c
  *
- * Copyright 1987, 1988, 2000 by the Massachusetts Institute of
+ * Copyright 1987, 1988, 2000, 2001 by the Massachusetts Institute of
  * Technology.  All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -29,6 +29,7 @@
 #define        DEFINE_SOCKADDR         /* Ask for sockets declarations from krb.h. */
 #include <stdio.h>
 #include "krb.h"
+#include "prot.h"
 #include <errno.h>
 #include <string.h>
 
@@ -143,7 +144,7 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
 
     if (!(options & KOPT_DONT_CANON)) {
        phost = krb_get_phost(inst);
-       phostlen = krb_strnlen(phost, INST_SZ) + 1;
+       phostlen = krb4int_strnlen(phost, INST_SZ) + 1;
        if (phostlen <= 0 || phostlen > INST_SZ)
            return KFAILURE;
        memcpy(inst, phost, (size_t)phostlen);
@@ -183,7 +184,7 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
     p += KRB_SENDAUTH_VLEN;
 
     /* put ticket length into buffer */
-    KRB4_PUT32(p, ticket->length);
+    KRB4_PUT32BE(p, ticket->length);
 
     /* put ticket into buffer */
     memcpy(p, ticket->dat, (size_t)ticket->length);
index 8fcb2ed21b1efb4c65f6460a0034d90f35c240e0..721149ec21593786763104c6cda2fd5df9a83e3f 100644 (file)
@@ -74,7 +74,7 @@ krb_mk_err(p, e, e_string)
     *p++ = AUTH_MSG_APPL_ERR;
 
     /* Add the basic info */
-    KRB4_PUT32(p, e);
+    KRB4_PUT32BE(p, e);
     memcpy(p, e_string, e_len); /* err text */
     p += e_len;
 
index 0c355480850985d64c1ed9fdb9082e43030d103f..1e168adce33c989c50c537f951eac23a7d313dfe 100644 (file)
@@ -141,7 +141,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver)
     q = p;
 
     /* stuff input length */
-    KRB4_PUT32(p, length);
+    KRB4_PUT32BE(p, length);
 
 #ifdef NOENCRYPTION
     /* make all the stuff contiguous for checksum */
@@ -174,7 +174,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver)
                                receiver->sin_port) == -1)
             msg_time_sec = -msg_time_sec;
     /* stuff time sec */
-    KRB4_PUT32(p, msg_time_sec);
+    KRB4_PUT32BE(p, msg_time_sec);
 
     /*
      * All that for one tiny bit!  Heaven help those that talk to
@@ -210,7 +210,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver)
                / sizeof(C_Block)) * sizeof(C_Block);
     /* stuff the length */
     p = c_length_ptr;
-    KRB4_PUT32(p, c_length);
+    KRB4_PUT32BE(p, c_length);
 
 #ifndef NOENCRYPTION
     /* pcbc encrypt, pad as needed, use key as ivec */
index 2d5d240efcf05be67d3c6c7a282ba78813996022..cbb4dbd9857f421c43c27449b301a9202ec26eb4 100644 (file)
@@ -197,13 +197,13 @@ krb_mk_req(authent, service, instance, realm, checksum)
     memcpy(q, myrealm, myrealmlen);
     q += myrealmlen;
     /* Checksum */
-    KRB4_PUT32(q, checksum);
+    KRB4_PUT32BE(q, checksum);
 
     /* Fill in the times on the request id */
     time_secs = TIME_GMT_UNIXSEC_US (&time_usecs);
     *q++ = time_usecs;         /* time_usecs % 255 */
     /* Time (coarse) */
-    KRB4_PUT32(q, time_secs);
+    KRB4_PUT32BE(q, time_secs);
 
     /* Fill to a multiple of 8 bytes for DES */
     req_id->length = ((q - req_id->dat + 7) / 8) * 8;
index 1efff995359b3006c29bdfd998128b1f3aefd91c..93cd1ead6d0bc68c8305e1fe1c3430a1a09ffe92 100644 (file)
@@ -117,7 +117,7 @@ krb_mk_safe(in, out, length, key, sender, receiver)
 
     q = p;                     /* start for checksum stuff */
     /* stuff input length */
-    KRB4_PUT32(p, length);
+    KRB4_PUT32BE(p, length);
 
     /* make all the stuff contiguous for checksum */
     memcpy(p, in, length);
@@ -151,7 +151,7 @@ krb_mk_safe(in, out, length, key, sender, receiver)
      */
 
     /* stuff time sec */
-    KRB4_PUT32(p, msg_time_sec);
+    KRB4_PUT32BE(p, msg_time_sec);
 
 #ifdef NOENCRYPTION
     cksum = 0;
@@ -165,7 +165,7 @@ krb_mk_safe(in, out, length, key, sender, receiver)
 
     /* stuff checksum */
     for (i = 0; i < 4; i++)
-       KRB4_PUT32(p, big_cksum[i]);
+       KRB4_PUT32BE(p, big_cksum[i]);
 
     return p - out;            /* resulting size */
 }
diff --git a/src/lib/krb4/prot_common.c b/src/lib/krb4/prot_common.c
new file mode 100644 (file)
index 0000000..7d6571d
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * lib/krb4/prot_common.c
+ *
+ * Copyright 2001 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.
+ *
+ * Contains some common code used by multiple encoders/decoders.
+ */
+
+#include "krb.h"
+#include "prot.h"
+#include <string.h>
+
+/*
+ * encode_naminstrlm
+ *
+ * Takes input string triplet of a principal, encodes into PKT.
+ * Assumes that input strings are properly terminated.  If CHKLEN is
+ * non-zero, validate input string lengths against their respective
+ * limits.  The pointer P is the address of the moving pointer used by
+ * the caller, and is updated here.
+ *
+ * Returns zero on success, non-zero on failure.
+ *
+ * PKT->LENGTH is NOT updated.  The caller must update it.
+ */
+int KRB5_CALLCONV
+krb4prot_encode_naminstrlm(char *name, char *inst, char *realm,
+                          int chklen, /* check input str len? */
+                          KTEXT pkt, /* buffer to encode into */
+                          unsigned char **p /* moving pointer */)
+{
+    size_t namelen, instlen, realmlen;
+
+    namelen = strlen(name) + 1;
+    instlen = strlen(inst) + 1;
+    realmlen = strlen(realm) + 1;
+    if (chklen && (namelen > ANAME_SZ || instlen > INST_SZ
+                  || realmlen > REALM_SZ))
+       return -1;
+    if (*p - pkt->dat < namelen + instlen + realmlen)
+       return -1;
+    memcpy(*p, name, namelen);
+    *p += namelen;
+    memcpy(*p, inst, instlen);
+    *p += namelen;
+    memcpy(*p, realm, realmlen);
+    *p += namelen;
+    return 0;
+}
+
+/*
+ * decode_naminstrlm
+ *
+ * Grabs a string triplet corresponding to a principal.  The input
+ * buffer PKT should have its length properly set.  The pointer P is
+ * the address of the moving pointer used by the caller, and will be
+ * updated.  If any input pointer is NULL, merely skip the string.
+ *
+ * The output strings NAME, INST, and REALM are assumed to be of the
+ * correct sizes (ANAME_SZ, INST_SZ, REALM_SZ).
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+int KRB5_CALLCONV
+krb4prot_decode_naminstrlm(KTEXT pkt, /* buffer to decode from */
+                          unsigned char **p, /* moving pointer */
+                          char *name, char *inst, char *realm)
+{
+    int len;
+
+#define PKT_REMAIN (pkt->length - (*p - pkt->dat))
+    len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
+    if (len <= 0 || len > ANAME_SZ)
+       return KFAILURE;
+    if (name != NULL)
+       memcpy(name, *p, (size_t)len);
+    *p += len;
+
+    len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       return KFAILURE;
+    if (name != NULL)
+       memcpy(inst, *p, (size_t)len);
+    *p += len;
+
+    len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
+    if (len <= 0 || len > REALM_SZ)
+       return KFAILURE;
+    if (realm != NULL)
+       memcpy(realm, *p, (size_t)len);
+    *p += len;
+    return KSUCCESS;
+#undef PKT_REMAIN
+}
diff --git a/src/lib/krb4/prot_kdc.c b/src/lib/krb4/prot_kdc.c
new file mode 100644 (file)
index 0000000..3b36ddb
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * lib/krb4/prot_kdc.c
+ *
+ * Copyright 1985--1988, 2000, 2001 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.
+ *
+ * Contains the protocol encoders and decoders used by the KDC.
+ */
+
+#include "krb.h"
+#include "prot.h"
+#include <string.h>
+
+/*
+ * encode_kdc_reply
+ *
+ * Encodes a reply from the KDC to the client.
+ *
+ * Returns KSUCCESS on success, KFAILURE on failure.
+ *
+ * Caller is responsible for cleaning up OUTBUF.
+ *
+ * This packet layout description was originally in cr_auth_repl.c
+ *
+ *                     variable
+ * type                        or constant        data
+ * ----                        -----------        ----
+ * unsigned char       KRB_PROT_VERSION   protocol version number
+ * 
+ * unsigned char       AUTH_MSG_KDC_REPLY protocol message type
+ * 
+ * [least significant  HOST_BYTE_ORDER    sender's (server's) byte
+ *  bit of above field]                           order
+ * 
+ * string              pname              principal's name
+ * 
+ * string              pinst              principal's instance
+ * 
+ * string              prealm             principal's realm
+ * 
+ * unsigned long       time_ws            client's timestamp
+ * 
+ * unsigned char       n                  number of tickets
+ * 
+ * unsigned long       x_date             expiration date
+ * 
+ * unsigned char       kvno               master key version
+ * 
+ * short               cipher->length     cipher length
+ * 
+ * binary              cipher->dat        cipher data
+ */
+int
+krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
+                         long time_ws,
+                         int n, /* Number of tickets; 0 for krb4 (!) */
+                         unsigned long x_date, /* exp date */
+                         int kvno,
+                         KTEXT cipher, /* encrypted ticket */
+                         int chklen, /* check input str len? */
+                         int le, /* little-endian? */
+                         KTEXT outbuf)
+{
+    unsigned char *p;
+
+    p = outbuf->dat;
+    /* This is really crusty. */
+    if (n != 0)
+       *p++ = 3;
+    else
+       *p++ = KRB_PROT_VERSION;
+    /* little-endianness based on input, usually big-endian, though. */
+    *p++ = AUTH_MSG_KDC_REPLY | (le ? LSB_FIRST : MSB_FIRST);
+
+    if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
+                                  outbuf, &p))
+       return KFAILURE;
+
+    /* Check lengths */
+    if (cipher->length > 65535 || cipher->length < 0)
+       return KFAILURE;
+    if ((sizeof(outbuf->dat) - (p - outbuf->dat)
+        < (4                   /* timestamp */
+           + 1                 /* num of tickets */
+           + 4                 /* exp date */
+           + 1                 /* kvno */
+           + 2                 /* cipher->length */
+           + cipher->length))) /* cipher->dat */
+        return KFAILURE;
+
+    /* Workstation timestamp */
+    KRB4_PUT32(p, time_ws, le);
+
+    /* Number of tickets */
+    *p++ = n;
+
+    /* Expiration date */
+    KRB4_PUT32(p, x_date, le);
+
+    /* Now send the ciphertext and info to help decode it */
+    *p++ = kvno;
+    KRB4_PUT16(p, cipher->length, le);
+    memcpy(p, cipher->dat, (size_t)cipher->length);
+    p += cipher->length;
+
+    /* And return the packet */
+    outbuf->length = p - outbuf->dat;
+    return KSUCCESS;
+}
+
+/*
+ * encode_ciph
+ *
+ * Encodes a "cipher" that is to be included in a KDC reply message.
+ *
+ * Caller is responsible for cleaning up CIPH.
+ *
+ * Returns KSUCCESS on success, KFAILURE on failure.
+ *
+ * Packet format below is originally from cr_ciph.c.
+ *
+ *                     variable
+ * type                        or constant     data
+ * ----                        -----------     ----
+ * 8 bytes             session         session key for client, service
+ * 
+ * string              service         service name
+ * 
+ * string              instance        service instance
+ * 
+ * string              realm           KDC realm
+ * 
+ * unsigned char       life            ticket lifetime
+ * 
+ * unsigned char       kvno            service key version number
+ * 
+ * unsigned char       tkt->length     length of following ticket
+ * 
+ * data                        tkt->dat        ticket for service
+ * 
+ * 4 bytes             kdc_time        KDC's timestamp
+ *
+ * <=7 bytes           null            null pad to 8 byte multiple
+ */
+int
+krb4prot_encode_ciph(C_Block session,
+                    char *name, char *inst, char *realm,
+                    unsigned long life, int kvno,
+                    KTEXT tkt, /* ticket */
+                    unsigned long kdc_time,
+                    int chklen, /* check str lens? */
+                    int le,    /* little-endian? */
+                    KTEXT ciph) /* output buffer */
+{
+    unsigned char *p;
+
+    p = ciph->dat;
+    /*
+     * Assume that there will be >= 8 bytes in a KTEXT.  If there
+     * aren't, we have worse problems.
+     */
+    memcpy(p, session, 8);
+    p += 8;
+
+    if (krb4prot_encode_naminstrlm(name, inst, realm, chklen,
+                                  ciph, &p))
+       return KFAILURE;
+    if (tkt->length > 255 || tkt->length < 0)
+       return KFAILURE;
+    if ((sizeof(ciph->dat) - (p - ciph->dat)) / 8
+       < (1                    /* life */
+          + 1                  /* kvno */
+          + 1                  /* tkt->length */
+          + tkt->length        /* tkt->dat */
+          + 4                  /* kdc_time */
+          + 7) / 8)            /* roundoff */
+       return KFAILURE;
+
+    *p++ = life;
+    *p++ = kvno;
+    *p++ = tkt->length;
+
+    memcpy(p, tkt->dat, (size_t)tkt->length);
+    p += tkt->length;
+
+    KRB4_PUT32(p, kdc_time, le);
+
+    /* Guarantee null pad to multiple of 8 bytes */
+    memset(p, 0, 7);
+    ciph->length = (((p - ciph->dat) + 7) / 8) * 8;
+    return KSUCCESS;
+}
+
+/*
+ * encode_tkt
+ *
+ * Encode ticket to include in a "cipher".  Does not encrypt.
+ *
+ * Caller is responsible for cleaning TKT.
+ *
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ *
+ * Returns KSUCCESS on success, KFAILURE on failure.
+ *
+ * The following packet layout is from cr_tkt.c
+ *
+ *                     variable
+ * type                        or constant        data
+ * ----                        -----------        ----
+ * unsigned char       flags              namely, HOST_BYTE_ORDER
+ * 
+ * string              pname              client's name
+ * 
+ * string              pinstance          client's instance
+ * 
+ * string              prealm             client's realm
+ * 
+ * 4 bytes             paddress           client's address
+ * 
+ * 8 bytes             session            session key
+ * 
+ * 1 byte              life               ticket lifetime
+ * 
+ * 4 bytes             time_sec           KDC timestamp
+ * 
+ * string              sname              service's name
+ * 
+ * string              sinstance          service's instance
+ * 
+ * <=7 bytes           null               null pad to 8 byte multiple
+ */
+int
+krb4prot_encode_tkt(unsigned int flags,
+                   char *pname, char *pinst, char *prealm,
+                   unsigned long paddress,
+                   char *session,
+                   int life, long time_sec,
+                   char *sname, char *sinst,
+                   int chklen, /* check str lens? */
+                   int le,     /* little-endian? */
+                   KTEXT tkt)  /* output buf */
+{
+    struct in_addr paddr;
+    unsigned char *p;
+    size_t snamelen, sinstlen;
+
+    /* Be really paranoid. */
+    if (sizeof(paddr.s_addr) != 4)
+       return KFAILURE;
+
+    p = tkt->dat;
+    /*
+     * Assume at least one byte in a KTEXT.  If not, we have bigger
+     * problems.  Also, bitwise-OR in the little-endian flag.
+     */
+    *p++ = flags | (le ? LSB_FIRST : MSB_FIRST);
+
+    if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
+                                  tkt, &p))
+       return KFAILURE;
+
+    snamelen = strlen(sname) + 1;
+    sinstlen = strlen(sinst) + 1;
+    if (life > 255 || life < 0)
+       return KFAILURE;
+    if (chklen && (snamelen > ANAME_SZ || sinstlen > INST_SZ))
+       return KFAILURE;
+    if ((sizeof(tkt->dat) - (p - tkt->dat)) / 8
+       < (4                    /* address */
+          + 8                  /* session */
+          + 1                  /* life */
+          + 4                  /* issue time */
+          + snamelen + sinstlen
+          + 7) / 8)            /* roundoff */
+        return KFAILURE;
+
+    paddr.s_addr = paddress;
+    memcpy(p, &paddr.s_addr, sizeof(paddr.s_addr));
+    p += sizeof(paddr.s_addr);
+
+    memcpy(p, session, 8);
+    p += 8;
+    *p++ = life;
+    /* issue time */
+    KRB4_PUT32(p, time_sec, le);
+
+    memcpy(p, sname, snamelen);
+    p += snamelen;
+    memcpy(p, sinst, sinstlen);
+    p += sinstlen;
+
+    /* guarantee null padded ticket to multiple of 8 bytes */
+    memset(p, 0, 7);
+    tkt->length = ((p - tkt->dat + 7) / 8) * 8;
+    return KSUCCESS;
+}
+
+/*
+ * This routine is used by the Kerberos authentication server to
+ * create an error reply packet to send back to its client.
+ *
+ * It takes a pointer to the packet to be built, the name, instance,
+ * and realm of the principal, the client's timestamp, an error code
+ * and an error string as arguments.  Its return value is undefined.
+ *
+ * The packet is built in the following format:
+ * 
+ * type                        variable           data
+ *                     or constant
+ * ----                        -----------        ----
+ * unsigned char       req_ack_vno        protocol version number
+ * 
+ * unsigned char       AUTH_MSG_ERR_REPLY protocol message type
+ * 
+ * [least significant  HOST_BYTE_ORDER    sender's (server's) byte
+ * bit of above field]                    order
+ * 
+ * string              pname              principal's name
+ * 
+ * string              pinst              principal's instance
+ * 
+ * string              prealm             principal's realm
+ * 
+ * unsigned long       time_ws            client's timestamp
+ * 
+ * unsigned long       e                  error code
+ * 
+ * string              e_string           error text
+ */
+int
+krb4prot_encode_err_reply(char *pname, char *pinst, char *prealm,
+                         unsigned long time_ws,
+                         unsigned long err, /* error code */
+                         char *err_string, /* error text */
+                         int chklen, /* check str lens? */
+                         int le, /* little-endian? */
+                         KTEXT pkt) /* output buf */
+{
+    unsigned char *p;
+    size_t err_stringlen;
+
+    p = pkt->dat;
+    /* Assume >= 2 bytes in KTEXT. */
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_ERR_REPLY | (le ? LSB_FIRST : MSB_FIRST);
+
+    if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
+                                  pkt, &p))
+       return KFAILURE;
+
+    err_stringlen = strlen(err_string) + 1;
+    if ((sizeof(pkt->dat) - (p - pkt->dat))
+       < (4                    /* timestamp */
+          + 4                  /* err code */
+          + err_stringlen))
+       return KFAILURE;
+    /* ws timestamp */
+    KRB4_PUT32(p, time_ws, le);
+    /* err code */
+    KRB4_PUT32(p, err, le);
+    /* err text */
+    memcpy(p, err_string, err_stringlen);
+    p += err_stringlen;
+
+    /* And return */
+    pkt->length = p - pkt->dat;
+    return KSUCCESS;
+}
index 542828d79164f9d5f4643a585835a5c36d02ff98..abcf7da430f6d49fe9b1b7f0cff5a90813844883 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/krb4/rd_req.c
  *
- * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
  * Institute of Technology.  All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -239,7 +239,7 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn)
         mutual = 0;
 #endif /* lint */
     s_kvno = *ptr++;           /* get server key version */
-    len = krb_strnlen((char *)ptr, AUTHENT_REMAIN) + 1;
+    len = krb4int_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 */
@@ -277,15 +277,15 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn)
            return RD_AP_UNDEC;
 #endif /* !NOENCRYPTION */
 
-       len = krb_strnlen(realm, sizeof(st_rlm)) + 1;
+       len = krb4int_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;
+       len = krb4int_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;
+       len = krb4int_strnlen(instance, sizeof(st_inst)) + 1;
        if (len <= 0)
            return KFAILURE;
        memcpy(st_inst, instance, (size_t)len);
@@ -366,17 +366,17 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn)
 
     ret = RD_AP_MODIFIED;
 
-    len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1;
+    len = krb4int_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;
+    len = krb4int_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;
+    len = krb4int_strnlen((char *)ptr, REQID_REMAIN) + 1;
     if (len <= 0 || len > REALM_SZ)
        goto cleanup;
     memcpy(r_realm, ptr, (size_t)len); /* Authentication name */
index b7339123e76f7a9659fa04546e2089b4cd653b90..5dc80115ccc8588d060ef11c60e297366a6fd334 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/krb4/strnlen.c
  *
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
 
 #include <stddef.h>
 #include "krb.h"
+#include "prot.h"
+
 /*
- * krb_strnlen()
+ * krb4int_strnlen()
  *
  * Return the length of the string if a NUL is found in the first n
  * bytes, otherwise, -1.
  */
 
 int KRB5_CALLCONV
-krb_strnlen(const char *s, int n)
+krb4int_strnlen(const char *s, int n)
 {
     int i = 0;