summaryrefslogtreecommitdiffstats
path: root/src/lib/krb4
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2000-06-27 21:00:02 +0000
committerKen Raeburn <raeburn@mit.edu>2000-06-27 21:00:02 +0000
commit9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff (patch)
tree2d4fd8b1bf6272f1286ffb7af9ae1d351a347e71 /src/lib/krb4
parent0d54ee19a3e5a159f0b86097ebfe193a0d9c26d8 (diff)
downloadkrb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.tar.gz
krb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.tar.xz
krb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.zip
pullup from 1.2 branch
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12442 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb4')
-rw-r--r--src/lib/krb4/ChangeLog83
-rw-r--r--src/lib/krb4/Password.c9
-rw-r--r--src/lib/krb4/configure.in2
-rw-r--r--src/lib/krb4/cr_auth_repl.c10
-rw-r--r--src/lib/krb4/cr_ciph.c11
-rw-r--r--src/lib/krb4/cr_death_pkt.c5
-rw-r--r--src/lib/krb4/cr_err_repl.c9
-rw-r--r--src/lib/krb4/cr_tkt.c23
-rw-r--r--src/lib/krb4/decomp_tkt.c10
-rw-r--r--src/lib/krb4/dest_tkt.c5
-rw-r--r--src/lib/krb4/g_ad_tkt.c45
-rw-r--r--src/lib/krb4/g_in_tkt.c14
-rw-r--r--src/lib/krb4/g_krbhst.c8
-rw-r--r--src/lib/krb4/g_krbrlm.c3
-rw-r--r--src/lib/krb4/g_pw_in_tkt.c1
-rw-r--r--src/lib/krb4/in_tkt.c5
-rw-r--r--src/lib/krb4/kntoln.c7
-rw-r--r--src/lib/krb4/kparse.c73
-rw-r--r--src/lib/krb4/kuserok.c7
-rw-r--r--src/lib/krb4/mk_auth.c6
-rw-r--r--src/lib/krb4/mk_err.c8
-rw-r--r--src/lib/krb4/mk_req.c13
-rw-r--r--src/lib/krb4/rd_req.c44
-rw-r--r--src/lib/krb4/realmofhost.c8
-rw-r--r--src/lib/krb4/recvauth.c7
-rw-r--r--src/lib/krb4/send_to_kdc.c3
-rw-r--r--src/lib/krb4/sendauth.c3
-rw-r--r--src/lib/krb4/tf_util.c5
-rw-r--r--src/lib/krb4/win_store.c20
29 files changed, 356 insertions, 91 deletions
diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog
index 29d985f31..c1d81d3b4 100644
--- a/src/lib/krb4/ChangeLog
+++ b/src/lib/krb4/ChangeLog
@@ -1,3 +1,86 @@
+2000-06-09 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Check for strdup().
+
+ * kparse.c: Remove strsave() and replace with an inlined static
+ version of strdup() if HAVE_STRDUP is not defined.
+
+ * g_ad_tkt.c (get_ad_tkt): ptr may be signed; cast while
+ assigning to larger types. [from Charles Hannum by way of
+ ghudson]
+
+2000-05-23 Ken Raeburn <raeburn@mit.edu>
+
+ * decomp_tkt.c (dcmp_tkt_int): Add a couple more length checks.
+ Reject names that are exactly ANAME_SZ (etc) bytes long without
+ the trailing nul, because krb.h says the *_SZ macros are "maximum
+ sizes ... +1".
+ * mk_auth.c (krb_mk_auth): Force nul termination of inst.
+ * sendauth.c (krb_sendauth): Force nul termination of srv_inst.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * Password.c (GetUserInfo): Truncate user name if it's too long
+ to fit.
+ * cr_auth_repl.c (cr_auth_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_ciph.c (create_ciph): Ditto.
+ * cr_death_pkt.c (krb_create_death_packet): Truncate "aname" to
+ make it fit into the packet's data buffer.
+ * cr_err_repl.c (cr_err_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_tkt.c (krb_create_ticket): Ditto.
+ * g_ad_tkt.c (get_ad_tkt): Stop if data being added to buffer
+ would overflow it. Add more sanity checks when decomposing the
+ credential received.
+ * g_in_tkt.c (krb_mk_in_tkt_preauth): Bail if the request packet
+ won't fit into its buffer.
+ * g_krbhst.c (get_krbhst_default): Truncate the guessed KDC's
+ hostname if it is too long.
+ * g_pw_in_tkt.c: Remove useless strcpy() prototype.
+ * kntoln.c (krb_kntoln): Don't overflow buffer "lname".
+ * mk_err.c (krb_mk_err): Return the needed buffer length if the
+ pointer passed in is NULL.
+ * mk_req.c (krb_mk_req): Bail if the reply packet won't
+ fit into its buffer.
+ * rd_req.c (krb_rd_req): Sanity check the realm name being read,
+ and truncate the service name, nstance, and realm from credential
+ read from keytab.
+ * realmofhost.c (krb_realmofhost): Truncate realm names read
+ from file if they are too long.
+ * send_to_kdc.c (send_to_kdc): Truncate passed-in realm name.
+
+2000-05-08 Ken Raeburn <raeburn@mit.edu>
+
+ * rd_req.c (krb_rd_req): Mask length byte with 0xff in case the
+ length is over 127 and char is signed.
+
+ * recvauth.c (krb_recvauth): If the number of bytes to be read
+ from the net is not positive, just return an error.
+
+2000-05-03 Tom Yu <tlyu@mit.edu>
+
+ * cr_tkt.c: Delete prototype for krb_cr_tkt_int(), since the
+ definition is K&R style and contains narrow types. Thank you
+ HP/UX for having a compiler that actually makes this a fatal
+ error.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * dest_tkt.c (dest_tkt): Don't overflow buffer "shmidname".
+ * in_tkt.c (in_tkt): Don't overflow buffer "shmidname".
+ * kuserok.c (kuserok): Don't overflow buffer "pbuf".
+ * tf_util.c (tf_init): Don't overflow buffer "shmidname".
+ * win_store.c (krb__get_cnffile): Don't overflow buffers "defname"
+ and "cnfname".
+ (krb__get_realmsfile): Don't overflow buffers "defname" and
+ "realmsname".
+
+2000-04-28 Tom Yu <tlyu@mit.edu>
+
+ * rd_req.c (krb_rd_req): Fix some uses of strcpy().
+
2000-03-12 Ezra Peisach <epeisach@mit.edu>
* cr_tkt.c (krb_cr_tkt_int): Add static prototype.
diff --git a/src/lib/krb4/Password.c b/src/lib/krb4/Password.c
index b29663006..5862e0e65 100644
--- a/src/lib/krb4/Password.c
+++ b/src/lib/krb4/Password.c
@@ -177,7 +177,8 @@ OSErr GetUserInfo( char *password )
// already got a password, just get the initial ticket
//////////////////////////////////////////////////////
if (*gPassword) {
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName)-1);
+ UserName[sizeof(UserName) - 1] = '\0';
/* FIXME jcm - if we have a password then no dialog
comes up for setting the uinstance. */
rc = kname_parse(uname, uinst, realm, UserName);
@@ -201,7 +202,8 @@ OSErr GetUserInfo( char *password )
}
// Insert user's name in dialog
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
if (*UserName) {
tempStr[0] = strlen(UserName);
memcpy( &(tempStr[1]), UserName, tempStr[0]);
@@ -417,7 +419,8 @@ CacheInitialTicket( serviceName )
if (!serviceName || (serviceName[0] == '\0'))
return err;
- strcpy (UserName, krb_get_default_user());
+ strncpy (UserName, krb_get_default_user(), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
err = kname_parse(uname, uinst, urealm, UserName);
if (err) return err;
diff --git a/src/lib/krb4/configure.in b/src/lib/krb4/configure.in
index 0434c7d0e..59937e1ac 100644
--- a/src/lib/krb4/configure.in
+++ b/src/lib/krb4/configure.in
@@ -38,7 +38,7 @@ else
AC_DEFINE(BITS32)
fi
AC_DEFINE(KRB4_USE_KEYTAB)
-AC_HAVE_FUNCS(strsave seteuid setreuid setresuid)
+AC_HAVE_FUNCS(strdup seteuid setreuid setresuid)
AC_PROG_AWK
KRB5_BUILD_LIBOBJS
KRB5_BUILD_LIBRARY_WITH_DEPS
diff --git a/src/lib/krb4/cr_auth_repl.c b/src/lib/krb4/cr_auth_repl.c
index 5203506d3..a0562d96f 100644
--- a/src/lib/krb4/cr_auth_repl.c
+++ b/src/lib/krb4/cr_auth_repl.c
@@ -83,6 +83,16 @@ create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
if (n != 0)
*v = 3;
+ /* 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) {
+ pkt->length = 0;
+ return NULL;
+ }
+
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2), pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_ciph.c b/src/lib/krb4/cr_ciph.c
index d15a4e0fd..d9c751271 100644
--- a/src/lib/krb4/cr_ciph.c
+++ b/src/lib/krb4/cr_ciph.c
@@ -71,6 +71,17 @@ create_ciph(c, session, service, instance, realm, life, kvno, tkt,
ptr = (char *) 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) {
+ c->length = 0;
+ return(KFAILURE);
+ }
+
memcpy(ptr, (char *) session, 8);
ptr += 8;
diff --git a/src/lib/krb4/cr_death_pkt.c b/src/lib/krb4/cr_death_pkt.c
index 8daa2d688..c3562675d 100644
--- a/src/lib/krb4/cr_death_pkt.c
+++ b/src/lib/krb4/cr_death_pkt.c
@@ -52,8 +52,9 @@ krb_create_death_packet(a_name)
*v = (unsigned char) KRB_PROT_VERSION;
*t = (unsigned char) AUTH_MSG_DIE;
*t |= HOST_BYTE_ORDER;
- (void) strcpy((char *) (pkt->dat+2),a_name);
- pkt->length = 3 + strlen(a_name);
+ (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);
return pkt;
}
#endif /* DEBUG */
diff --git a/src/lib/krb4/cr_err_repl.c b/src/lib/krb4/cr_err_repl.c
index 7f68bda76..54e87d82e 100644
--- a/src/lib/krb4/cr_err_repl.c
+++ b/src/lib/krb4/cr_err_repl.c
@@ -78,6 +78,15 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
*t = (unsigned char) AUTH_MSG_ERR_REPLY;
*t |= HOST_BYTE_ORDER;
+ /* 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)) {
+ pkt->length = 0;
+ return;
+ }
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2),pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c
index 0293e105f..34bec4801 100644
--- a/src/lib/krb4/cr_tkt.c
+++ b/src/lib/krb4/cr_tkt.c
@@ -15,12 +15,6 @@
#include <string.h>
#include <krb5.h>
-static int krb_cr_tkt_int PROTOTYPE((KTEXT tkt, unsigned char flags,
- char *pname, char *pinstance,
- char *prealm, long paddress,
- char *session, short life, long time_sec,
- 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
@@ -141,6 +135,23 @@ krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress,
register char *data; /* running index into ticket */
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 */
+ 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);
diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c
index 04d3298ad..06e9e316c 100644
--- a/src/lib/krb4/decomp_tkt.c
+++ b/src/lib/krb4/decomp_tkt.c
@@ -192,17 +192,17 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
tkt_swap_bytes++;
- if (strlen(ptr) > ANAME_SZ)
+ if (strlen(ptr) >= ANAME_SZ)
return(KFAILURE);
(void) strcpy(pname,ptr); /* pname */
ptr += strlen(pname) + 1;
- if (strlen(ptr) > INST_SZ)
+ if (strlen(ptr) >= INST_SZ)
return(KFAILURE);
(void) strcpy(pinstance,ptr); /* instance */
ptr += strlen(pinstance) + 1;
- if (strlen(ptr) > REALM_SZ)
+ if (strlen(ptr) >= REALM_SZ)
return(KFAILURE);
(void) strcpy(prealm,ptr); /* realm */
ptr += strlen(prealm) + 1;
@@ -229,9 +229,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (tkt_swap_bytes)
*time_sec = krb4_swab32(*time_sec);
+ if (strlen(ptr) >= ANAME_SZ)
+ return KFAILURE;
(void) strcpy(sname,ptr); /* service name */
ptr += 1 + strlen(sname);
+ if (strlen (ptr) >= INST_SZ)
+ return KFAILURE;
(void) strcpy(sinstance,ptr); /* instance */
ptr += 1 + strlen(sinstance);
diff --git a/src/lib/krb4/dest_tkt.c b/src/lib/krb4/dest_tkt.c
index 70578183e..50c1352b2 100644
--- a/src/lib/krb4/dest_tkt.c
+++ b/src/lib/krb4/dest_tkt.c
@@ -87,8 +87,9 @@ out:
/*
* handle the shared memory case
*/
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strcat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
return(i);
#endif /* TKT_SHMEM */
diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c
index b3abb2ddc..afcd0c6f8 100644
--- a/src/lib/krb4/g_ad_tkt.c
+++ b/src/lib/krb4/g_ad_tkt.c
@@ -19,6 +19,19 @@
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.
@@ -136,11 +149,22 @@ get_ad_tkt(service,sinstance,realm,lifetime)
return(AD_NOTGT);
/* 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;
+
+ if(pkt->length + 1 > sizeof(pkt->dat))
+ return(INTK_ERR);
*(pkt->dat+(pkt->length)++) = (char) 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);
+
+ 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);
@@ -199,18 +223,27 @@ get_ad_tkt(service,sinstance,realm,lifetime)
memcpy((char *)ses, ptr, 8);
ptr += 8;
- (void) strcpy(s_name,ptr);
+ 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;
- (void) strcpy(s_instance,ptr);
+ 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;
- (void) strcpy(rlm,ptr);
+ 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 long) ptr[0];
- kvno = (unsigned long) ptr[1];
- tkt->length = (int) ptr[2];
+ 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;
diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c
index c9d618382..361273c9d 100644
--- a/src/lib/krb4/g_in_tkt.c
+++ b/src/lib/krb4/g_in_tkt.c
@@ -152,6 +152,20 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
*t = (unsigned char) AUTH_MSG_KDC_REQUEST;
*t |= HOST_BYTE_ORDER;
+ /* 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) {
+ pkt->length = 0;
+ return INTK_ERR;
+ }
+
/* Now for the variable info */
(void) strcpy((char *)(pkt->dat+2),user); /* aname */
pkt->length = 3 + strlen(user);
diff --git a/src/lib/krb4/g_krbhst.c b/src/lib/krb4/g_krbhst.c
index 529ac0769..4e0fd6d76 100644
--- a/src/lib/krb4/g_krbhst.c
+++ b/src/lib/krb4/g_krbhst.c
@@ -52,9 +52,11 @@ get_krbhst_default(h, r, n)
int n;
{
if (n==1) {
- (void) strcpy(h,KRB_HOST);
- (void) strcat(h,".");
- (void) strcat(h,r); /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
+ (void) strncpy(h,KRB_HOST,MAXHOSTNAMELEN-1);
+ h[MAXHOSTNAMELEN-1] = '\0';
+ (void) strncat(h,".",MAXHOSTNAMELEN-1-strlen(h));
+ (void) strncat(h,r,MAXHOSTNAMELEN-1-strlen(h));
+ /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_krbrlm.c b/src/lib/krb4/g_krbrlm.c
index 983150ce4..c75023176 100644
--- a/src/lib/krb4/g_krbrlm.c
+++ b/src/lib/krb4/g_krbrlm.c
@@ -44,7 +44,8 @@ krb_get_lrealm(r,n)
cnffile = krb__get_cnffile();
if (!cnffile) {
if (n == 1) {
- (void) strcpy(r, KRB_REALM);
+ (void) strncpy(r, KRB_REALM, REALM_SZ);
+ r[REALM_SZ - 1] = '\0';
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c
index 6723df87e..13f762b01 100644
--- a/src/lib/krb4/g_pw_in_tkt.c
+++ b/src/lib/krb4/g_pw_in_tkt.c
@@ -176,7 +176,6 @@ krb_get_pw_in_tkt_preauth(user,instance,realm,service,sinstance,life,password)
#include <signal.h>
#include <setjmp.h>
#else
-char *strcpy();
int strcmp();
#endif
#if defined(__svr4__) || defined(__SVR4)
diff --git a/src/lib/krb4/in_tkt.c b/src/lib/krb4/in_tkt.c
index ea17be820..4e220f913 100644
--- a/src/lib/krb4/in_tkt.c
+++ b/src/lib/krb4/in_tkt.c
@@ -159,8 +159,9 @@ in_tkt(pname,pinst)
}
(void) close(tktfile);
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
return(krb_shm_create(shmidname));
#else /* !TKT_SHMEM */
return(KSUCCESS);
diff --git a/src/lib/krb4/kntoln.c b/src/lib/krb4/kntoln.c
index 8b6cdfe0e..f86599cce 100644
--- a/src/lib/krb4/kntoln.c
+++ b/src/lib/krb4/kntoln.c
@@ -38,6 +38,10 @@
* KSUCCESS if all goes well, otherwise KFAILURE.
*/
+/* The definition of MAX_USERNAME here MUST agree with kuserok.c, or bad
+ * things will happen. */
+#define MAX_USERNAME 10
+
krb_kntoln(ad,lname)
AUTH_DAT *ad;
char *lname;
@@ -51,6 +55,7 @@ krb_kntoln(ad,lname)
return(KFAILURE);
if (strcmp(ad->prealm,lrealm))
return(KFAILURE);
- (void) strcpy(lname,ad->pname);
+ (void) strncpy(lname,ad->pname,MAX_USERNAME-1);
+ lname[MAX_USERNAME - 1] = '\0';
return(KSUCCESS);
}
diff --git a/src/lib/krb4/kparse.c b/src/lib/krb4/kparse.c
index 98e48fbd9..e72295c48 100644
--- a/src/lib/krb4/kparse.c
+++ b/src/lib/krb4/kparse.c
@@ -54,8 +54,8 @@
static char *strutol();
-#ifndef HAVE_STRSAVE
-static char *strsave();
+#ifndef HAVE_STRDUP
+static char *strdup();
#endif
#ifndef HAVE_STDLIB_H
extern char *malloc();
@@ -104,7 +104,7 @@ int fGetParameterSet( fp,parm,parmcount )
keyword);
return(PS_BAD_KEYWORD);
}
- parm[i].value = strsave( value );
+ parm[i].value = strdup(value);
break;
}
}
@@ -552,34 +552,6 @@ int fGetChar(fp)
return(ch);
}
-
-/*
- * Routine Name: strsave
- *
- * Function: return a pointer to a saved copy of the
- * input string. the copy will be allocated
- * as large as necessary.
- *
- * Explicit Parameters: pointer to string to save
- *
- * Implicit Parameters: None
- *
- * External Procedures: malloc,strcpy,strlen
- *
- * Side Effects: None
- *
- * Return Value: pointer to copied string
- *
- */
-#ifndef HAVE_STRSAVE
-static char * strsave(p)
- char *p;
-{
- return(strcpy(malloc(strlen(p)+1),p));
-}
-#endif
-
-
/*
* strutol changes all characters in a string to lower case, in place.
* the pointer to the beginning of the string is returned.
@@ -770,3 +742,42 @@ main(argc,argv)
exit(0);
}
#endif
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* based on @(#)strdup.c 5.3 (Berkeley) 6/1/90 */
+
+#ifndef HAVE_STRDUP
+static char *
+strdup(str)
+ const char *str;
+{
+ int len;
+ char *copy;
+
+ if (!str)
+ return((char *)0);
+ len = strlen(str) + 1;
+ if (!(copy = malloc((u_int)len)))
+ return((char *)0);
+ memcpy(copy, str, len);
+ return(copy);
+}
+#endif
diff --git a/src/lib/krb4/kuserok.c b/src/lib/krb4/kuserok.c
index 0aee8934a..20587cb5b 100644
--- a/src/lib/krb4/kuserok.c
+++ b/src/lib/krb4/kuserok.c
@@ -118,8 +118,11 @@ kuserok(kdata, luser)
if ((pwd = getpwnam(luser)) == NULL) {
return(NOTOK);
}
- (void) strcpy(pbuf, pwd->pw_dir);
- (void) strcat(pbuf, "/.klogin");
+ if (strlen (pwd->pw_dir) + sizeof ("/.klogin") >= sizeof (pbuf))
+ return NOTOK;
+ (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
+ pbuf[sizeof(pbuf) - 1] = '\0';
+ (void) strncat(pbuf, "/.klogin", sizeof(pbuf) - 1 - strlen(pbuf));
if (access(pbuf, F_OK)) { /* not accessible */
/*
diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c
index 39a2e2f68..a94a25d85 100644
--- a/src/lib/krb4/mk_auth.c
+++ b/src/lib/krb4/mk_auth.c
@@ -124,8 +124,10 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
realm = krb_realm;
}
- if (!(options & KOPT_DONT_CANON))
- (void) strncpy(inst, krb_get_phost(inst), INST_SZ);
+ if (!(options & KOPT_DONT_CANON)) {
+ (void) strncpy(inst, krb_get_phost(inst), INST_SZ - 1);
+ inst[INST_SZ-1] = 0;
+ }
/* get the ticket if desired */
if (!(options & KOPT_DONT_MK_REQ)) {
diff --git a/src/lib/krb4/mk_err.c b/src/lib/krb4/mk_err.c
index e30e299bc..029aa9f9c 100644
--- a/src/lib/krb4/mk_err.c
+++ b/src/lib/krb4/mk_err.c
@@ -41,6 +41,14 @@ krb_mk_err(p,e,e_string)
{
u_char *start;
+ /* 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);
+ }
+
start = p;
/* Create fixed part of packet */
diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c
index 1936cb287..468dccdb6 100644
--- a/src/lib/krb4/mk_req.c
+++ b/src/lib/krb4/mk_req.c
@@ -130,6 +130,19 @@ krb_mk_req(authent,service,instance,realm,checksum)
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;
+ }
+
if (krb_ap_req_debug)
DEB (("%s %s %s %s %s\n", service, instance, realm,
cr.pname, cr.pinst));
diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c
index c9b6ac734..09f914d8a 100644
--- a/src/lib/krb4/rd_req.c
+++ b/src/lib/krb4/rd_req.c
@@ -108,6 +108,19 @@ krb_clear_key_krb5(ctx)
krb5_key = 0;
}
+/* A helper function to let us see if a buffer is properly terminated. */
+static int
+krb_strnlen(const char *str, size_t max_len)
+{
+ int i = 0;
+ for(i = 0; i < max_len; i++) {
+ if(str[i] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
/*
* krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
* AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
@@ -184,6 +197,8 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
krb5_keyblock keyblock;
int status;
+ tkt->mbz = req_id->mbz = 0;
+
if (authent->length <= 0)
return(RD_AP_MODIFIED);
@@ -219,8 +234,13 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
mutual = 0;
#endif /* lint */
s_kvno = *ptr++; /* get server key version */
- (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
- ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+ if(krb_strnlen(ptr, sizeof(realm)) < 0) {
+ 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" */
/*
* If "fn" is NULL, key info should already be set; don't
@@ -249,13 +269,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
return(RD_AP_UNDEC);
#endif /* !NOENCRYPTION */
- (void) strcpy(st_rlm,realm);
- (void) strcpy(st_nam,service);
- (void) strcpy(st_inst,instance);
+ (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';
}
/* Get ticket from authenticator */
- tkt->length = (int) *ptr++;
+ 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);
@@ -324,13 +347,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
ptr = (char *) req_id->dat;
- (void) strcpy(r_aname,ptr); /* Authentication name */
+ (void) strncpy(r_aname,ptr,ANAME_SZ); /* Authentication name */
+ r_aname[ANAME_SZ-1] = '\0';
ptr += strlen(r_aname)+1;
check_ptr();
- (void) strcpy(r_inst,ptr); /* Authentication instance */
+ (void) strncpy(r_inst,ptr,INST_SZ); /* Authentication instance */
+ r_inst[INST_SZ-1] = '\0';
ptr += strlen(r_inst)+1;
check_ptr();
- (void) strcpy(r_realm,ptr); /* Authentication name */
+ (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 */
diff --git a/src/lib/krb4/realmofhost.c b/src/lib/krb4/realmofhost.c
index 90e01bb34..1e4b78601 100644
--- a/src/lib/krb4/realmofhost.c
+++ b/src/lib/krb4/realmofhost.c
@@ -131,14 +131,18 @@ krb_realmofhost(host)
if (domain && (strlen(trans_host) == strlen(domain))
&& !strcasecmp (trans_host, domain)) {
/* got domain match, save for later */
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
continue;
}
} else {
/* want exact match of hostname */
if ((strlen(lhost) == strlen(trans_host)) &&
!strcasecmp (trans_host, lhost)) {
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
break;
}
}
diff --git a/src/lib/krb4/recvauth.c b/src/lib/krb4/recvauth.c
index e62e3f954..2a6665648 100644
--- a/src/lib/krb4/recvauth.c
+++ b/src/lib/krb4/recvauth.c
@@ -188,9 +188,12 @@ krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
if (i < KRB_SENDAUTH_VLEN) {
/* since we already got the space, and part of the ticket,
we read fewer bytes to get the rest of the ticket */
+ int len_to_read = tkt_len - KRB_SENDAUTH_VLEN + 1 + i;
+ if (len_to_read <= 0)
+ return KFAILURE;
if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
- (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
- != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ len_to_read)
+ != len_to_read)
return(errno);
} else {
if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
diff --git a/src/lib/krb4/send_to_kdc.c b/src/lib/krb4/send_to_kdc.c
index c7e0fb33b..f93b9d079 100644
--- a/src/lib/krb4/send_to_kdc.c
+++ b/src/lib/krb4/send_to_kdc.c
@@ -94,12 +94,13 @@ send_to_kdc(pkt,rpkt,realm)
* local realm.
*/
if (realm)
- (void) strcpy(lrealm, realm);
+ (void) strncpy(lrealm, realm, sizeof(lrealm) - 1);
else
if (krb_get_lrealm(lrealm,1)) {
DEB (("%s: can't get local realm\n", prog));
return(SKDC_CANT);
}
+ lrealm[sizeof(lrealm) - 1] = '\0';
DEB (("lrealm is %s\n", lrealm));
if (SOCKET_INITIALIZE()) {
diff --git a/src/lib/krb4/sendauth.c b/src/lib/krb4/sendauth.c
index 9b8fb3904..76c470c20 100644
--- a/src/lib/krb4/sendauth.c
+++ b/src/lib/krb4/sendauth.c
@@ -208,7 +208,8 @@ krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
}
/* copy instance into local storage, so mk_auth can canonicalize */
- (void) strncpy(srv_inst, inst, INST_SZ);
+ (void) strncpy(srv_inst, inst, INST_SZ-1);
+ srv_inst[INST_SZ-1] = 0;
rem = krb_mk_auth (options, ticket, service, srv_inst, realm, checksum,
version, packet);
if (rem != KSUCCESS)
diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c
index ebf500bf2..0d69719cf 100644
--- a/src/lib/krb4/tf_util.c
+++ b/src/lib/krb4/tf_util.c
@@ -181,8 +181,9 @@ int tf_init(tf_name, rw)
tf_name = tkt_string();
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, tf_name);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, tf_name, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
#endif /* TKT_SHMEM */
/*
diff --git a/src/lib/krb4/win_store.c b/src/lib/krb4/win_store.c
index 50507aa12..28d11bd85 100644
--- a/src/lib/krb4/win_store.c
+++ b/src/lib/krb4/win_store.c
@@ -62,15 +62,17 @@ krb__get_cnffile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_CONF);
+ strncat(defname, DEF_KRB_CONF, sizeof(defname) - 1 - strlen(defname));
+ cnfname[sizeof(cnfname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname,
- cnfname, sizeof(cnfname), KERBEROS_INI);
+ cnfname, sizeof(cnfname) - 1, KERBEROS_INI);
cnffile = fopen(cnfname, "r");
@@ -94,15 +96,17 @@ krb__get_realmsfile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_REALMS);
+ strncat(defname, DEF_KRB_REALMS, sizeof(defname) - 1 - strlen(defname));
+ defname[sizeof(defname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname,
- realmsname, sizeof(realmsname), KERBEROS_INI);
+ realmsname, sizeof(realmsname) - 1, KERBEROS_INI);
realmsfile = fopen(realmsname, "r");