diff options
-rw-r--r-- | server/Makefile.in | 2 | ||||
-rw-r--r-- | server/bdump.c | 8 | ||||
-rw-r--r-- | server/kopt.c | 500 | ||||
-rw-r--r-- | server/kstuff.c | 64 |
4 files changed, 2 insertions, 572 deletions
diff --git a/server/Makefile.in b/server/Makefile.in index 2dd0fd3..3e79792 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -26,7 +26,7 @@ LDFLAGS=-L${BUILDTOP}/lib @LDFLAGS@ LIBS=-lzephyr @LIBS@ -lcom_err OBJS= zsrv_err.o access.o acl_files.o bdump.o class.o client.o common.o \ - dispatch.o kopt.o kstuff.o main.o server.o subscr.o timer.o uloc.o \ + dispatch.o kstuff.o main.o server.o subscr.o timer.o uloc.o \ zstring.o realm.o version.o all: zephyrd diff --git a/server/bdump.c b/server/bdump.c index 80f7e72..22bf518 100644 --- a/server/bdump.c +++ b/server/bdump.c @@ -725,13 +725,7 @@ get_tgt() krb_get_err_text(retval)); return 1; } - s = (Sched *) check_key_sched_cache(serv_key); - if (s) { - serv_ksched = *s; - } else { - des_key_sched(serv_key, serv_ksched.s); - add_to_key_sched_cache(serv_key, &serv_ksched); - } + des_key_sched(serv_key, serv_ksched.s); #endif /* !NOENCRYPTION */ } return(0); diff --git a/server/kopt.c b/server/kopt.c deleted file mode 100644 index acc299d..0000000 --- a/server/kopt.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * $Source$ - * $Author$ - * - * Copyright 1985, 1986, 1987, 1988, 1990, 1991 by the Massachusetts - * Institute of Technology. - * - * For copying and distribution information, please see the file - * <mit-copyright.h>. - */ - -/* - * This includes code taken from: - * Kerberos: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp - * Kerberos: prot.h,v 4.13 89/01/24 14:27:22 jtkohl Exp - * Kerberos: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp - */ - -#include <zephyr/mit-copyright.h> -#include "zserver.h" - -#ifndef lint -#ifndef SABER -static const char *rcsid_rd_req_c = - "$Id$"; -#endif /* lint */ -#endif /* SABER */ - -#ifdef HAVE_KRB4 -#ifndef NOENCRYPTION - -/* Byte ordering */ -#undef HOST_BYTE_ORDER -static int krbONE = 1; -#define HOST_BYTE_ORDER (* (char *) &krbONE) - -#define KRB_PROT_VERSION 4 - -/* Message types , always leave lsb for byte order */ - -#define AUTH_MSG_KDC_REQUEST 1<<1 -#define AUTH_MSG_KDC_REPLY 2<<1 -#define AUTH_MSG_APPL_REQUEST 3<<1 -#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 -#define AUTH_MSG_ERR_REPLY 5<<1 -#define AUTH_MSG_PRIVATE 6<<1 -#define AUTH_MSG_SAFE 7<<1 -#define AUTH_MSG_APPL_ERR 8<<1 -#define AUTH_MSG_DIE 63<<1 - -/* values for kerb error codes */ - -#define KERB_ERR_OK 0 -#define KERB_ERR_NAME_EXP 1 -#define KERB_ERR_SERVICE_EXP 2 -#define KERB_ERR_AUTH_EXP 3 -#define KERB_ERR_PKT_VER 4 -#define KERB_ERR_NAME_MAST_KEY_VER 5 -#define KERB_ERR_SERV_MAST_KEY_VER 6 -#define KERB_ERR_BYTE_ORDER 7 -#define KERB_ERR_PRINCIPAL_UNKNOWN 8 -#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 -#define KERB_ERR_NULL_KEY 10 - -extern int krb_ap_req_debug; - -extern struct timeval t_local; - -/* - * Keep the following information around for subsequent calls - * to this routine by the same server using the same key. - */ - -static Sched serv_ksched; /* Key sched to decrypt ticket */ -static des_cblock serv_key; /* Initialization vector */ - -static int st_kvno; /* version number for this key */ -static char st_rlm[REALM_SZ]; /* server's realm */ -static char st_nam[ANAME_SZ]; /* service name */ -static char st_inst[INST_SZ]; /* server's instance */ - -/* - * Cache of key schedules - */ -#define HASH_SIZE_1 255 /* not a power of 2 */ -#define HASH_SIZE_2 3 -static unsigned long last_use; -typedef struct { - unsigned long last_time_used; - des_cblock key; - Sched schedule; -} KeySchedRec; -static KeySchedRec scheds[HASH_SIZE_1][HASH_SIZE_2]; - -Sched *check_key_sched_cache(key) - des_cblock key; -{ - unsigned int hash_value = key[0] + key[1] * 256; - KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1]; - int i; - - for (i = HASH_SIZE_2 - 1; i >= 0; i--) { - if (rec[i].last_time_used && key[0] == rec[i].key[0] - && !memcmp(key, rec[i].key, sizeof(des_cblock))) { - rec[i].last_time_used = last_use++; - return &rec[i].schedule; - } - } - return 0; -} - -void add_to_key_sched_cache(key, sched) - des_cblock key; - Sched *sched; -{ - unsigned int hash_value = key[0] + key[1] * 256; - KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1]; - int i, oldest = HASH_SIZE_2 - 1; - - for (i = HASH_SIZE_2 - 1; i >= 0; i--) { - if (rec[i].last_time_used == 0) { - oldest = i; - break; - } - if (rec[i].last_time_used < rec[oldest].last_time_used) - oldest = i; - } - memcpy (rec[oldest].key, key, sizeof(des_cblock)); - rec[oldest].schedule = *sched; - rec[oldest].last_time_used = last_use++; -} - -/* - * This file contains two functions. krb_set_key() takes a DES - * key or password string and returns a DES key (either the original - * key, or the password converted into a DES key) and a key schedule - * for it. - * - * krb_rd_req() reads an authentication request and returns information - * about the identity of the requestor, or an indication that the - * identity information was not authentic. - */ - -/* - * krb_set_key() takes as its first argument either a DES key or a - * password string. The "cvt" argument indicates how the first - * argument "key" is to be interpreted: if "cvt" is null, "key" is - * taken to be a DES key; if "cvt" is non-null, "key" is taken to - * be a password string, and is converted into a DES key using - * string_to_key(). In either case, the resulting key is returned - * in the external variable "serv_key". A key schedule is - * generated for "serv_key" and returned in the external variable - * "serv_ksched". - * - * This routine returns the return value of des_key_sched. - * - * krb_set_key() needs to be in the same .o file as krb_rd_req() so that - * the key set by krb_set_key() is available in private storage for - * krb_rd_req(). - */ - -int -krb_set_key(key,cvt) - char *key; - int cvt; -{ -#ifdef NOENCRYPTION - memset(serv_key, 0, sizeof(serv_key)); - return KSUCCESS; -#else /* Encrypt */ - Sched *s; - int ret; - - if (cvt) - string_to_key(key,serv_key); - else - memcpy((char *)serv_key,key,8); - - s = check_key_sched_cache (serv_key); - if (s) { - serv_ksched = *s; - return 0; - } - ret = des_key_sched(serv_key, serv_ksched.s); - add_to_key_sched_cache(serv_key, &serv_ksched); - return ret; -#endif /* NOENCRYPTION */ -} - - -/* - * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or - * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), - * checks its integrity and returns a judgement as to the requestor's - * identity. - * - * The "authent" argument is a pointer to the received message. - * The "service" and "instance" arguments name the receiving server, - * and are used to get the service's ticket to decrypt the ticket - * in the message, and to compare against the server name inside the - * ticket. "from_addr" is the network address of the host from which - * the message was received; this is checked against the network - * address in the ticket. If "from_addr" is zero, the check is not - * performed. "ad" is an AUTH_DAT structure which is - * filled in with information about the sender's identity according - * to the authenticator and ticket sent in the message. Finally, - * "fn" contains the name of the file containing the server's key. - * (If "fn" is NULL, the server's key is assumed to have been set - * by krb_set_key(). If "fn" is the null string ("") the default - * file KEYFILE, defined in "krb.h", is used.) - * - * krb_rd_req() returns RD_AP_OK if the authentication information - * was genuine, or one of the following error codes (defined in - * "krb.h"): - * - * RD_AP_VERSION - wrong protocol version number - * RD_AP_MSG_TYPE - wrong message type - * RD_AP_UNDEC - couldn't decipher the message - * RD_AP_INCON - inconsistencies found - * RD_AP_BADD - wrong network address - * RD_AP_TIME - client time (in authenticator) - * too far off server time - * RD_AP_NYV - Kerberos time (in ticket) too - * far off server time - * RD_AP_EXP - ticket expired - * - * For the message format, see krb_mk_req(). - * - * Mutual authentication is not implemented. - */ - -int -krb_rd_req(authent,service,instance,from_addr,ad,fn) - KTEXT authent; /* The received message */ - char *service; /* Service name */ - char *instance; /* Service instance */ - unsigned KRB_INT32 from_addr; /* Net address of originating host */ - AUTH_DAT *ad; /* Structure to be filled in */ - char *fn; /* Filename to get keys from */ -{ - KTEXT_ST ticket; /* Temp storage for ticket */ - KTEXT tkt = &ticket; - KTEXT_ST req_id_st; /* Temp storage for authenticator */ - KTEXT req_id = &req_id_st; - - char realm[REALM_SZ]; /* Realm of issuing kerberos */ - Sched seskey_sched, *sched; /* Key sched for session key */ - unsigned char skey[KKEY_SZ]; /* Session key from ticket */ - char sname[SNAME_SZ]; /* Service name from ticket */ - char iname[INST_SZ]; /* Instance name from ticket */ - char r_aname[ANAME_SZ]; /* Client name from authenticator */ - char r_inst[INST_SZ]; /* Client instance from authenticator */ - char r_realm[REALM_SZ]; /* Client realm from authenticator */ - unsigned int r_time_ms; /* Fine time from authenticator */ - unsigned long r_time_sec; /* Coarse time from authenticator */ - char *ptr; /* For stepping through */ - unsigned long delta_t; /* Time in authenticator - local time */ - long tkt_age; /* Age of ticket */ - int swap_bytes; /* Need to swap bytes? */ - int mutual; /* Mutual authentication requested? */ - unsigned char s_kvno; /* Version number of the server's key - * Kerberos used to encrypt ticket */ - int status; - - if (authent->length <= 0) - return(RD_AP_MODIFIED); - - ptr = (char *) 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; - - /* byte order */ - swap_bytes = 0; - if ((*ptr & 1) != HOST_BYTE_ORDER) - swap_bytes++; - - /* check msg type */ - mutual = 0; - switch (*ptr++ & ~1) { - case AUTH_MSG_APPL_REQUEST: - break; - case AUTH_MSG_APPL_REQUEST_MUTUAL: - mutual++; - break; - default: - return(RD_AP_MSG_TYPE); - } - -#ifdef lint - /* XXX mutual is set but not used; why??? */ - /* this is a crock to get lint to shut up */ - if (mutual) - mutual = 0; -#endif /* lint */ - s_kvno = *ptr++; /* get server key version */ - 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 - * bother with ticket file. Otherwise, check to see if we - * already have key info for the given server and key version - * (saved in the static st_* variables). If not, go get it - * from the ticket file. If "fn" is the null string, use the - * default ticket file. - */ - if (fn && (strcmp(st_nam,service) != 0 || strcmp(st_inst,instance) != 0 || - strcmp(st_rlm,realm) != 0 || (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)) - return(RD_AP_UNDEC); - status = krb_set_key((char *) skey, 0); - if (status != 0) - return(status); -#endif /* !NOENCRYPTION */ - strcpy(st_rlm,realm); - strcpy(st_nam,service); - strcpy(st_inst,instance); - } - - /* Get ticket from authenticator */ - tkt->length = (int) *ptr++; - if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length) - return RD_AP_MODIFIED; - memcpy(tkt->dat, ptr + 1, tkt->length); - - if (krb_ap_req_debug) - krb_log("ticket->length: %d", tkt->length); - -#ifndef NOENCRYPTION - /* Decrypt and take apart ticket */ -#endif - - if (decomp_ticket(tkt, &ad->k_flags, ad->pname, ad->pinst, ad->prealm, - &(ad->address), ad->session, &(ad->life), - &(ad->time_sec), sname, iname, serv_key, serv_ksched.s)) - return RD_AP_UNDEC; - - if (krb_ap_req_debug) { - krb_log("Ticket Contents."); - krb_log(" Aname: %s.%s",ad->pname, - ((int)*(ad->prealm) ? ad->prealm : "Athena")); - krb_log(" Service: %s%s%s", sname, ((int)*iname ? "." : ""), iname); - } - - /* 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(req_id->dat, ptr + tkt->length, req_id->length); - -#ifndef NOENCRYPTION - /* And decrypt it with the session key from the ticket */ - if (krb_ap_req_debug) - krb_log("About to decrypt authenticator"); - sched = check_key_sched_cache(ad->session); - if (!sched) { - sched = &seskey_sched; - key_sched(ad->session, seskey_sched.s); - add_to_key_sched_cache(ad->session, &seskey_sched); - } - /* can't do much to optimize this... */ - pcbc_encrypt((C_Block *) req_id->dat, (C_Block *) req_id->dat, - (long) req_id->length, sched->s, ad->session, DES_DECRYPT); - if (krb_ap_req_debug) - krb_log("Done."); -#endif /* NOENCRYPTION */ - -#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); - - ptr = (char *) req_id->dat; - strncpy(r_aname, ptr, ANAME_SZ); /* Authentication name */ - r_aname[ANAME_SZ-1] = '\0'; - ptr += strlen(r_aname) + 1; - check_ptr(); - strncpy(r_inst, ptr, INST_SZ); /* Authentication instance */ - r_inst[INST_SZ-1] = '\0'; - ptr += strlen(r_inst) + 1; - check_ptr(); - strncpy(r_realm, ptr, REALM_SZ); /* Authentication name */ - r_realm[REALM_SZ-1] = '\0'; - ptr += strlen(r_realm) + 1; - check_ptr(); - memcpy(&ad->checksum, ptr, 4); /* Checksum */ - ptr += 4; - check_ptr(); - if (swap_bytes) - swap_u_long(ad->checksum); - 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(&r_time_sec,ptr,4); /* Time (coarse) */ - if (swap_bytes) - swap_u_long(r_time_sec); - - /* Check for authenticity of the request */ - if (krb_ap_req_debug) - krb_log("Pname: %s %s",ad->pname,r_aname); - if (strcmp(ad->pname,r_aname) != 0) - return RD_AP_INCON; - if (strcmp(ad->pinst,r_inst) != 0) - return RD_AP_INCON; - if (krb_ap_req_debug) - krb_log("Realm: %s %s", ad->prealm, r_realm); - if (strcmp(ad->prealm,r_realm) != 0) - return RD_AP_INCON; - - if (krb_ap_req_debug) - krb_log("Address: %d %d", ad->address, from_addr); - if (from_addr && (ad->address != from_addr)) - return RD_AP_BADD; - - delta_t = abs((int)(t_local.tv_sec - r_time_sec)); - if (delta_t > CLOCK_SKEW) { - gettimeofday(&t_local, NULL); - delta_t = abs((int)(t_local.tv_sec - r_time_sec)); - if (delta_t > CLOCK_SKEW) { - if (krb_ap_req_debug) { - krb_log("Time out of range: %d - %d = %d", - t_local.tv_sec, r_time_sec, delta_t); - } - return RD_AP_TIME; - } - } - - /* Now check for expiration of ticket */ - - tkt_age = t_local.tv_sec - ad->time_sec; - if (krb_ap_req_debug) { - krb_log("Time: %d Issue Date: %d Diff: %d Life %x", - t_local.tv_sec, ad->time_sec, tkt_age, ad->life); - } - - if (t_local.tv_sec < ad->time_sec) { - if (ad->time_sec - t_local.tv_sec > CLOCK_SKEW) - return RD_AP_NYV; - } else if (t_local.tv_sec - ad->time_sec > 5 * 60 * ad->life) { - return RD_AP_EXP; - } - - /* All seems OK */ - ad->reply.length = 0; - - return RD_AP_OK; -} -#endif /* NOENCRYPTION */ - -int -krb_find_ticket(authent, ticket) - KTEXT authent, ticket; -{ - char *ptr; /* For stepping through */ - - /* Check for bogus length. */ - if (authent->length <= 0) - return RD_AP_MODIFIED; - - ptr = (char *) authent->dat; - - /* check version */ - if (KRB_PROT_VERSION != (unsigned int) *ptr++) - return RD_AP_VERSION; - - /* Make sure msg type is ok. */ - switch (*ptr++ & ~1) { - case AUTH_MSG_APPL_REQUEST: - case AUTH_MSG_APPL_REQUEST_MUTUAL: - break; - default: - return RD_AP_MSG_TYPE; - } - - *ptr++; /* skip server key version */ - ptr += strlen(ptr) + 1; /* skip the realm "hint" */ - - /* Get ticket from authenticator */ - ticket->length = (int) *ptr++; - if ((ticket->length + (ptr + 1 - (char *) authent->dat)) > authent->length) - return RD_AP_MODIFIED; - memcpy((char *)(ticket->dat),ptr+1,ticket->length); - - return RD_AP_OK; -} -#endif /* HAVE_KRB4 */ diff --git a/server/kstuff.c b/server/kstuff.c index ca9f055..eff445d 100644 --- a/server/kstuff.c +++ b/server/kstuff.c @@ -174,41 +174,9 @@ ZCheckRealmAuthentication(notice, from, realm) } authent.length = notice->z_authent_len; - /* Copy the ticket out of the authentication data. */ - if (krb_find_ticket(&authent, &ticket) != RD_AP_OK) - return ZAUTH_FAILED; - (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE, SERVER_INSTANCE, realm); - /* Try to do a fast check against the cryptographic checksum. */ - if (find_session_key(&ticket, session_key, srcprincipal) >= 0) { - if (strcmp(srcprincipal, rlmprincipal) != 0) - return ZAUTH_FAILED; - if (notice->z_time.tv_sec - NOW > CLOCK_SKEW) - return ZAUTH_FAILED; - checksum = compute_rlm_checksum(notice, session_key); - - /* If checksum matches, packet is authentic. If not, we might - * have an outdated session key, so keep going the slow way. - */ - if (checksum == notice->z_checksum) { - (void) memcpy((char *)__Zephyr_session, (char *)session_key, - sizeof(C_Block)); /* For control_dispatch() */ - return ZAUTH_YES; - } - - /* Try again. This way we can switch to the same checksums - * that the rest of Zephyr uses at a future date, but for now - * we need to be compatible */ - checksum = compute_checksum(notice, session_key); - if (checksum == notice->z_checksum) { - memcpy(__Zephyr_session, session_key, sizeof(C_Block)); - return ZAUTH_YES; - } - } - - /* We don't have the session key cached; do it the long way. */ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, from->sin_addr.s_addr, &dat, srvtab_file); if (result == RD_AP_OK) { @@ -234,11 +202,6 @@ ZCheckRealmAuthentication(notice, from, realm) return ZAUTH_FAILED; } - /* Record the session key, expiry time, and source principal in the - * hash table, so we can do a fast check next time. */ - add_session_key(&ticket, dat.session, srcprincipal, - (time_t)(dat.time_sec + dat.life * 5 * 60)); - return ZAUTH_YES; #else /* !HAVE_KRB4 */ @@ -275,28 +238,6 @@ ZCheckAuthentication(notice, from) } authent.length = notice->z_authent_len; - /* Copy the ticket out of the authentication data. */ - if (krb_find_ticket(&authent, &ticket) != RD_AP_OK) - return ZAUTH_FAILED; - - /* Try to do a fast check against the cryptographic checksum. */ - if (find_session_key(&ticket, session_key, srcprincipal) >= 0) { - if (strcmp(srcprincipal, notice->z_sender) != 0) - return ZAUTH_FAILED; - if (notice->z_time.tv_sec - NOW > CLOCK_SKEW) - return ZAUTH_FAILED; - checksum = compute_checksum(notice, session_key); - - /* If checksum matches, packet is authentic. If not, we might - * have an outdated session key, so keep going the slow way. - */ - if (checksum == notice->z_checksum) { - memcpy(__Zephyr_session, session_key, sizeof(C_Block)); - return ZAUTH_YES; - } - } - - /* We don't have the session key cached; do it the long way. */ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, from->sin_addr.s_addr, &dat, srvtab_file); if (result == RD_AP_OK) { @@ -318,11 +259,6 @@ ZCheckAuthentication(notice, from) if (checksum != notice->z_checksum) return ZAUTH_FAILED; - /* Record the session key, expiry time, and source principal in the - * hash table, so we can do a fast check next time. */ - add_session_key(&ticket, dat.session, srcprincipal, - (time_t)(dat.time_sec + dat.life * 5 * 60)); - return ZAUTH_YES; #else /* !HAVE_KRB4 */ |