From: Tom Yu Date: Tue, 23 Jan 2001 05:48:06 +0000 (+0000) Subject: * prot_common.c: New file; contains functions to encode/decode X-Git-Tag: krb5-1.3-alpha1~1697 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9f4b3a4565363936189fb99322ad7df77c03e856;p=krb5.git * prot_common.c: New file; contains functions to encode/decode string triples for principals. * prot_kdc.c: New file; contains encoders and decoders (eventually) for the KDC's use. * Makefile.in (OBJS, SRCS): Add prot_common.o, prot_kdc.o. * cr_auth_repl.c: KRB4_PUT{16,32} -> KRB4_PUT{16,32}BE. * cr_ciph.c: Include prot.h. KRB4_PUT32 -> KRB4_PUT32BE. * cr_err_repl.c: KRB4_PUT32 -> KRB4_PUT32BE. * cr_tkt.c: KRB4_PUT32 -> KRB4_PUT32BE. * decomp_tkt.c: krb_strnlen -> krb4int_strnlen. * g_ad_tkt.c: krb_strnlen -> krb4int_strnlen. KRB4_PUT32 -> KRB4_PUT32BE. Properly skip date while parsing error. * g_in_tkt.c: krb_strnlen -> krb4int_strnlen. KRB4_PUT32 -> KRB4_PUT32BE. Properly skip date while parsing error. * g_phost.c: Changes from audit. Actually bail out instead of failing silently if h->h_name is too long. * kname_parse.c: Changes from audit. Check overrun per character processed. * mk_auth.c: krb_strnlen -> krb4int_strnlen. KRB4_PUT32 -> KRB4_PUT32BE. Include prot.h. * mk_err.c: KRB4_PUT32 -> KRB4_PUT32BE. * mk_priv.c: KRB4_PUT32 -> KRB4_PUT32BE. * mk_req.c: KRB4_PUT32 -> KRB4_PUT32BE. * mk_safe.c: KRB4_PUT32 -> KRB4_PUT32BE. * rd_req.c: krb_strnlen -> krb4int_strnlen. * strnlen.c: Rename to krb4int_strnlen. Also include prot.h, which is where strnlen is declared now. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12932 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb4/Makefile.in b/src/lib/krb4/Makefile.in index 3afd33ced..917e6424a 100644 --- a/src/lib/krb4/Makefile.in +++ b/src/lib/krb4/Makefile.in @@ -53,6 +53,8 @@ OBJS = \ $(OUTPRE)mk_safe.$(OBJEXT) \ $(OUTPRE)month_sname.$(OBJEXT) \ $(OUTPRE)one.$(OBJEXT) \ + $(OUTPRE)prot_common.$(OBJEXT) \ + $(OUTPRE)prot_kdc.$(OBJEXT) \ $(OUTPRE)pkt_cipher.$(OBJEXT) \ $(OUTPRE)pkt_clen.$(OBJEXT) \ $(OUTPRE)rd_err.$(OBJEXT) \ @@ -92,6 +94,8 @@ SRCS = \ $(srcdir)/one.c \ $(srcdir)/pkt_cipher.c \ $(srcdir)/pkt_clen.c \ + $(srcdir)/prot_common.c \ + $(srcdir)/prot_kdc.c \ $(srcdir)/rd_err.c \ $(srcdir)/rd_priv.c \ $(srcdir)/rd_safe.c \ diff --git a/src/lib/krb4/cr_auth_repl.c b/src/lib/krb4/cr_auth_repl.c index 16482908e..277d9af8e 100644 --- a/src/lib/krb4/cr_auth_repl.c +++ b/src/lib/krb4/cr_auth_repl.c @@ -117,16 +117,16 @@ create_auth_reply(pname, pinst, prealm, time_ws, n, x_date, kvno, cipher) p += prealmlen; /* Workstation timestamp */ - KRB4_PUT32(p, time_ws); + KRB4_PUT32BE(p, time_ws); *p++ = n; /* Expiration date */ - KRB4_PUT32(p, x_date); + KRB4_PUT32BE(p, x_date); /* Now send the ciphertext and info to help decode it */ *p++ = kvno; - KRB4_PUT16(p, cipher->length); + KRB4_PUT16BE(p, cipher->length); memcpy(p, cipher->dat, (size_t)cipher->length); p += cipher->length; diff --git a/src/lib/krb4/cr_err_repl.c b/src/lib/krb4/cr_err_repl.c index 35196df49..bfd628a62 100644 --- a/src/lib/krb4/cr_err_repl.c +++ b/src/lib/krb4/cr_err_repl.c @@ -106,9 +106,9 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string) memcpy(p, prealm, prealmlen); p += prealmlen; /* ws timestamp */ - KRB4_PUT32(p, time_ws); + KRB4_PUT32BE(p, time_ws); /* err code */ - KRB4_PUT32(p, e); + KRB4_PUT32BE(p, e); /* err text */ memcpy(p, e_string, e_stringlen); p += e_stringlen; diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c index 46753d820..f84429d2e 100644 --- a/src/lib/krb4/cr_tkt.c +++ b/src/lib/krb4/cr_tkt.c @@ -199,7 +199,7 @@ krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress, data += 8; *data++ = life; /* issue time */ - KRB4_PUT32(data, time_sec); + KRB4_PUT32BE(data, time_sec); memcpy(data, sname, snamelen); data += snamelen; diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c index c74cdba3e..597be9ab6 100644 --- a/src/lib/krb4/decomp_tkt.c +++ b/src/lib/krb4/decomp_tkt.c @@ -1,7 +1,7 @@ /* * lib/krb4/decomp_tkt.c * - * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts + * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts * Institute of Technology. All Rights Reserved. * * Export of this software from the United States of America may @@ -213,19 +213,19 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, *flags = *ptr++; tkt_le = (*flags >> K_FLAG_ORDER) & 1; - len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1; if (len <= 0 || len > ANAME_SZ) goto cleanup; memcpy(pname, ptr, (size_t)len); ptr += len; - len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1; if (len <= 0 || len > INST_SZ) goto cleanup; memcpy(pinstance, ptr, (size_t)len); ptr += len; - len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1; if (len <= 0 || len > REALM_SZ) goto cleanup; memcpy(prealm, ptr, (size_t)len); @@ -258,13 +258,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, KRB4_GET32(*time_sec, ptr, tkt_le); - len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1; if (len <= 0 || len > SNAME_SZ) goto cleanup; memcpy(sname, ptr, (size_t)len); ptr += len; - len = krb_strnlen((char *)ptr, TKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1; if (len <= 0 || len > INST_SZ) goto cleanup; memcpy(sinstance, ptr, (size_t)len); diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c index a1e3b36f0..4f77f2a6a 100644 --- a/src/lib/krb4/g_ad_tkt.c +++ b/src/lib/krb4/g_ad_tkt.c @@ -116,7 +116,7 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses, * these? */ for (i = 0; i < 3; i++) { - len = krb_strnlen((char *)ptr, RPKT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, RPKT_REMAIN) + 1; if (len <= 0) return INTK_PROT; ptr += len; @@ -128,8 +128,9 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses, ptr += 4 + 1 + 4 + 1; break; case AUTH_MSG_ERR_REPLY: - if (RPKT_REMAIN < 4) + if (RPKT_REMAIN < 8) return INTK_PROT; + ptr += 4; KRB4_GET32(rep_err_code, ptr, msg_byte_order); return rep_err_code; @@ -175,19 +176,19 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses, memset(ptr, 0, 8); ptr += 8; - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > SNAME_SZ) return RD_AP_MODIFIED; memcpy(s_name, ptr, (size_t)len); ptr += len; - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > INST_SZ) return RD_AP_MODIFIED; memcpy(s_instance, ptr, (size_t)len); ptr += len; - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > REALM_SZ) return RD_AP_MODIFIED; memcpy(rlm, ptr, (size_t)len); @@ -317,7 +318,7 @@ get_ad_tkt(service, sinstance, realm, lifetime) } /* timestamp */ /* FIXME -- always 0 now, should we fill it in??? */ - KRB4_PUT32(ptr, time_ws); + KRB4_PUT32BE(ptr, time_ws); *ptr++ = lifetime; diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c index 872d3fe2b..32f51c1cd 100644 --- a/src/lib/krb4/g_in_tkt.c +++ b/src/lib/krb4/g_in_tkt.c @@ -196,7 +196,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life, /* timestamp */ t_local = TIME_GMT_UNIXSEC; - KRB4_PUT32(p, t_local); + KRB4_PUT32BE(p, t_local); *p++ = life; @@ -241,7 +241,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life, * cr_auth_repl.c for details). */ for (i = 0; i < 3; i++) { - len = krb_strnlen((char *)p, RPKT_REMAIN) + 1; + len = krb4int_strnlen((char *)p, RPKT_REMAIN) + 1; if (len <= 0) return INTK_PROT; p += len; @@ -253,8 +253,9 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life, p += 4 + 1 + 4 + 1; break; case AUTH_MSG_ERR_REPLY: - if (RPKT_REMAIN < 4) + if (RPKT_REMAIN < 8) return INTK_PROT; + p += 4; KRB4_GET32(rep_err_code, p, msg_byte_order); return rep_err_code; default: @@ -316,21 +317,21 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip, ptr += 8; /* extract server's name */ - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > sizeof(s_name)) return INTK_BADPW; memcpy(s_name, ptr, (size_t)len); ptr += len; /* extract server's instance */ - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > sizeof(s_instance)) return INTK_BADPW; memcpy(s_instance, ptr, (size_t)len); ptr += len; /* extract server's realm */ - len = krb_strnlen((char *)ptr, CIP_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, CIP_REMAIN) + 1; if (len <= 0 || len > sizeof(rlm)) return INTK_BADPW; memcpy(rlm, ptr, (size_t)len); diff --git a/src/lib/krb4/g_phost.c b/src/lib/krb4/g_phost.c index 8caece372..15d027974 100644 --- a/src/lib/krb4/g_phost.c +++ b/src/lib/krb4/g_phost.c @@ -1,13 +1,29 @@ /* - * g_phost.c + * lib/krb4/g_phost.c * - * Copyright 1988 by the Massachusetts Institute of Technology. + * Copyright 1988, 2001 by the Massachusetts Institute of Technology. + * All Rights Reserved. * - * For copying and distribution information, please see the file - * . + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. */ -#include "mit-copyright.h" #define DEFINE_SOCKADDR /* For struct hostent, , etc */ #include "krb.h" @@ -38,6 +54,7 @@ krb_get_phost(alias) { struct hostent FAR *h; char *p; + unsigned char *ucp; static char hostname_mem[MAXHOSTNAMELEN]; #ifdef DO_REVERSE_RESOLVE char *rev_addr; int rev_type, rev_len; @@ -60,14 +77,16 @@ krb_get_phost(alias) #endif /* We don't want to return a FAR *, so we copy to a safe location. */ strncpy (hostname_mem, h->h_name, sizeof (hostname_mem)); - hostname_mem[MAXHOSTNAMELEN-1]='\0'; + /* Bail out if h_name is too long. */ + if (hostname_mem[MAXHOSTNAMELEN-1] != '\0') + return NULL; p = strchr( hostname_mem, '.' ); if (p) *p = 0; - p = hostname_mem; + ucp = (unsigned char *)hostname_mem; do { - if (isupper(*p)) *p=tolower(*p); - } while (*p++); + if (isupper(*ucp)) *ucp=tolower(*ucp); + } while (*ucp++); } return(hostname_mem); } diff --git a/src/lib/krb4/kname_parse.c b/src/lib/krb4/kname_parse.c index 53d8fb77c..a8bfbe45d 100644 --- a/src/lib/krb4/kname_parse.c +++ b/src/lib/krb4/kname_parse.c @@ -1,19 +1,39 @@ /* - * kname_parse.c + * lib/krb4/kname_parse.c * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * Copyright 1987, 1988, 2001 by the Massachusetts Institute of + * Technology. All Rights Reserved. * - * For copying and distribution information, please see the file - * . + * 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 #include "krb.h" #include -/* max size of full name */ +/* + * max size of full name + * + * XXX This does not account for backslach quoting, and besides we + * might want to use MAX_K_NAME_SZ. + */ #define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ) #define NAME 0 /* which field are we in? */ @@ -123,12 +143,29 @@ kname_parse(np, ip, rp, fullname) default: *wnext++ = c; } + /* + * Paranoia: check length each time through to ensure that we + * don't overwrite things. + */ + switch (field) { + case NAME: + if (wnext - np >= ANAME_SZ) + return KNAME_FMT; + break; + case INST: + if (wnext - ip >= INST_SZ) + return KNAME_FMT; + break; + case REALM: + if (wnext - rp >= REALM_SZ) + return KNAME_FMT; + break; + default: + DEB (("unknown field value\n")); + return KNAME_FMT; + } } *wnext = '\0'; - if ((strlen(np) > ANAME_SZ - 1) || - (strlen(ip) > INST_SZ - 1) || - (strlen(rp) > REALM_SZ - 1)) - return KNAME_FMT; return KSUCCESS; } diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c index 45415fed3..335324cdc 100644 --- a/src/lib/krb4/mk_auth.c +++ b/src/lib/krb4/mk_auth.c @@ -1,7 +1,7 @@ /* * lib/krb4/mk_auth.c * - * Copyright 1987, 1988, 2000 by the Massachusetts Institute of + * Copyright 1987, 1988, 2000, 2001 by the Massachusetts Institute of * Technology. All Rights Reserved. * * Export of this software from the United States of America may @@ -29,6 +29,7 @@ #define DEFINE_SOCKADDR /* Ask for sockets declarations from krb.h. */ #include #include "krb.h" +#include "prot.h" #include #include @@ -143,7 +144,7 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf) if (!(options & KOPT_DONT_CANON)) { phost = krb_get_phost(inst); - phostlen = krb_strnlen(phost, INST_SZ) + 1; + phostlen = krb4int_strnlen(phost, INST_SZ) + 1; if (phostlen <= 0 || phostlen > INST_SZ) return KFAILURE; memcpy(inst, phost, (size_t)phostlen); @@ -183,7 +184,7 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf) p += KRB_SENDAUTH_VLEN; /* put ticket length into buffer */ - KRB4_PUT32(p, ticket->length); + KRB4_PUT32BE(p, ticket->length); /* put ticket into buffer */ memcpy(p, ticket->dat, (size_t)ticket->length); diff --git a/src/lib/krb4/mk_err.c b/src/lib/krb4/mk_err.c index 8fcb2ed21..721149ec2 100644 --- a/src/lib/krb4/mk_err.c +++ b/src/lib/krb4/mk_err.c @@ -74,7 +74,7 @@ krb_mk_err(p, e, e_string) *p++ = AUTH_MSG_APPL_ERR; /* Add the basic info */ - KRB4_PUT32(p, e); + KRB4_PUT32BE(p, e); memcpy(p, e_string, e_len); /* err text */ p += e_len; diff --git a/src/lib/krb4/mk_priv.c b/src/lib/krb4/mk_priv.c index 0c3554808..1e168adce 100644 --- a/src/lib/krb4/mk_priv.c +++ b/src/lib/krb4/mk_priv.c @@ -141,7 +141,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver) q = p; /* stuff input length */ - KRB4_PUT32(p, length); + KRB4_PUT32BE(p, length); #ifdef NOENCRYPTION /* make all the stuff contiguous for checksum */ @@ -174,7 +174,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver) receiver->sin_port) == -1) msg_time_sec = -msg_time_sec; /* stuff time sec */ - KRB4_PUT32(p, msg_time_sec); + KRB4_PUT32BE(p, msg_time_sec); /* * All that for one tiny bit! Heaven help those that talk to @@ -210,7 +210,7 @@ krb_mk_priv(in, out, length, schedule, key, sender, receiver) / sizeof(C_Block)) * sizeof(C_Block); /* stuff the length */ p = c_length_ptr; - KRB4_PUT32(p, c_length); + KRB4_PUT32BE(p, c_length); #ifndef NOENCRYPTION /* pcbc encrypt, pad as needed, use key as ivec */ diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c index 2d5d240ef..cbb4dbd98 100644 --- a/src/lib/krb4/mk_req.c +++ b/src/lib/krb4/mk_req.c @@ -197,13 +197,13 @@ krb_mk_req(authent, service, instance, realm, checksum) memcpy(q, myrealm, myrealmlen); q += myrealmlen; /* Checksum */ - KRB4_PUT32(q, checksum); + KRB4_PUT32BE(q, checksum); /* Fill in the times on the request id */ time_secs = TIME_GMT_UNIXSEC_US (&time_usecs); *q++ = time_usecs; /* time_usecs % 255 */ /* Time (coarse) */ - KRB4_PUT32(q, time_secs); + KRB4_PUT32BE(q, time_secs); /* Fill to a multiple of 8 bytes for DES */ req_id->length = ((q - req_id->dat + 7) / 8) * 8; diff --git a/src/lib/krb4/mk_safe.c b/src/lib/krb4/mk_safe.c index 1efff9953..93cd1ead6 100644 --- a/src/lib/krb4/mk_safe.c +++ b/src/lib/krb4/mk_safe.c @@ -117,7 +117,7 @@ krb_mk_safe(in, out, length, key, sender, receiver) q = p; /* start for checksum stuff */ /* stuff input length */ - KRB4_PUT32(p, length); + KRB4_PUT32BE(p, length); /* make all the stuff contiguous for checksum */ memcpy(p, in, length); @@ -151,7 +151,7 @@ krb_mk_safe(in, out, length, key, sender, receiver) */ /* stuff time sec */ - KRB4_PUT32(p, msg_time_sec); + KRB4_PUT32BE(p, msg_time_sec); #ifdef NOENCRYPTION cksum = 0; @@ -165,7 +165,7 @@ krb_mk_safe(in, out, length, key, sender, receiver) /* stuff checksum */ for (i = 0; i < 4; i++) - KRB4_PUT32(p, big_cksum[i]); + KRB4_PUT32BE(p, big_cksum[i]); return p - out; /* resulting size */ } diff --git a/src/lib/krb4/prot_common.c b/src/lib/krb4/prot_common.c new file mode 100644 index 000000000..7d6571d44 --- /dev/null +++ b/src/lib/krb4/prot_common.c @@ -0,0 +1,114 @@ +/* + * lib/krb4/prot_common.c + * + * Copyright 2001 by the Massachusetts Institute of Technology. All + * Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Contains some common code used by multiple encoders/decoders. + */ + +#include "krb.h" +#include "prot.h" +#include + +/* + * encode_naminstrlm + * + * Takes input string triplet of a principal, encodes into PKT. + * Assumes that input strings are properly terminated. If CHKLEN is + * non-zero, validate input string lengths against their respective + * limits. The pointer P is the address of the moving pointer used by + * the caller, and is updated here. + * + * Returns zero on success, non-zero on failure. + * + * PKT->LENGTH is NOT updated. The caller must update it. + */ +int KRB5_CALLCONV +krb4prot_encode_naminstrlm(char *name, char *inst, char *realm, + int chklen, /* check input str len? */ + KTEXT pkt, /* buffer to encode into */ + unsigned char **p /* moving pointer */) +{ + size_t namelen, instlen, realmlen; + + namelen = strlen(name) + 1; + instlen = strlen(inst) + 1; + realmlen = strlen(realm) + 1; + if (chklen && (namelen > ANAME_SZ || instlen > INST_SZ + || realmlen > REALM_SZ)) + return -1; + if (*p - pkt->dat < namelen + instlen + realmlen) + return -1; + memcpy(*p, name, namelen); + *p += namelen; + memcpy(*p, inst, instlen); + *p += namelen; + memcpy(*p, realm, realmlen); + *p += namelen; + return 0; +} + +/* + * decode_naminstrlm + * + * Grabs a string triplet corresponding to a principal. The input + * buffer PKT should have its length properly set. The pointer P is + * the address of the moving pointer used by the caller, and will be + * updated. If any input pointer is NULL, merely skip the string. + * + * The output strings NAME, INST, and REALM are assumed to be of the + * correct sizes (ANAME_SZ, INST_SZ, REALM_SZ). + * + * Returns 0 on success, non-zero on failure. + */ +int KRB5_CALLCONV +krb4prot_decode_naminstrlm(KTEXT pkt, /* buffer to decode from */ + unsigned char **p, /* moving pointer */ + char *name, char *inst, char *realm) +{ + int len; + +#define PKT_REMAIN (pkt->length - (*p - pkt->dat)) + len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1; + if (len <= 0 || len > ANAME_SZ) + return KFAILURE; + if (name != NULL) + memcpy(name, *p, (size_t)len); + *p += len; + + len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1; + if (len <= 0 || len > INST_SZ) + return KFAILURE; + if (name != NULL) + memcpy(inst, *p, (size_t)len); + *p += len; + + len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1; + if (len <= 0 || len > REALM_SZ) + return KFAILURE; + if (realm != NULL) + memcpy(realm, *p, (size_t)len); + *p += len; + return KSUCCESS; +#undef PKT_REMAIN +} diff --git a/src/lib/krb4/prot_kdc.c b/src/lib/krb4/prot_kdc.c new file mode 100644 index 000000000..3b36ddb8c --- /dev/null +++ b/src/lib/krb4/prot_kdc.c @@ -0,0 +1,390 @@ +/* + * lib/krb4/prot_kdc.c + * + * Copyright 1985--1988, 2000, 2001 by the Massachusetts Institute of + * Technology. All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Contains the protocol encoders and decoders used by the KDC. + */ + +#include "krb.h" +#include "prot.h" +#include + +/* + * encode_kdc_reply + * + * Encodes a reply from the KDC to the client. + * + * Returns KSUCCESS on success, KFAILURE on failure. + * + * Caller is responsible for cleaning up OUTBUF. + * + * This packet layout description was originally in cr_auth_repl.c + * + * variable + * type or constant data + * ---- ----------- ---- + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_KDC_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned char n number of tickets + * + * unsigned long x_date expiration date + * + * unsigned char kvno master key version + * + * short cipher->length cipher length + * + * binary cipher->dat cipher data + */ +int +krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm, + long time_ws, + int n, /* Number of tickets; 0 for krb4 (!) */ + unsigned long x_date, /* exp date */ + int kvno, + KTEXT cipher, /* encrypted ticket */ + int chklen, /* check input str len? */ + int le, /* little-endian? */ + KTEXT outbuf) +{ + unsigned char *p; + + p = outbuf->dat; + /* This is really crusty. */ + if (n != 0) + *p++ = 3; + else + *p++ = KRB_PROT_VERSION; + /* little-endianness based on input, usually big-endian, though. */ + *p++ = AUTH_MSG_KDC_REPLY | (le ? LSB_FIRST : MSB_FIRST); + + if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen, + outbuf, &p)) + return KFAILURE; + + /* Check lengths */ + if (cipher->length > 65535 || cipher->length < 0) + return KFAILURE; + if ((sizeof(outbuf->dat) - (p - outbuf->dat) + < (4 /* timestamp */ + + 1 /* num of tickets */ + + 4 /* exp date */ + + 1 /* kvno */ + + 2 /* cipher->length */ + + cipher->length))) /* cipher->dat */ + return KFAILURE; + + /* Workstation timestamp */ + KRB4_PUT32(p, time_ws, le); + + /* Number of tickets */ + *p++ = n; + + /* Expiration date */ + KRB4_PUT32(p, x_date, le); + + /* Now send the ciphertext and info to help decode it */ + *p++ = kvno; + KRB4_PUT16(p, cipher->length, le); + memcpy(p, cipher->dat, (size_t)cipher->length); + p += cipher->length; + + /* And return the packet */ + outbuf->length = p - outbuf->dat; + return KSUCCESS; +} + +/* + * encode_ciph + * + * Encodes a "cipher" that is to be included in a KDC reply message. + * + * Caller is responsible for cleaning up CIPH. + * + * Returns KSUCCESS on success, KFAILURE on failure. + * + * Packet format below is originally from cr_ciph.c. + * + * variable + * type or constant data + * ---- ----------- ---- + * 8 bytes session session key for client, service + * + * string service service name + * + * string instance service instance + * + * string realm KDC realm + * + * unsigned char life ticket lifetime + * + * unsigned char kvno service key version number + * + * unsigned char tkt->length length of following ticket + * + * data tkt->dat ticket for service + * + * 4 bytes kdc_time KDC's timestamp + * + * <=7 bytes null null pad to 8 byte multiple + */ +int +krb4prot_encode_ciph(C_Block session, + char *name, char *inst, char *realm, + unsigned long life, int kvno, + KTEXT tkt, /* ticket */ + unsigned long kdc_time, + int chklen, /* check str lens? */ + int le, /* little-endian? */ + KTEXT ciph) /* output buffer */ +{ + unsigned char *p; + + p = ciph->dat; + /* + * Assume that there will be >= 8 bytes in a KTEXT. If there + * aren't, we have worse problems. + */ + memcpy(p, session, 8); + p += 8; + + if (krb4prot_encode_naminstrlm(name, inst, realm, chklen, + ciph, &p)) + return KFAILURE; + if (tkt->length > 255 || tkt->length < 0) + return KFAILURE; + if ((sizeof(ciph->dat) - (p - ciph->dat)) / 8 + < (1 /* life */ + + 1 /* kvno */ + + 1 /* tkt->length */ + + tkt->length /* tkt->dat */ + + 4 /* kdc_time */ + + 7) / 8) /* roundoff */ + return KFAILURE; + + *p++ = life; + *p++ = kvno; + *p++ = tkt->length; + + memcpy(p, tkt->dat, (size_t)tkt->length); + p += tkt->length; + + KRB4_PUT32(p, kdc_time, le); + + /* Guarantee null pad to multiple of 8 bytes */ + memset(p, 0, 7); + ciph->length = (((p - ciph->dat) + 7) / 8) * 8; + return KSUCCESS; +} + +/* + * encode_tkt + * + * Encode ticket to include in a "cipher". Does not encrypt. + * + * Caller is responsible for cleaning TKT. + * + * The length of the ticket is a multiple of + * eight bytes and is in tkt->length. + * + * If the ticket is too long, the ticket will contain nulls. + * + * Returns KSUCCESS on success, KFAILURE on failure. + * + * The following packet layout is from cr_tkt.c + * + * variable + * type or constant data + * ---- ----------- ---- + * unsigned char flags namely, HOST_BYTE_ORDER + * + * string pname client's name + * + * string pinstance client's instance + * + * string prealm client's realm + * + * 4 bytes paddress client's address + * + * 8 bytes session session key + * + * 1 byte life ticket lifetime + * + * 4 bytes time_sec KDC timestamp + * + * string sname service's name + * + * string sinstance service's instance + * + * <=7 bytes null null pad to 8 byte multiple + */ +int +krb4prot_encode_tkt(unsigned int flags, + char *pname, char *pinst, char *prealm, + unsigned long paddress, + char *session, + int life, long time_sec, + char *sname, char *sinst, + int chklen, /* check str lens? */ + int le, /* little-endian? */ + KTEXT tkt) /* output buf */ +{ + struct in_addr paddr; + unsigned char *p; + size_t snamelen, sinstlen; + + /* Be really paranoid. */ + if (sizeof(paddr.s_addr) != 4) + return KFAILURE; + + p = tkt->dat; + /* + * Assume at least one byte in a KTEXT. If not, we have bigger + * problems. Also, bitwise-OR in the little-endian flag. + */ + *p++ = flags | (le ? LSB_FIRST : MSB_FIRST); + + if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen, + tkt, &p)) + return KFAILURE; + + snamelen = strlen(sname) + 1; + sinstlen = strlen(sinst) + 1; + if (life > 255 || life < 0) + return KFAILURE; + if (chklen && (snamelen > ANAME_SZ || sinstlen > INST_SZ)) + return KFAILURE; + if ((sizeof(tkt->dat) - (p - tkt->dat)) / 8 + < (4 /* address */ + + 8 /* session */ + + 1 /* life */ + + 4 /* issue time */ + + snamelen + sinstlen + + 7) / 8) /* roundoff */ + return KFAILURE; + + paddr.s_addr = paddress; + memcpy(p, &paddr.s_addr, sizeof(paddr.s_addr)); + p += sizeof(paddr.s_addr); + + memcpy(p, session, 8); + p += 8; + *p++ = life; + /* issue time */ + KRB4_PUT32(p, time_sec, le); + + memcpy(p, sname, snamelen); + p += snamelen; + memcpy(p, sinst, sinstlen); + p += sinstlen; + + /* guarantee null padded ticket to multiple of 8 bytes */ + memset(p, 0, 7); + tkt->length = ((p - tkt->dat + 7) / 8) * 8; + return KSUCCESS; +} + +/* + * This routine is used by the Kerberos authentication server to + * create an error reply packet to send back to its client. + * + * It takes a pointer to the packet to be built, the name, instance, + * and realm of the principal, the client's timestamp, an error code + * and an error string as arguments. Its return value is undefined. + * + * The packet is built in the following format: + * + * type variable data + * or constant + * ---- ----------- ---- + * unsigned char req_ack_vno protocol version number + * + * unsigned char AUTH_MSG_ERR_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned long e error code + * + * string e_string error text + */ +int +krb4prot_encode_err_reply(char *pname, char *pinst, char *prealm, + unsigned long time_ws, + unsigned long err, /* error code */ + char *err_string, /* error text */ + int chklen, /* check str lens? */ + int le, /* little-endian? */ + KTEXT pkt) /* output buf */ +{ + unsigned char *p; + size_t err_stringlen; + + p = pkt->dat; + /* Assume >= 2 bytes in KTEXT. */ + *p++ = KRB_PROT_VERSION; + *p++ = AUTH_MSG_ERR_REPLY | (le ? LSB_FIRST : MSB_FIRST); + + if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen, + pkt, &p)) + return KFAILURE; + + err_stringlen = strlen(err_string) + 1; + if ((sizeof(pkt->dat) - (p - pkt->dat)) + < (4 /* timestamp */ + + 4 /* err code */ + + err_stringlen)) + return KFAILURE; + /* ws timestamp */ + KRB4_PUT32(p, time_ws, le); + /* err code */ + KRB4_PUT32(p, err, le); + /* err text */ + memcpy(p, err_string, err_stringlen); + p += err_stringlen; + + /* And return */ + pkt->length = p - pkt->dat; + return KSUCCESS; +} diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c index 542828d79..abcf7da43 100644 --- a/src/lib/krb4/rd_req.c +++ b/src/lib/krb4/rd_req.c @@ -1,7 +1,7 @@ /* * lib/krb4/rd_req.c * - * Copyright 1985, 1986, 1987, 1988, 2000 by the Massachusetts + * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts * Institute of Technology. All Rights Reserved. * * Export of this software from the United States of America may @@ -239,7 +239,7 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn) mutual = 0; #endif /* lint */ s_kvno = *ptr++; /* get server key version */ - len = krb_strnlen((char *)ptr, AUTHENT_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, AUTHENT_REMAIN) + 1; if (len <= 0 || len > sizeof(realm)) { return RD_AP_MODIFIED; /* must have been modified, the client wouldn't try to trick us with wacky data */ @@ -277,15 +277,15 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn) return RD_AP_UNDEC; #endif /* !NOENCRYPTION */ - len = krb_strnlen(realm, sizeof(st_rlm)) + 1; + len = krb4int_strnlen(realm, sizeof(st_rlm)) + 1; if (len <= 0) return KFAILURE; memcpy(st_rlm, realm, (size_t)len); - len = krb_strnlen(service, sizeof(st_nam)) + 1; + len = krb4int_strnlen(service, sizeof(st_nam)) + 1; if (len <= 0) return KFAILURE; memcpy(st_nam, service, (size_t)len); - len = krb_strnlen(instance, sizeof(st_inst)) + 1; + len = krb4int_strnlen(instance, sizeof(st_inst)) + 1; if (len <= 0) return KFAILURE; memcpy(st_inst, instance, (size_t)len); @@ -366,17 +366,17 @@ krb_rd_req(authent, service, instance, from_addr, ad, fn) ret = RD_AP_MODIFIED; - len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, REQID_REMAIN) + 1; if (len <= 0 || len > ANAME_SZ) goto cleanup; memcpy(r_aname, ptr, (size_t)len); /* Authentication name */ ptr += len; - len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, REQID_REMAIN) + 1; if (len <= 0 || len > INST_SZ) goto cleanup; memcpy(r_inst, ptr, (size_t)len); /* Authentication instance */ ptr += len; - len = krb_strnlen((char *)ptr, REQID_REMAIN) + 1; + len = krb4int_strnlen((char *)ptr, REQID_REMAIN) + 1; if (len <= 0 || len > REALM_SZ) goto cleanup; memcpy(r_realm, ptr, (size_t)len); /* Authentication name */ diff --git a/src/lib/krb4/strnlen.c b/src/lib/krb4/strnlen.c index b7339123e..5dc80115c 100644 --- a/src/lib/krb4/strnlen.c +++ b/src/lib/krb4/strnlen.c @@ -1,7 +1,7 @@ /* * lib/krb4/strnlen.c * - * Copyright 2000 by the Massachusetts Institute of Technology. + * Copyright 2000, 2001 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -27,15 +27,17 @@ #include #include "krb.h" +#include "prot.h" + /* - * krb_strnlen() + * krb4int_strnlen() * * Return the length of the string if a NUL is found in the first n * bytes, otherwise, -1. */ int KRB5_CALLCONV -krb_strnlen(const char *s, int n) +krb4int_strnlen(const char *s, int n) { int i = 0;