summaryrefslogtreecommitdiffstats
path: root/src/lib/krb4/g_in_tkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb4/g_in_tkt.c')
-rw-r--r--src/lib/krb4/g_in_tkt.c337
1 files changed, 185 insertions, 152 deletions
diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c
index 361273c9d7..b7ab0dfc43 100644
--- a/src/lib/krb4/g_in_tkt.c
+++ b/src/lib/krb4/g_in_tkt.c
@@ -1,22 +1,35 @@
/*
- * g_in_tkt.c
+ * lib/krb4/g_in_tkt.c
*
- * Copyright 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1986, 1987, 1988, 2000 by the Massachusetts Institute of
+ * Technology. All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
*/
-#include "mit-copyright.h"
#include "krb.h"
#include "des.h"
#include "prot.h"
#include <string.h>
-extern int swap_bytes;
-
/* Define a couple of function types including parameters. These
are needed on MS-Windows to convert arguments of the function pointers
to the proper types during calls. These declarations are found
@@ -39,40 +52,36 @@ typedef int (*decrypt_tkt_type) PROTOTYPE ((char *, char *, char *, char *,
static int
decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
- char *user;
- char *instance;
- char *realm;
- char *arg;
- key_proc_type key_proc;
- KTEXT *cipp;
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ key_proc_type key_proc;
+ KTEXT *cipp;
{
KTEXT cip = *cipp;
C_Block key; /* Key for decrypting cipher */
Key_schedule key_s;
+ register int rc;
#ifndef NOENCRYPTION
/* Attempt to decrypt it */
#endif
-
/* generate a key from the supplied arg or password. */
-
- {
- register int rc;
- rc = (*key_proc) (user,instance,realm,arg,key);
- if (rc)
- return(rc);
- }
-
+ rc = (*key_proc)(user, instance, realm, arg, key);
+ if (rc)
+ return rc;
+
#ifndef NOENCRYPTION
- key_sched(key,key_s);
- pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
- (long) cip->length,key_s,(C_Block *)key,0);
+ key_sched(key, key_s);
+ pcbc_encrypt((C_Block *)cip->dat, (C_Block *)cip->dat,
+ (long)cip->length, key_s, (C_Block *)key, 0);
#endif /* !NOENCRYPTION */
/* Get rid of all traces of key */
- memset((char *)key, 0,sizeof(key));
- memset((char *)key_s, 0,sizeof(key_s));
+ memset(key, 0, sizeof(key));
+ memset(key_s, 0, sizeof(key_s));
- return(0);
+ return 0;
}
/*
@@ -118,7 +127,7 @@ decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
int
krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
- preauth_p, preauth_len, cip)
+ preauth_p, preauth_len, cip, byteorder)
char *user;
char *instance;
char *realm;
@@ -128,13 +137,15 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
char *preauth_p;
int preauth_len;
KTEXT cip;
+ int *byteorder;
{
KTEXT_ST pkt_st;
KTEXT pkt = &pkt_st; /* Packet to KDC */
KTEXT_ST rpkt_st;
KTEXT rpkt = &rpkt_st; /* Returned packet */
- unsigned char *v = pkt->dat; /* Prot vers no */
- unsigned char *t = (pkt->dat+1); /* Prot msg type */
+ unsigned char *p;
+ size_t userlen, instlen, realmlen, servicelen, sinstlen;
+ unsigned KRB4_32 t_local;
int msg_byte_order;
int kerror;
@@ -142,112 +153,127 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
unsigned long exp_date;
#endif
unsigned long rep_err_code;
+ unsigned long cip_len;
unsigned int t_switch;
- unsigned KRB4_32 t_local; /* Must be 4 bytes long for memcpy below! */
+ int i, len;
/* BUILD REQUEST PACKET */
- /* Set up the fixed part of the packet */
- *v = (unsigned char) KRB_PROT_VERSION;
- *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
- *t |= HOST_BYTE_ORDER;
+ p = pkt->dat;
+ userlen = strlen(user) + 1;
+ instlen = strlen(instance) + 1;
+ realmlen = strlen(realm) + 1;
+ servicelen = strlen(service) + 1;
+ sinstlen = strlen(sinstance) + 1;
/* Make sure the ticket data will fit into the buffer. */
- if(sizeof(pkt->dat) < 2 + /* protocol version + flags */
- 3 + strlen(user) +
- 1 + strlen(instance) +
- 1 + strlen(realm) +
- 4 + /* timestamp */
- 1 + /* lifetime */
- 1 + strlen(service) +
- 1 + strlen(sinstance) +
- preauth_len) {
+ if (sizeof(pkt->dat) < (1 + 1 + userlen + instlen + realmlen
+ + 4 + 1 + servicelen + sinstlen
+ + preauth_len)) {
pkt->length = 0;
return INTK_ERR;
}
+ /* Set up the fixed part of the packet */
+ *p++ = KRB_PROT_VERSION;
+ *p++ = AUTH_MSG_KDC_REQUEST;
+
/* Now for the variable info */
- (void) strcpy((char *)(pkt->dat+2),user); /* aname */
- pkt->length = 3 + strlen(user);
- (void) strcpy((char *)(pkt->dat+pkt->length),
- instance); /* instance */
- pkt->length += 1 + strlen(instance);
- (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
- pkt->length += 1 + strlen(realm);
+ memcpy(p, user, userlen);
+ p += userlen;
+ memcpy(p, instance, instlen);
+ p += instlen;
+ memcpy(p, realm, realmlen);
+ p += realmlen;
/* timestamp */
t_local = TIME_GMT_UNIXSEC;
- memcpy((char *)(pkt->dat+pkt->length), (char *)&t_local, 4);
- pkt->length += 4;
+ KRB4_PUT32(p, t_local);
- *(pkt->dat+(pkt->length)++) = (char) life;
- (void) strcpy((char *)(pkt->dat+pkt->length),service);
- pkt->length += 1 + strlen(service);
- (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ *p++ = life;
- pkt->length += 1 + strlen(sinstance);
+ memcpy(p, service, servicelen);
+ p += servicelen;
+ memcpy(p, sinstance, sinstlen);
+ p += sinstlen;
if (preauth_len)
- memcpy((char *)(pkt->dat+pkt->length), preauth_p, preauth_len);
- pkt->length += preauth_len;
+ memcpy(p, preauth_p, (size_t)preauth_len);
+ p += preauth_len;
- rpkt->length = 0;
+ pkt->length = p - pkt->dat;
/* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+ rpkt->length = 0;
+ kerror = send_to_kdc(pkt, rpkt, realm);
+ if (kerror)
+ return kerror;
- if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+ p = rpkt->dat;
+#define RPKT_REMAIN (rpkt->length - (p - rpkt->dat))
/* check packet version of the returned packet */
- if (pkt_version(rpkt) != KRB_PROT_VERSION)
- return(INTK_PROT);
-
- /* Check byte order */
- msg_byte_order = pkt_msg_type(rpkt) & 1;
- swap_bytes = 0;
- if (msg_byte_order != HOST_BYTE_ORDER) {
- swap_bytes++;
- }
+ if (RPKT_REMAIN < 1 + 1)
+ return INTK_PROT;
+ if (*p++ != KRB_PROT_VERSION)
+ return INTK_PROT;
/* This used to be
switch (pkt_msg_type(rpkt) & ~1) {
but SCO 3.2v4 cc compiled that incorrectly. */
- t_switch = pkt_msg_type(rpkt);
+ t_switch = *p++;
+ /* Check byte order */
+ msg_byte_order = t_switch & 1;
t_switch &= ~1;
switch (t_switch) {
case AUTH_MSG_KDC_REPLY:
break;
case AUTH_MSG_ERR_REPLY:
- memcpy((char *) &rep_err_code, pkt_err_code(rpkt), 4);
- if (swap_bytes) rep_err_code = krb4_swab32(rep_err_code);
- return((int)rep_err_code);
+ if (RPKT_REMAIN < 4)
+ return INTK_PROT;
+ KRB4_GET32(rep_err_code, p, msg_byte_order);
+ return rep_err_code;
default:
- return(INTK_PROT);
+ return INTK_PROT;
}
/* EXTRACT INFORMATION FROM RETURN PACKET */
-#if 0
- /* not used */
- /* get the principal's expiration date */
- memcpy((char *) &exp_date, pkt_x_date(rpkt), sizeof(exp_date));
- if (swap_bytes) exp_data = krb4_swab32(exp_date);
-#endif
+ /*
+ * Skip over some stuff (3 strings and various integers -- see
+ * cr_auth_repl.c for details).
+ */
+ for (i = 0; i < 3; i++) {
+ len = krb_strnlen((char *)p, RPKT_REMAIN) + 1;
+ if (len <= 0)
+ return INTK_PROT;
+ p += len;
+ }
+ if (RPKT_REMAIN < 4 + 1 + 4 + 1)
+ return INTK_PROT;
+ p += 4 + 1 + 4 + 1;
/* Extract the ciphertext */
- cip->length = pkt_clen(rpkt); /* let clen do the swap */
-
- if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
- return(INTK_ERR); /* no appropriate error code
- currently defined for INTK_ */
- /* copy information from return packet into "cip" */
- memcpy((char *)(cip->dat), (char *) pkt_cipher(rpkt), cip->length);
-
+ if (RPKT_REMAIN < 2)
+ return INTK_PROT;
+ KRB4_GET16(cip_len, p, msg_byte_order);
+ if (RPKT_REMAIN < cip_len)
+ return INTK_ERR;
+ /*
+ * RPKT_REMAIN will always be non-negative and at most the maximum
+ * possible value of cip->length, so this assignment is safe.
+ */
+ cip->length = cip_len;
+ memcpy(cip->dat, p, (size_t)cip->length);
+ p += cip->length;
+
+ *byteorder = msg_byte_order;
return INTK_OK;
}
-
int
-krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
+krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip,
+ byteorder)
char *user;
char *instance;
char *realm;
@@ -255,9 +281,11 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
char *sinstance;
int life;
KTEXT cip;
+ int byteorder;
{
- char *ptr;
+ unsigned char *ptr;
C_Block ses; /* Session key for tkt */
+ int len;
int kvno; /* Kvno for session key */
char s_name[SNAME_SZ];
char s_instance[INST_SZ];
@@ -270,79 +298,80 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
int kerror;
int lifetime;
- ptr = (char *) cip->dat;
+ ptr = cip->dat;
+ /* Assume that cip->length >= 0 for now. */
+#define CIP_REMAIN (cip->length - (ptr - cip->dat))
- /* extract session key */
- memcpy((char *)ses, ptr, 8);
+ /* Skip session key for now */
+ if (CIP_REMAIN < 8)
+ return INTK_BADPW;
ptr += 8;
- if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
- return(INTK_BADPW);
-
/* extract server's name */
- (void) strncpy(s_name,ptr, sizeof(s_name)-1);
- s_name[sizeof(s_name)-1] = '\0';
- ptr += strlen(s_name) + 1;
-
- if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
- return(INTK_BADPW);
+ len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+ if (len <= 0 || len > sizeof(s_name))
+ return INTK_BADPW;
+ memcpy(s_name, ptr, (size_t)len);
+ ptr += len;
/* extract server's instance */
- (void) strncpy(s_instance,ptr, sizeof(s_instance)-1);
- s_instance[sizeof(s_instance)-1] = '\0';
- ptr += strlen(s_instance) + 1;
-
- if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
- return(INTK_BADPW);
+ len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+ if (len <= 0 || len > sizeof(s_instance))
+ return INTK_BADPW;
+ memcpy(s_instance, ptr, (size_t)len);
+ ptr += len;
/* extract server's realm */
- (void) strncpy(rlm,ptr, sizeof(rlm));
- rlm[sizeof(rlm)-1] = '\0';
- ptr += strlen(rlm) + 1;
+ len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1;
+ if (len <= 0 || len > sizeof(rlm))
+ return INTK_BADPW;
+ memcpy(rlm, ptr, (size_t)len);
+ ptr += len;
/* extract ticket lifetime, server key version, ticket length */
/* be sure to avoid sign extension on lifetime! */
- lifetime = (unsigned char) ptr[0];
- kvno = (unsigned char) ptr[1];
- tkt->length = (unsigned char) ptr[2];
- ptr += 3;
-
- if ((tkt->length < 0) ||
- ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
- return(INTK_BADPW);
+ if (CIP_REMAIN < 3)
+ return INTK_BADPW;
+ lifetime = *ptr++;
+ kvno = *ptr++;
+ tkt->length = *ptr++;
/* extract ticket itself */
- memcpy((char *)(tkt->dat), ptr, tkt->length);
+ if (CIP_REMAIN < tkt->length)
+ return INTK_BADPW;
+ memcpy(tkt->dat, ptr, (size_t)tkt->length);
ptr += tkt->length;
- if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
- strcmp(rlm, realm)) /* not what we asked for */
- return(INTK_ERR); /* we need a better code here XXX */
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance)
+ || strcmp(rlm, realm)) /* not what we asked for */
+ return INTK_ERR; /* we need a better code here XXX */
/* check KDC time stamp */
- memcpy((char *)&kdc_time, ptr, 4); /* Time (coarse) */
- if (swap_bytes) kdc_time = krb4_swab32(kdc_time);
-
- ptr += 4;
+ if (CIP_REMAIN < 4)
+ return INTK_BADPW;
+ KRB4_GET32(kdc_time, ptr, byteorder);
t_local = TIME_GMT_UNIXSEC;
t_diff = t_local - kdc_time;
- if (t_diff < 0) t_diff = -t_diff; /* Absolute value of difference */
+ if (t_diff < 0)
+ t_diff = -t_diff; /* Absolute value of difference */
if (t_diff > CLOCK_SKEW) {
- return(RD_AP_TIME); /* XXX should probably be better
- code */
+ return RD_AP_TIME; /* XXX should probably be better code */
}
/* initialize ticket cache */
if (in_tkt(user,instance) != KSUCCESS)
- return(INTK_ERR);
-
+ return INTK_ERR;
/* stash ticket, session key, etc. for future use */
- if (kerror = krb_save_credentials(s_name, s_instance, rlm, ses,
- lifetime, kvno, tkt, t_local))
- return(kerror);
+ memcpy(ses, cip->dat, 8);
+ kerror = krb_save_credentials(s_name, s_instance, rlm, ses,
+ lifetime, kvno,
+ tkt, (KRB4_32)t_local);
+ memset(ses, 0, 8);
+ if (kerror)
+ return kerror;
- return(INTK_OK);
+ return INTK_OK;
}
int
@@ -363,21 +392,26 @@ krb_get_in_tkt_preauth(user, instance, realm, service, sinstance, life,
KTEXT_ST cip_st;
KTEXT cip = &cip_st; /* Returned Ciphertext */
int kerror;
- if (kerror = krb_mk_in_tkt_preauth(user, instance, realm,
- service, sinstance,
- life, preauth_p, preauth_len, cip))
- return kerror;
+ int byteorder;
+ kerror = krb_mk_in_tkt_preauth(user, instance, realm,
+ service, sinstance,
+ life, preauth_p, preauth_len,
+ cip, &byteorder);
+ if (kerror)
+ return kerror;
/* Attempt to decrypt the reply. */
if (decrypt_proc == NULL)
decrypt_tkt (user, instance, realm, arg, key_proc, &cip);
else
(*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
-
- return
- krb_parse_in_tkt(user, instance, realm, service, sinstance,
- life, cip);
+ kerror = krb_parse_in_tkt(user, instance, realm,
+ service, sinstance,
+ life, cip, byteorder);
+ /* stomp stomp stomp */
+ memset(cip->dat, 0, (size_t)cip->length);
+ return kerror;
}
int
@@ -395,7 +429,6 @@ krb_get_in_tkt(user, instance, realm, service, sinstance, life,
{
return krb_get_in_tkt_preauth(user, instance, realm,
service, sinstance, life,
- key_proc, decrypt_proc, arg, (char *)0, 0);
-
+ key_proc, decrypt_proc, arg,
+ (char *)NULL, 0);
}
-