+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
$(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) \
$(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 \
/*
- * 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>
*/
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 */
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;
}
/*
- * 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>
*
*/
+int
create_ciph(c, session, service, instance, realm, life, kvno, tkt,
kdc_time, key)
KTEXT c; /* Text block to hold ciphertext */
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;
}
/*
- * 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>
{
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 */
/*
- * 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>
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;
}
-/*
- * 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"
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
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 */
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);
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;
/*
- * 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"
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 */
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? */
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
}
#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) {
}
#endif
- return(KSUCCESS);
+cleanup:
+ if (kret != KSUCCESS) {
+ memset(session, 0, sizeof(session));
+ memset(tkt->dat, 0, (size_t)tkt->length);
+ return kret;
+ }
+ return KSUCCESS;
}
/*
- * 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.
* 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;
* 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;
}
/*
- * 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
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;
}
/*
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;
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;
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;
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];
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
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
{
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);
}
-
/*
- * 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"
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
}
#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
{
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;
}
/*
- * 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;
}
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;
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
/*
*/
*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;
}
char *preauth_p;
int preauth_len;
{
- free(preauth_p);
- return;
+ free(preauth_p);
+ return;
}
/*
- * 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.
* Steve Miller Project Athena MIT/DEC
*/
-#include "mit-copyright.h"
-
#include <stdio.h>
#include <string.h>
*/
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
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 */
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);
/* 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
* 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
*/
#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 */
}
/*
- * 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"
*/
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 */
{
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));
* 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;
}
/*
int olife = lifetime;
lifetime = newval;
- return(olife);
+ return olife;
}
/*
- * 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
* Steve Miller Project Athena MIT/DEC
*/
-#include "mit-copyright.h"
#include <stdio.h>
#include <string.h>
*/
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!
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);
/* 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 */
}
/*
- * 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 */
}
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;
}
/*
- * 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
* Steve Miller Project Athena MIT/DEC
*/
-#include "mit-copyright.h"
-
/* system include files */
#include <stdio.h>
#include <string.h>
*/
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 */
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
#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 */
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
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.
/* 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
/*
- * 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"
static krb5_keyblock srv_k5key;
int
-krb_set_key(key,cvt)
+krb_set_key(key, cvt)
char *key;
int 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 */
}
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(),
*/
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 */
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
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
* 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)
}
}
-
#ifdef KRB_CRYPT_DEBUG
if (krb_ap_req_debug) {
log("Ticket Contents.");
#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 */
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)
#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;
}
/*
- * 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.
* Steve Miller Project Athena MIT/DEC
*/
-#include "mit-copyright.h"
-
/* system include files */
#include <stdio.h>
#include <string.h>
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 */
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
* 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 */
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 */
}
DEB (("Recvfrom error %d\n", SOCKET_ERRNO));
return 0;
}
+ rpkt->length = recvresult;
#ifdef DEBUG
if (krb_debug) {
printf("received packet from ");
--- /dev/null
+/*
+ * 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;
+}