diff options
author | Greg Hudson <ghudson@mit.edu> | 1997-09-14 17:50:06 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 1997-09-14 17:50:06 +0000 |
commit | ac16f380e349fa39ec7e26bccb5456cb300006a5 (patch) | |
tree | c07ca88af97b4f6b77d28a2dc723d2e4621ed302 /server/kstuff.c.auth | |
parent | d33e482744fad80d95cdd89ed380c5b8401e49bf (diff) |
Pull in sources from zephyr locker. See /mit/zephyr/repository for
detailed change information.
Diffstat (limited to 'server/kstuff.c.auth')
-rw-r--r-- | server/kstuff.c.auth | 363 |
1 files changed, 0 insertions, 363 deletions
diff --git a/server/kstuff.c.auth b/server/kstuff.c.auth deleted file mode 100644 index f81da75..0000000 --- a/server/kstuff.c.auth +++ /dev/null @@ -1,363 +0,0 @@ -#ifdef KERBEROS -/* This file is part of the Project Athena Zephyr Notification System. - * It contains functions for dealing with Kerberos functions in the server. - * - * Created by: John T Kohl - * - * Copyright (c) 1988 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - */ -/* - * $Source$ - * $Header$ - */ - -#ifndef lint -#ifndef SABER -static char rcsid_kstuff_c[] = "$Id$"; -#endif -#endif - -#include "zserver.h" - -#include <ctype.h> -#include <netdb.h> -#include <string.h> - -#include <zephyr/zephyr_internal.h> -#ifdef KERBEROS -#include <zephyr/krb_err.h> -#endif - -/* Keep a hash table mapping tickets to session keys, so we can do a fast - * check of the cryptographic checksum without doing and DES decryptions. - * Also remember the expiry time of the ticket, so that we can sweep the - * table periodically. */ - -#define HASHTAB_SIZE 4091 - -typedef struct hash_entry Hash_entry; - -/* The ticket comes at the end, in a variable-length array. */ -struct hash_entry { - C_Block session_key; - time_t expires; - char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; - Hash_entry *next; - int ticket_len; - unsigned char ticket[1]; -}; - -Hash_entry *hashtab[HASHTAB_SIZE]; - -static char tkt_file[] = ZEPHYR_TKFILE; - -#ifdef __STDC__ -static int hash_ticket(unsigned char *, int); -static void add_session_key(KTEXT, C_Block, char *, time_t); -static int find_session_key(KTEXT, C_Block, char *); -#else -static int hash_ticket(); -static void add_session_key(); -static int find_session_key(); -#endif - -/* - * GetKerberosData - * - * get ticket from file descriptor and decode it. - * Return KFAILURE if we barf on reading the ticket, else return - * the value of rd_ap_req() applied to the ticket. - */ -int -GetKerberosData(fd, haddr, kdata, service, srvtab) - int fd; /* file descr. to read from */ - struct in_addr haddr; /* address of foreign host on fd */ - AUTH_DAT *kdata; /* kerberos data (returned) */ - char *service; /* service principal desired */ - char *srvtab; /* file to get keys from */ -{ - char p[20]; - KTEXT_ST ticket; /* will get Kerberos ticket from client */ - int i; - char instance[INST_SZ]; - - /* - * Get the Kerberos ticket. The first few characters, terminated - * by a blank, should give us a length; then get than many chars - * which will be the ticket proper. - */ - for (i=0; i<20; i++) { - if (read(fd, &p[i], 1) != 1) { - syslog(LOG_WARNING,"bad read tkt len"); - return(KFAILURE); - } - if (p[i] == ' ') { - p[i] = '\0'; - break; - } - } - ticket.length = atoi(p); - if ((i==20) || (ticket.length<=0) || (ticket.length>MAX_KTXT_LEN)) { - syslog(LOG_WARNING,"bad tkt len %d",ticket.length); - return(KFAILURE); - } - for (i=0; i<ticket.length; i++) { - if (read(fd, (caddr_t) &(ticket.dat[i]), 1) != 1) { - syslog(LOG_WARNING,"bad tkt read"); - return(KFAILURE); - } - } - /* - * now have the ticket. use it to get the authenticated - * data from Kerberos. - */ - (void) strcpy(instance,"*"); /* let Kerberos fill it in */ - - return(krb_rd_req(&ticket, service, instance, haddr.s_addr, - kdata, srvtab ? srvtab : "")); -} - -/* - * SendKerberosData - * - * create and transmit a ticket over the file descriptor for service.host - * return failure codes if appropriate, or 0 if we - * get the ticket and write it to the file descriptor - */ - -int -SendKerberosData(fd, ticket, service, host) - int fd; /* file descriptor to write onto */ - KTEXT ticket; /* where to put ticket (return) */ - char *service; /* service name, foreign host */ - char *host; -{ - int rem; - char p[32]; - char krb_realm[REALM_SZ]; - int written; - int size_to_write; - - rem = krb_get_lrealm(krb_realm,1); - if (rem != KSUCCESS) - return rem + krb_err_base; - - rem = krb_mk_req( ticket, service, host, krb_realm, (u_long)0 ); - if (rem != KSUCCESS) - return rem + krb_err_base; - - (void) sprintf(p,"%d ",ticket->length); - size_to_write = strlen (p); - if ((written = write(fd, p, size_to_write)) != size_to_write) - if (written < 0) - return errno; - else - return ZSRV_PKSHORT; - if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length)) != ticket->length) - if (written < 0) - return errno; - else - return ZSRV_PKSHORT; - - return 0; -} - -/* Hack to replace the kerberos library's idea of the ticket file with - our idea */ -char * -tkt_string() -{ - return tkt_file; -} - -int -ZCheckAuthentication(notice, from) - ZNotice_t *notice; - struct sockaddr_in *from; -{ -#ifdef Z_HaveKerberos - int result, len; - char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; - KTEXT_ST authent, ticket; - AUTH_DAT dat; - ZChecksum_t our_checksum; - unsigned long cksum; - CREDENTIALS cred; - C_Block session_key; - - if (!notice->z_auth) - return (ZAUTH_NO); - - /* Check for bogus authentication data length. */ - if (notice->z_authent_len <= 0) - return(ZAUTH_FAILED); - - /* Read in the authentication data. */ - if (ZReadAscii(notice->z_ascii_authent, - strlen(notice->z_ascii_authent)+1, - (unsigned char *)authent.dat, - notice->z_authent_len) == ZERR_BADFIELD) { - return (ZAUTH_FAILED); - } - 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); -#ifdef NOENCRYPTION - our_checksum = 0; -#else - len = notice->z_default_format + strlen(notice->z_default_format) - + 1 - notice->z_packet; - result = des_quad_cksum(notice->z_packet, NULL, len, 0, session_key); - result ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len, - 0, session_key); - our_checksum = (ZChecksum_t) result; -#endif - /* If checksum matches, packet is authentic. Otherwise, check - * the authenticator as if we didn't have the session key cached - * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the - * ticket isn't cached after a checksum failure), so don't worry - * about the extra des_quad_cksum() call. */ - if (our_checksum == notice->z_checksum) - 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, SERVER_SRVTAB); - if (result == RD_AP_OK) { - (void) memcpy((char *)__Zephyr_session, (char *)dat.session, - sizeof(C_Block)); - (void) sprintf(srcprincipal, "%s%s%s@%s", dat.pname, - dat.pinst[0]?".":"", dat.pinst, dat.prealm); - if (strcmp(srcprincipal, notice->z_sender)) - return (ZAUTH_FAILED); - } else { - return (ZAUTH_FAILED); /* didn't decode correctly */ - } - - /* Check the cryptographic checksum. */ -#ifdef NOENCRYPTION - our_checksum = 0; -#else - len = notice->z_default_format + strlen(notice->z_default_format) - + 1 - notice->z_packet; - cksum = des_quad_cksum(notice->z_packet, NULL, len, 0, dat.session); - our_checksum = (ZChecksum_t) cksum; -#endif - if (our_checksum != notice->z_checksum) - return (ZAUTH_CKSUM_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 /* not Z_HaveKerberos */ - return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO); -#endif -} - -static int hash_ticket(p, len) - unsigned char *p; - int len; -{ - unsigned long hashval = 0, g; - - for (; len > 0; p++, len--) { - hashval = (hashval << 4) + *p; - g = hashval & 0xf0000000; - if (g) { - hashval ^= g >> 24; - hashval ^= g; - } - } - return hashval % HASHTAB_SIZE; -} - -static void add_session_key(ticket, session_key, srcprincipal, expires) - KTEXT ticket; - C_Block session_key; - char *srcprincipal; - time_t expires; -{ - Hash_entry *entry; - int hashval; - - /* If we can't allocate memory for the hash table entry, just forget - * about it. */ - entry = (Hash_entry *) xmalloc(sizeof(Hash_entry) - 1 + ticket->length); - if (!entry) - return; - - /* Initialize the new entry. */ - memcpy(entry->session_key, session_key, sizeof(entry->session_key)); - strcpy(entry->srcprincipal, srcprincipal); - entry->expires = expires; - entry->ticket_len = ticket->length; - memcpy(entry->ticket, ticket->dat, ticket->length * sizeof(unsigned char)); - - /* Insert the new entry in the hash table. */ - hashval = hash_ticket(ticket->dat, ticket->length); - entry->next = hashtab[hashval]; - hashtab[hashval] = entry; -} - -static int find_session_key(ticket, key, srcprincipal) - KTEXT ticket; - C_Block key; - char *srcprincipal; -{ - unsigned char *dat; - int hashval, len; - Hash_entry *entry; - - dat = ticket->dat; - len = ticket->length; - hashval = hash_ticket(dat, len); - - for (entry = hashtab[hashval]; entry; entry = entry->next) { - if (entry->ticket_len == len && memcmp(entry->ticket, dat, len) == 0) { - memcpy(key, entry->session_key, sizeof(entry->session_key)); - strcpy(srcprincipal, entry->srcprincipal); - return 0; - } - } - return -1; -} - -void sweep_ticket_hash_table(arg) - void *arg; -{ - int i; - Hash_entry **ptr, *entry; - - for (i = 0; i < HASHTAB_SIZE; i++) { - ptr = &hashtab[i]; - while (*ptr) { - entry = *ptr; - if (entry->expires < NOW) { - *ptr = entry->next; - free(entry); - } else { - ptr = &(*ptr)->next; - } - } - } - timer_set_rel(SWEEP_INTERVAL, sweep_ticket_hash_table, NULL); -} - -#endif /* KERBEROS */ - |