summaryrefslogtreecommitdiffstats
path: root/eBones/krb
diff options
context:
space:
mode:
Diffstat (limited to 'eBones/krb')
-rw-r--r--eBones/krb/Makefile31
-rw-r--r--eBones/krb/add_ticket.c88
-rw-r--r--eBones/krb/create_auth_reply.c116
-rw-r--r--eBones/krb/create_ciph.c109
-rw-r--r--eBones/krb/create_death_packet.c63
-rw-r--r--eBones/krb/create_ticket.c130
-rw-r--r--eBones/krb/debug_decl.c18
-rw-r--r--eBones/krb/decomp_ticket.c123
-rw-r--r--eBones/krb/des_rw.c265
-rw-r--r--eBones/krb/dest_tkt.c87
-rw-r--r--eBones/krb/extract_ticket.c58
-rw-r--r--eBones/krb/fgetst.c39
-rw-r--r--eBones/krb/get_ad_tkt.c234
-rw-r--r--eBones/krb/get_admhst.c79
-rw-r--r--eBones/krb/get_cred.c60
-rw-r--r--eBones/krb/get_in_tkt.c288
-rw-r--r--eBones/krb/get_krbhst.c84
-rw-r--r--eBones/krb/get_krbrlm.c59
-rw-r--r--eBones/krb/get_phost.c53
-rw-r--r--eBones/krb/get_pw_tkt.c72
-rw-r--r--eBones/krb/get_request.c52
-rw-r--r--eBones/krb/get_svc_in_tkt.c73
-rw-r--r--eBones/krb/get_tf_fullname.c66
-rw-r--r--eBones/krb/get_tf_realm.c34
-rw-r--r--eBones/krb/getrealm.c104
-rw-r--r--eBones/krb/getst.c35
-rw-r--r--eBones/krb/in_tkt.c142
-rw-r--r--eBones/krb/k_gethostname.c65
-rw-r--r--eBones/krb/klog.c108
-rw-r--r--eBones/krb/kname_parse.c233
-rw-r--r--eBones/krb/kntoln.c60
-rw-r--r--eBones/krb/kparse.c763
-rw-r--r--eBones/krb/krb_err.et257
-rw-r--r--eBones/krb/krb_err_txt.c278
-rw-r--r--eBones/krb/krb_get_in_tkt.c297
-rw-r--r--eBones/krb/krb_realmofhost.3161
-rw-r--r--eBones/krb/krb_sendauth.3348
-rw-r--r--eBones/krb/krb_set_tkt_string.343
-rw-r--r--eBones/krb/krbglue.c252
-rw-r--r--eBones/krb/kuserok.363
-rw-r--r--eBones/krb/kuserok.c195
-rw-r--r--eBones/krb/log.c121
-rw-r--r--eBones/krb/mk_err.c63
-rw-r--r--eBones/krb/mk_priv.c203
-rw-r--r--eBones/krb/mk_req.c195
-rw-r--r--eBones/krb/mk_safe.c168
-rw-r--r--eBones/krb/month_sname.c31
-rw-r--r--eBones/krb/netread.c46
-rw-r--r--eBones/krb/netwrite.c42
-rw-r--r--eBones/krb/one.c20
-rw-r--r--eBones/krb/pkt_cipher.c38
-rw-r--r--eBones/krb/pkt_clen.c53
-rw-r--r--eBones/krb/rd_err.c79
-rw-r--r--eBones/krb/rd_priv.c204
-rw-r--r--eBones/krb/rd_req.c328
-rw-r--r--eBones/krb/rd_safe.c180
-rw-r--r--eBones/krb/read_service_key.c120
-rw-r--r--eBones/krb/recvauth.c286
-rw-r--r--eBones/krb/save_credentials.c53
-rw-r--r--eBones/krb/send_to_kdc.c313
-rw-r--r--eBones/krb/sendauth.c257
-rw-r--r--eBones/krb/stime.c40
-rw-r--r--eBones/krb/tf_shm.c174
-rw-r--r--eBones/krb/tf_util.3151
-rw-r--r--eBones/krb/tf_util.c572
-rw-r--r--eBones/krb/tkt_string.c79
-rw-r--r--eBones/krb/util.c72
67 files changed, 9573 insertions, 0 deletions
diff --git a/eBones/krb/Makefile b/eBones/krb/Makefile
new file mode 100644
index 0000000..8336132
--- /dev/null
+++ b/eBones/krb/Makefile
@@ -0,0 +1,31 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1994/09/07 16:10:17 g89r4222 Exp $
+
+LIB= krb
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42
+SRCS= create_auth_reply.c create_ciph.c \
+ create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
+ des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \
+ get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \
+ get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \
+ get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \
+ k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \
+ krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \
+ mk_priv.c mk_req.c mk_safe.c month_sname.c \
+ netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \
+ rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \
+ save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \
+ tkt_string.c util.c
+
+TDIR= ${.CURDIR}/..
+krb_err.et.c: ${COMPILE_ET}
+ (cd ${TDIR}/compile_et; make)
+ ${COMPILE_ET} ${.CURDIR}/krb_err.et -n
+
+beforedepend: krb_err.et.c
+
+CLEANFILES+= krb_err.et.c krb_err.h
+
+.include <bsd.lib.mk>
diff --git a/eBones/krb/add_ticket.c b/eBones/krb/add_ticket.c
new file mode 100644
index 0000000..cb79a18
--- /dev/null
+++ b/eBones/krb/add_ticket.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $
+ * $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is now obsolete. It used to be possible to request
+ * more than one ticket at a time from the authentication server, and
+ * it looks like this routine was used by the server to package the
+ * tickets to be returned to the client.
+ */
+
+/*
+ * This routine adds a new ticket to the ciphertext to be returned to
+ * the client. The routine takes the ciphertext (which doesn't get
+ * encrypted till later), the number of the ticket (i.e. 1st, 2nd,
+ * etc) the session key which goes in the ticket and is sent back to
+ * the user, the lifetime for the ticket, the service name, the
+ * instance, the realm, the key version number, and the ticket itself.
+ *
+ * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on
+ * failure. On failure, which occurs when there isn't enough room
+ * for the ticket, a 0 length ticket is added.
+ *
+ * Notes: This routine must be called with successive values of n.
+ * i.e. the ticket must be added in order. The corresponding routine
+ * on the client side is extract ticket.
+ */
+
+/* XXX they aren't all used; to avoid incompatible changes we will
+ * fool lint for the moment */
+/*ARGSUSED */
+add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket)
+ KTEXT cipher; /* Ciphertext info for ticket */
+ char *sname; /* Service name */
+ char *instance; /* Instance */
+ int n; /* Relative position of this ticket */
+ char *session; /* Session key for this tkt */
+ int lifetime; /* Lifetime of this ticket */
+ char *realm; /* Realm in which ticket is valid */
+ int kvno; /* Key version number of service key */
+ KTEXT ticket; /* The ticket itself */
+{
+
+ /* Note, the 42 is a temporary hack; it will have to be changed. */
+
+ /* Begin check of ticket length */
+ if ((cipher->length + ticket->length + 4 + 42 +
+ (*(cipher->dat)+1-n)*(11+strlen(realm))) >
+ MAX_KTXT_LEN) {
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ *(cipher->dat+n) = 0;
+ return(KFAILURE);
+ }
+ /* End check of ticket length */
+
+ /* Add the session key, lifetime, kvno, ticket to the ciphertext */
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length),
+ ticket->length);
+ cipher->length += ticket->length;
+
+ /* Set the ticket length at beginning of ciphertext */
+ *(cipher->dat+n) = ticket->length;
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/create_auth_reply.c b/eBones/krb/create_auth_reply.c
new file mode 100644
index 0000000..e47d4df
--- /dev/null
+++ b/eBones/krb/create_auth_reply.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $
+ * $Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is called by the Kerberos authentication server
+ * to create a reply to an authentication request. The routine
+ * takes the user's name, instance, and realm, the client's
+ * timestamp, the number of tickets, the user's key version
+ * number and the ciphertext containing the tickets themselves.
+ * It constructs a packet and returns a pointer to it.
+ *
+ * Notes: The packet returned by this routine is static. Thus, if you
+ * intend to keep the result beyond the next call to this routine, you
+ * must copy it elsewhere.
+ *
+ * The packet is built in the following format:
+ *
+ * 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 w_1 cipher length
+ *
+ * --- cipher->dat cipher data
+ */
+
+KTEXT
+create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long time_ws; /* Workstation time */
+ int n; /* Number of tickets */
+ unsigned long x_date; /* Principal's expiration date */
+ int kvno; /* Principal's key version number */
+ KTEXT cipher; /* Cipher text with tickets and
+ * session keys */
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ unsigned char *v = pkt->dat; /* Prot vers number */
+ unsigned char *t = (pkt->dat+1); /* Prot message type */
+ short w_l; /* Cipher length */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ if (n != 0)
+ *v = 3;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2), pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* Workstation timestamp */
+ bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+ /* Expiration date */
+ bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+
+ /* Now send the ciphertext and info to help decode it */
+ *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
+ w_l = (short) cipher->length;
+ bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
+ pkt->length += 2;
+ bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
+ cipher->length);
+ pkt->length += cipher->length;
+
+ /* And return the packet */
+ return pkt;
+}
diff --git a/eBones/krb/create_ciph.c b/eBones/krb/create_ciph.c
new file mode 100644
index 0000000..c3bc0db
--- /dev/null
+++ b/eBones/krb/create_ciph.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $
+ * $Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <strings.h>
+
+/*
+ * This routine is used by the authentication server to create
+ * a packet for its client, containing a ticket for the requested
+ * service (given in "tkt"), and some information about the ticket,
+ *
+ * Returns KSUCCESS no matter what.
+ *
+ * The length of the cipher is stored in c->length; the format of
+ * c->dat is as follows:
+ *
+ * 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
+ *
+ */
+
+create_ciph(c, session, service, instance, realm, life, kvno, tkt,
+ kdc_time, key)
+ KTEXT c; /* Text block to hold ciphertext */
+ C_Block session; /* Session key to send to user */
+ char *service; /* Service name on ticket */
+ char *instance; /* Instance name on ticket */
+ char *realm; /* Realm of this KDC */
+ unsigned long life; /* Lifetime of the ticket */
+ int kvno; /* Key version number for service */
+ KTEXT tkt; /* The ticket for the service */
+ unsigned long kdc_time; /* KDC time */
+ C_Block key; /* Key to encrypt ciphertext with */
+{
+ char *ptr;
+ Key_schedule key_s;
+
+ ptr = (char *) c->dat;
+
+ bcopy((char *) session, ptr, 8);
+ ptr += 8;
+
+ (void) strcpy(ptr,service);
+ ptr += strlen(service) + 1;
+
+ (void) strcpy(ptr,instance);
+ ptr += strlen(instance) + 1;
+
+ (void) strcpy(ptr,realm);
+ ptr += strlen(realm) + 1;
+
+ *(ptr++) = (unsigned char) life;
+ *(ptr++) = (unsigned char) kvno;
+ *(ptr++) = (unsigned char) tkt->length;
+
+ bcopy((char *)(tkt->dat),ptr,tkt->length);
+ ptr += tkt->length;
+
+ bcopy((char *) &kdc_time,ptr,4);
+ ptr += 4;
+
+ /* guarantee null padded encrypted data to multiple of 8 bytes */
+ bzero(ptr, 7);
+
+ c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s,
+ key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/create_death_packet.c b/eBones/krb/create_death_packet.c
new file mode 100644
index 0000000..f747d6b
--- /dev/null
+++ b/eBones/krb/create_death_packet.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $
+ * $Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a packet to type AUTH_MSG_DIE which is sent to
+ * the Kerberos server to make it shut down. It is used only in the
+ * development environment.
+ *
+ * It takes a string "a_name" which is sent in the packet. A pointer
+ * to the packet is returned.
+ *
+ * The format of the killer packet is:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_DIE message type
+ *
+ * [least significant HOST_BYTE_ORDER byte order of sender
+ * bit of above field]
+ *
+ * string a_name presumably, name of
+ * principal sending killer
+ * packet
+ */
+
+#ifdef DEBUG
+KTEXT
+krb_create_death_packet(a_name)
+ char *a_name;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+
+ unsigned char *v = pkt->dat;
+ unsigned char *t = (pkt->dat+1);
+ *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);
+ return pkt;
+}
+#endif /* DEBUG */
diff --git a/eBones/krb/create_ticket.c b/eBones/krb/create_ticket.c
new file mode 100644
index 0000000..984d8e9
--- /dev/null
+++ b/eBones/krb/create_ticket.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $
+ * $Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed. It then constructs a ticket and returns, leaving the
+ * newly created ticket in 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.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket. When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * tkt->length length of ticket (multiple of 8 bytes)
+ *
+ * tkt->dat:
+ *
+ * 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 krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+{
+ Key_schedule key_s;
+ register char *data; /* running index into ticket */
+
+ tkt->length = 0; /* Clear previous data */
+ flags |= HOST_BYTE_ORDER; /* ticket byte order */
+ bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
+ data = ((char *)tkt->dat) + sizeof(flags);
+ (void) strcpy(data, pname);
+ data += 1 + strlen(pname);
+ (void) strcpy(data, pinstance);
+ data += 1 + strlen(pinstance);
+ (void) strcpy(data, prealm);
+ data += 1 + strlen(prealm);
+ bcopy((char *) &paddress, data, 4);
+ data += 4;
+
+ bcopy((char *) session, data, 8);
+ data += 8;
+ *(data++) = (char) life;
+ /* issue time */
+ bcopy((char *) &time_sec, data, 4);
+ data += 4;
+ (void) strcpy(data, sname);
+ data += 1 + strlen(sname);
+ (void) strcpy(data, sinstance);
+ data += 1 + strlen(sinstance);
+
+ /* guarantee null padded ticket to multiple of 8 bytes */
+ bzero(data, 7);
+ tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+ /* Check length of ticket */
+ if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+ bzero(tkt->dat, tkt->length);
+ tkt->length = 0;
+ return KFAILURE /* XXX */;
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,ENCRYPT);
+#endif
+ return 0;
+}
diff --git a/eBones/krb/debug_decl.c b/eBones/krb/debug_decl.c
new file mode 100644
index 0000000..1a0f6df
--- /dev/null
+++ b/eBones/krb/debug_decl.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $
+ * $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $";
+#endif lint
+
+/* Declare global debugging variables. */
+
+int krb_ap_req_debug = 0;
+int krb_debug = 0;
diff --git a/eBones/krb/decomp_ticket.c b/eBones/krb/decomp_ticket.c
new file mode 100644
index 0000000..181864c
--- /dev/null
+++ b/eBones/krb/decomp_ticket.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $
+ * $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine takes a ticket and pointers to the variables that
+ * should be filled in based on the information in the ticket. It
+ * fills in values for its arguments.
+ *
+ * Note: if the client realm field in the ticket is the null string,
+ * then the "prealm" variable is filled in with the local realm (as
+ * defined by KRB_REALM).
+ *
+ * If the ticket byte order is different than the host's byte order
+ * (as indicated by the byte order bit of the "flags" field), then
+ * the KDC timestamp "time_sec" is byte-swapped. The other fields
+ * potentially affected by byte order, "paddress" and "session" are
+ * not byte-swapped.
+ *
+ * The routine returns KFAILURE if any of the "pname", "pinstance",
+ * or "prealm" fields is too big, otherwise it returns KSUCCESS.
+ *
+ * The corresponding routine to generate tickets is create_ticket.
+ * When changes are made to this routine, the corresponding changes
+ * should also be made to that file.
+ *
+ * See create_ticket.c for the format of the ticket packet.
+ */
+
+decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
+ life, time_sec, sname, sinstance, key, key_s)
+ KTEXT tkt; /* The ticket to be decoded */
+ unsigned char *flags; /* Kerberos ticket flags */
+ char *pname; /* Authentication name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ unsigned long *paddress; /* Net address of entity
+ * requesting ticket */
+ C_Block session; /* Session key inserted in ticket */
+ int *life; /* Lifetime of the ticket */
+ unsigned long *time_sec; /* Issue time and date */
+ char *sname; /* Service name */
+ char *sinstance; /* Service instance */
+ C_Block key; /* Service's secret key
+ * (to decrypt the ticket) */
+ Key_schedule key_s; /* The precomputed key schedule */
+{
+ static int tkt_swap_bytes;
+ unsigned char *uptr;
+ char *ptr = (char *)tkt->dat;
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,DECRYPT);
+#endif /* ! NOENCRYPTION */
+
+ *flags = *ptr; /* get flags byte */
+ ptr += sizeof(*flags);
+ tkt_swap_bytes = 0;
+ if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
+ tkt_swap_bytes++;
+
+ if (strlen(ptr) > ANAME_SZ)
+ return(KFAILURE);
+ (void) strcpy(pname,ptr); /* pname */
+ ptr += strlen(pname) + 1;
+
+ if (strlen(ptr) > INST_SZ)
+ return(KFAILURE);
+ (void) strcpy(pinstance,ptr); /* instance */
+ ptr += strlen(pinstance) + 1;
+
+ if (strlen(ptr) > REALM_SZ)
+ return(KFAILURE);
+ (void) strcpy(prealm,ptr); /* realm */
+ ptr += strlen(prealm) + 1;
+ /* temporary hack until realms are dealt with properly */
+ if (*prealm == 0)
+ (void) strcpy(prealm,KRB_REALM);
+
+ bcopy(ptr,(char *)paddress,4); /* net address */
+ ptr += 4;
+
+ bcopy(ptr,(char *)session,8); /* session key */
+ ptr+= 8;
+#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
+ if (tkt_swap_bytes)
+ swap_C_Block(session);
+#endif
+
+ /* get lifetime, being certain we don't get negative lifetimes */
+ uptr = (unsigned char *) ptr++;
+ *life = (int) *uptr;
+
+ bcopy(ptr,(char *) time_sec,4); /* issue time */
+ ptr += 4;
+ if (tkt_swap_bytes)
+ swap_u_long(*time_sec);
+
+ (void) strcpy(sname,ptr); /* service name */
+ ptr += 1 + strlen(sname);
+
+ (void) strcpy(sinstance,ptr); /* instance */
+ ptr += 1 + strlen(sinstance);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/des_rw.c b/eBones/krb/des_rw.c
new file mode 100644
index 0000000..c958355
--- /dev/null
+++ b/eBones/krb/des_rw.c
@@ -0,0 +1,265 @@
+/* -
+ * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
+ * All rights reserved.
+ *
+ * This code is derived from a specification based on software
+ * which forms part of the 4.4BSD-Lite distribution, which was developed
+ * by the University of California and its contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the entire comment,
+ * including the above copyright notice, this list of conditions
+ * and the following disclaimer, verbatim, at the beginning of
+ * the source file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Geoffrey M. Rehmet
+ * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $
+ */
+
+/*
+ *
+ * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED.
+ *
+ */
+
+/*
+ * Routines for reading and writing DES encrypted messages onto sockets.
+ * (These routines will fail if non-blocking I/O is used.)
+ *
+ * When a message is written, its length is first transmitted as an int,
+ * in network byte order. The encrypted message is then transmitted,
+ * to a multiple of 8 bytes. Messages shorter than 8 bytes are right
+ * justified into a buffer of length 8 bytes, and the remainder of the
+ * buffer is filled with random garbage (before encryption):
+ *
+ * DDD -------->--+--------+
+ * | |
+ * +--+--+--+--+--+--+--+--+
+ * |x |x |x |x |x |D |D |D |
+ * +--+--+--+--+--+--+--+--+
+ * | garbage | data |
+ * | |
+ * +-----------------------+----> des_pcbc_encrypt() -->
+ *
+ * (Note that the length field sent before the actual message specifies
+ * the number of data bytes, not the length of the entire padded message.
+ *
+ * When data is read, if the message received is longer than the number
+ * of bytes requested, then the remaining bytes are stored until the
+ * following call to des_read(). If the number of bytes received is
+ * less then the number of bytes received, then only the number of bytes
+ * actually received is returned.
+ *
+ * This interface corresponds with the original des_rw.c, except for the
+ * bugs in des_read() in the original 4.4BSD version. (One bug is
+ * normally not visible, due to undocumented behaviour of
+ * des_pcbc_encrypt() in the original MIT libdes.)
+ *
+ * XXX Todo:
+ * 1) Give better error returns on writes
+ * 2) Improve error checking on reads
+ * 3) Get rid of need for extern decl. of krb_net_read()
+ * 4) Tidy garbage generation a bit
+ * 5) Make the above comment more readable
+ */
+
+#ifdef CRYPT
+#ifdef KERBEROS
+
+#ifndef BUFFER_LEN
+#define BUFFER_LEN 10240
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+extern int krb_net_read(int fd, void * data, size_t length);
+extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output,
+ register long length,
+ des_key_schedule schedule,
+ des_cblock *ivec,
+ int encrypt);
+
+static bit_64 des_key;
+static des_key_schedule key_sched;
+
+/*
+ * Buffer for storing extra data when more data is received, then was
+ * actually requested in des_read().
+ */
+static u_char des_buff[BUFFER_LEN];
+static u_char buffer[BUFFER_LEN];
+static unsigned stored = 0;
+static u_char *buff_ptr = buffer;
+
+/*
+ * Set the encryption key for des_read() and des_write().
+ * inkey is the initial vector for the DES encryption, while insched is
+ * the DES key, in unwrapped form.
+ */
+void des_set_key(inkey, insched)
+ bit_64 *inkey;
+ u_char *insched;
+{
+ bcopy(inkey, &des_key, sizeof(bit_64));
+ bcopy(insched, &key_sched, sizeof(des_key_schedule));
+}
+
+/*
+ * Clear the key schedule, and initial vector, which were previously
+ * stored in static vars by des_set_key().
+ */
+void des_clear_key()
+{
+ bzero(&des_key, sizeof(des_cblock));
+ bzero(&key_sched, sizeof(des_key_schedule));
+}
+
+int des_read(fd, buf, len)
+ int fd;
+ register char * buf;
+ int len;
+{
+ int msg_length; /* length of actual message data */
+ int pad_length; /* length of padded message */
+ int nread; /* number of bytes actually read */
+ int nreturned = 0;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ return(len);
+ } else {
+ if (stored) {
+ bcopy(buff_ptr, buf, stored);
+ nreturned = stored;
+ len -= stored;
+ stored = 0;
+ buff_ptr = buffer;
+ } else {
+ nreturned = 0;
+ buff_ptr = buffer;
+ }
+ }
+
+ nread = krb_net_read(fd, &msg_length, sizeof(msg_length));
+ if(nread != (int)(sizeof(msg_length)))
+ return(0);
+
+ msg_length = ntohl(msg_length);
+ pad_length = roundup(msg_length, 8);
+
+ nread = krb_net_read(fd, des_buff, pad_length);
+ if(nread != pad_length)
+ return(0);
+
+ des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr,
+ (msg_length < 8 ? 8 : msg_length),
+ key_sched, (des_cblock*) &des_key, DES_DECRYPT);
+
+
+ if(msg_length < 8)
+ buff_ptr += (8 - msg_length);
+ stored = msg_length;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ nreturned += len;
+ } else {
+ bcopy(buff_ptr, buf, stored);
+ nreturned += stored;
+ stored = 0;
+ }
+
+ return(nreturned);
+}
+
+
+/*
+ * Write a message onto a file descriptor (generally a socket), using
+ * DES to encrypt the message.
+ */
+int des_write(fd, buf, len)
+ int fd;
+ char * buf;
+ int len;
+{
+ static int seeded = 0;
+ char garbage[8];
+ long rnd;
+ int pad_len;
+ int write_len;
+ int nwritten = 0;
+ int i;
+ char *data;
+
+ if(len < 8) {
+ /*
+ * Right justify the message in 8 bytes of random garbage.
+ */
+ if(!seeded) {
+ seeded = 1;
+ srandom((unsigned)time(NULL));
+ }
+
+ for(i = 0 ; i < 8 ; i+= sizeof(long)) {
+ rnd = random();
+ bcopy(&rnd, garbage+i,
+ (i <= (8 - sizeof(long)))?sizeof(long):(8-i));
+ }
+ bcopy(buf, garbage + 8 - len, len);
+ data = garbage;
+ pad_len = 8;
+ } else {
+ data = buf;
+ pad_len = roundup(len, 8);
+ }
+
+ des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff,
+ (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT);
+
+
+ write_len = htonl(len);
+ if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len))
+ return(-1);
+ if(write(fd, des_buff, pad_len) != pad_len)
+ return(-1);
+
+ return(len);
+}
+
+#endif /* KERBEROS */
+#endif /* CRYPT */
diff --git a/eBones/krb/dest_tkt.c b/eBones/krb/dest_tkt.c
new file mode 100644
index 0000000..17c7855
--- /dev/null
+++ b/eBones/krb/dest_tkt.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $
+ * $Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+#include <errno.h>
+
+/*
+ * dest_tkt() is used to destroy the ticket store upon logout.
+ * If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
+ * Otherwise the function returns RET_OK on success, KFAILURE on
+ * failure.
+ *
+ * The ticket file (TKT_FILE) is defined in "krb.h".
+ */
+
+dest_tkt()
+{
+ char *file = TKT_FILE;
+ int i,fd;
+ extern int errno;
+ struct stat statb;
+ char buf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ errno = 0;
+ if (lstat(file,&statb) < 0)
+ goto out;
+
+ if (!(statb.st_mode & S_IFREG)
+#ifdef notdef
+ || statb.st_mode & 077
+#endif
+ )
+ goto out;
+
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out;
+
+ bzero(buf, BUFSIZ);
+
+ for (i = 0; i < statb.st_size; i += BUFSIZ)
+ if (write(fd, buf, BUFSIZ) != BUFSIZ) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+
+ (void) unlink(file);
+
+out:
+ if (errno == ENOENT) return RET_TKFIL;
+ else if (errno != 0) return KFAILURE;
+#ifdef TKT_SHMEM
+ /*
+ * handle the shared memory case
+ */
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
+ return(i);
+#endif /* TKT_SHMEM */
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/extract_ticket.c b/eBones/krb/extract_ticket.c
new file mode 100644
index 0000000..571d5da
--- /dev/null
+++ b/eBones/krb/extract_ticket.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $
+ * $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is obsolete.
+ *
+ * This routine accepts the ciphertext returned by kerberos and
+ * extracts the nth ticket. It also fills in the variables passed as
+ * session, liftime and kvno.
+ */
+
+extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket)
+ KTEXT cipher; /* The ciphertext */
+ int n; /* Which ticket */
+ char *session; /* The session key for this tkt */
+ int *lifetime; /* The life of this ticket */
+ int *kvno; /* The kvno for the service */
+ char *realm; /* Realm in which tkt issued */
+ KTEXT ticket; /* The ticket itself */
+{
+ char *ptr;
+ int i;
+
+ /* Start after the ticket lengths */
+ ptr = (char *) cipher->dat;
+ ptr = ptr + 1 + (int) *(cipher->dat);
+
+ /* Step through earlier tickets */
+ for (i = 1; i < n; i++)
+ ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
+ bcopy(ptr, (char *) session, 8); /* Save the session key */
+ ptr += 8;
+ *lifetime = *(ptr++); /* Save the life of the ticket */
+ *kvno = *(ptr++); /* Save the kvno */
+ (void) strcpy(realm,ptr); /* instance */
+ ptr += strlen(realm) + 1;
+
+ /* Save the ticket if its length is non zero */
+ ticket->length = *(cipher->dat+n);
+ if (ticket->length)
+ bcopy(ptr, (char *) (ticket->dat), ticket->length);
+}
diff --git a/eBones/krb/fgetst.c b/eBones/krb/fgetst.c
new file mode 100644
index 0000000..d938013
--- /dev/null
+++ b/eBones/krb/fgetst.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $
+ * $Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+
+/*
+ * fgetst takes a file descriptor, a character pointer, and a count.
+ * It reads from the file it has either read "count" characters, or
+ * until it reads a null byte. When finished, what has been read exists
+ * in "s". If "count" characters were actually read, the last is changed
+ * to a null, so the returned string is always null-terminated. fgetst
+ * returns the number of characters read, including the null terminator.
+ */
+
+fgetst(f, s, n)
+ FILE *f;
+ register char *s;
+ int n;
+{
+ register count = n;
+ int ch; /* NOT char; otherwise you don't see EOF */
+
+ while ((ch = getc(f)) != EOF && ch && --count) {
+ *s++ = ch;
+ }
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/krb/get_ad_tkt.c b/eBones/krb/get_ad_tkt.c
new file mode 100644
index 0000000..d8e1283
--- /dev/null
+++ b/eBones/krb/get_ad_tkt.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $
+ * $Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+#include <strings.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+extern int krb_debug;
+
+struct timeval tt_local = { 0, 0 };
+
+int swap_bytes;
+unsigned long rep_err_code;
+
+/*
+ * get_ad_tkt obtains a new service ticket from Kerberos, using
+ * the ticket-granting ticket which must be in the ticket file.
+ * It is typically called by krb_mk_req() when the client side
+ * of an application is creating authentication information to be
+ * sent to the server side.
+ *
+ * get_ad_tkt takes four arguments: three pointers to strings which
+ * contain the name, instance, and realm of the service for which the
+ * ticket is to be obtained; and an integer indicating the desired
+ * lifetime of the ticket.
+ *
+ * It returns an error status if the ticket couldn't be obtained,
+ * or AD_OK if all went well. The ticket is stored in the ticket
+ * cache.
+ *
+ * The request sent to the Kerberos ticket-granting service looks
+ * like this:
+ *
+ * pkt->dat
+ *
+ * TEXT original contents of authenticator+ticket
+ * pkt->dat built in krb_mk_req call
+ *
+ * 4 bytes time_ws always 0 (?)
+ * char lifetime lifetime argument passed
+ * string service service name argument
+ * string sinstance service instance arg.
+ *
+ * See "prot.h" for the reply packet layout and definitions of the
+ * extraction macros like pkt_version(), pkt_msg_type(), etc.
+ */
+
+get_ad_tkt(service,sinstance,realm,lifetime)
+ char *service;
+ char *sinstance;
+ char *realm;
+ int lifetime;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = & pkt_st; /* Packet to KDC */
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ static KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ static KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ CREDENTIALS cr;
+ int kvno; /* Kvno for session key */
+ char lrealm[REALM_SZ];
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ long time_ws = 0;
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ int msg_byte_order;
+ int kerror;
+ char rlm[REALM_SZ];
+ char *ptr;
+
+ unsigned long kdc_time; /* KDC time */
+
+ if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+ return(kerror);
+
+ /* Create skeleton of packet to be sent */
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+
+ pkt->length = 0;
+
+ /*
+ * Look for the session key (and other stuff we don't need)
+ * in the ticket file for krbtgt.realm@lrealm where "realm"
+ * is the service's realm (passed in "realm" argument) and
+ * lrealm is the realm of our initial ticket. If we don't
+ * have this, we will try to get it.
+ */
+
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+ /*
+ * If realm == lrealm, we have no hope, so let's not even try.
+ */
+ if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
+ return(AD_NOTGT);
+ else{
+ if ((kerror =
+ get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
+ return(kerror);
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
+ return(kerror);
+ }
+ }
+
+ /*
+ * Make up a request packet to the "krbtgt.realm@lrealm".
+ * Start by calling krb_mk_req() which puts ticket+authenticator
+ * into "pkt". Then tack other stuff on the end.
+ */
+
+ kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+
+ if (kerror)
+ return(AD_NOTGT);
+
+ /* timestamp */
+ bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (char) lifetime;
+ (void) strcpy((char *) (pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* Send the request to the local ticket-granting server */
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION )
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
+ if (swap_bytes)
+ swap_u_long(rep_err_code);
+ return(rep_err_code);
+
+ default:
+ return(INTK_PROT);
+ }
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length,
+ key_s,cr.session,DECRYPT);
+#endif
+ /* Get rid of all traces of key */
+ bzero((char *) cr.session, sizeof(key));
+ bzero((char *) key_s, sizeof(key_s));
+
+ ptr = (char *) cip->dat;
+
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ lifetime = (unsigned long) ptr[0];
+ kvno = (unsigned long) ptr[1];
+ tkt->length = (int) ptr[2];
+ ptr += 3;
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+ if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
+ kvno,tkt,tt_local.tv_sec))
+ return(kerror);
+
+ return(AD_OK);
+}
diff --git a/eBones/krb/get_admhst.c b/eBones/krb/get_admhst.c
new file mode 100644
index 0000000..c36e997
--- /dev/null
+++ b/eBones/krb/get_admhst.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $
+ * $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <string.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos database
+ * administration server can be found.
+ *
+ * krb_get_admhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer n, and
+ * returns (in h) the nth administrative host entry from the configuration
+ * file (KRB_CONF, defined in "krb.h") associated with the specified realm.
+ *
+ * On error, get_admhst returns KFAILURE. If all goes well, the routine
+ * returns KSUCCESS.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * a Kerberos admin server. In the long run, this functionality will be
+ * provided by a nameserver.
+ */
+
+krb_get_admhst(h, r, n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char scratch[64];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ return(KFAILURE);
+ }
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ /* error reading */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (!index(linebuf, '\n')) {
+ /* didn't all fit into buffer, punt */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ for (i = 0; i < n; ) {
+ /* run through the file, looking for admin host */
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ /* need to scan for a token after 'admin' to make sure that
+ admin matched correctly */
+ if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_cred.c b/eBones/krb/get_cred.c
new file mode 100644
index 0000000..baf7ae2
--- /dev/null
+++ b/eBones/krb/get_cred.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $
+ * $Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * krb_get_cred takes a service name, instance, and realm, and a
+ * structure of type CREDENTIALS to be filled in with ticket
+ * information. It then searches the ticket file for the appropriate
+ * ticket and fills in the structure with the corresponding
+ * information from the file. If successful, it returns KSUCCESS.
+ * On failure it returns a Kerberos error code.
+ */
+
+krb_get_cred(service,instance,realm,c)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ CREDENTIALS *c; /* Credentials struct */
+{
+ int tf_status; /* return value of tf function calls */
+
+ /* Open ticket file and lock it for shared reading */
+ if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Copy principal's name and instance into the CREDENTIALS struc c */
+
+ if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
+ (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
+ return (tf_status);
+
+ /* Search for requested service credentials and copy into c */
+
+ while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
+ /* Is this the right ticket? */
+ if ((strcmp(c->service,service) == 0) &&
+ (strcmp(c->instance,instance) == 0) &&
+ (strcmp(c->realm,realm) == 0))
+ break;
+ }
+ (void) tf_close();
+
+ if (tf_status == EOF)
+ return (GC_NOTKT);
+ return(tf_status);
+}
diff --git a/eBones/krb/get_in_tkt.c b/eBones/krb/get_in_tkt.c
new file mode 100644
index 0000000..5fb1560
--- /dev/null
+++ b/eBones/krb/get_in_tkt.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $
+ * $Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: passwd_to_key() converts
+ * a password into a DES key (prompting for the password if
+ * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
+ * a user.
+ */
+
+/*
+ * passwd_to_key(): given a password, return a DES key.
+ * There are extra arguments here which (used to be?)
+ * used by srvtab_to_key().
+ *
+ * If the "passwd" argument is not null, generate a DES
+ * key from it, using string_to_key().
+ *
+ * If the "passwd" argument is null, call des_read_password()
+ * to prompt for a password and then convert it into a DES key.
+ *
+ * In either case, the resulting key is put in the "key" argument,
+ * and 0 is returned.
+ */
+
+/*ARGSUSED */
+static int passwd_to_key(user,instance,realm,passwd,key)
+ char *user, *instance, *realm, *passwd;
+ C_Block key;
+{
+#ifdef NOENCRYPTION
+ if (!passwd)
+ placebo_read_password(key, "Password: ", 0);
+#else
+ if (passwd)
+ string_to_key(passwd,key);
+ else
+ des_read_password(key,"Password: ",0);
+#endif
+ return (0);
+}
+
+/*
+ * krb_get_pw_in_tkt() takes the name of the server for which the initial
+ * ticket is to be obtained, the name of the principal the ticket is
+ * for, the desired lifetime of the ticket, and the user's password.
+ * It passes its arguments on to krb_get_in_tkt(), which contacts
+ * Kerberos to get the ticket, decrypts it using the password provided,
+ * and stores it away for future use.
+ *
+ * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
+ * the name of a routine (passwd_to_key()) to be used to get the
+ * password in case the "password" argument is null and NULL for the
+ * decryption procedure indicating that krb_get_in_tkt should use the
+ * default method of decrypting the response from the KDC.
+ *
+ * The result of the call to krb_get_in_tkt() is returned.
+ */
+
+krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return(krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+ passwd_to_key, NULL, password));
+}
+
+#ifdef NOENCRYPTION
+/*
+ * $Source: /home/CVS/src/eBones/krb/get_in_tkt.c,v $
+ * $Author: g89r4222 $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine prints the supplied string to standard
+ * output as a prompt, and reads a password string without
+ * echoing.
+ */
+
+#ifndef lint
+static char rcsid_read_password_c[] =
+"Bones$Header: /home/CVS/src/eBones/krb/get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif lint
+
+#include <des.h>
+#include "conf.h"
+
+#include <stdio.h>
+#ifdef BSDUNIX
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+#else
+char *strcpy();
+int strcmp();
+#endif
+
+#ifdef BSDUNIX
+static jmp_buf env;
+#endif
+
+#ifdef BSDUNIX
+static void sig_restore();
+static push_signals(), pop_signals();
+int placebo_read_pw_string();
+#endif
+
+/*** Routines ****************************************************** */
+int
+placebo_read_password(k,prompt,verify)
+ des_cblock *k;
+ char *prompt;
+ int verify;
+{
+ int ok;
+ char key_string[BUFSIZ];
+
+#ifdef BSDUNIX
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+#endif
+
+ ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
+ if (ok == 0)
+ bzero(k, sizeof(C_Block));
+
+lose:
+ bzero(key_string, sizeof (key_string));
+ return ok;
+}
+
+/*
+ * This version just returns the string, doesn't map to key.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int
+placebo_read_pw_string(s,max,prompt,verify)
+ char *s;
+ int max;
+ char *prompt;
+ int verify;
+{
+ int ok = 0;
+ char *ptr;
+
+#ifdef BSDUNIX
+ jmp_buf old_env;
+ struct sgttyb tty_state;
+#endif
+ char key_string[BUFSIZ];
+
+ if (max > BUFSIZ) {
+ return -1;
+ }
+
+#ifdef BSDUNIX
+ bcopy(old_env, env, sizeof(env));
+ if (setjmp(env))
+ goto lose;
+
+ /* save terminal state*/
+ if (ioctl(0,TIOCGETP,&tty_state) == -1)
+ return -1;
+
+ push_signals();
+ /* Turn off echo */
+ tty_state.sg_flags &= ~ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state) == -1)
+ return -1;
+#endif
+ while (!ok) {
+ printf(prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(s,sizeof(s),0);
+ if (!strlen(s))
+ continue;
+#else
+ if (!fgets(s, max, stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(s, '\n')))
+ *ptr = '\0';
+#endif
+ if (verify) {
+ printf("\nVerifying, please re-enter %s",prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(key_string,sizeof(key_string),0);
+ if (!strlen(key_string))
+ continue;
+#else
+ if (!fgets(key_string, sizeof(key_string), stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(key_string, '\n')))
+ *ptr = '\0';
+#endif
+ if (strcmp(s,key_string)) {
+ printf("\n\07\07Mismatch - try again\n");
+ fflush(stdout);
+ continue;
+ }
+ }
+ ok = 1;
+ }
+
+#ifdef BSDUNIX
+lose:
+ if (!ok)
+ bzero(s, max);
+ printf("\n");
+ /* turn echo back on */
+ tty_state.sg_flags |= ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state))
+ ok = 0;
+ pop_signals();
+ bcopy(env, old_env, sizeof(env));
+#endif
+ if (verify)
+ bzero(key_string, sizeof (key_string));
+ s[max-1] = 0; /* force termination */
+ return !ok; /* return nonzero if not okay */
+}
+
+#ifdef BSDUNIX
+/*
+ * this can be static since we should never have more than
+ * one set saved....
+ */
+#ifdef POSIX
+static void (*old_sigfunc[NSIG])();
+#else
+static int (*old_sigfunc[NSIG])();
+#endif POSIX
+
+static push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}
+#endif
+#endif /* NOENCRYPTION */
diff --git a/eBones/krb/get_krbhst.c b/eBones/krb/get_krbhst.c
new file mode 100644
index 0000000..16c4ff2
--- /dev/null
+++ b/eBones/krb/get_krbhst.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $
+ * $Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos authenti-
+ * cation server can be found.
+ *
+ * krb_get_krbhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer, n, and
+ * returns (in h) the nth entry from the configuration file (KRB_CONF,
+ * defined in "krb.h") associated with the specified realm.
+ *
+ * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the
+ * configuration file does not exist, krb_get_krbhst will return KRB_HOST
+ * (also defined in "krb.h"). If all goes well, the routine returnes
+ * KSUCCESS.
+ *
+ * The KRB_CONF file contains the name of the local realm in the first
+ * line (not used by this routine), followed by lines indicating realm/host
+ * entries. The words "admin server" following the hostname indicate that
+ * the host provides an administrative database server.
+ *
+ * For example:
+ *
+ * ATHENA.MIT.EDU
+ * ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ * ATHENA.MIT.EDU kerberos-2.mit.edu
+ * LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * kerberos. In the long run, this functionality will be provided by a
+ * nameserver.
+ */
+
+krb_get_krbhst(h,r,n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ if (n==1) {
+ (void) strcpy(h,KRB_HOST);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+ if (fscanf(cnffile,"%s",tr) == EOF)
+ return(KFAILURE);
+ /* run through the file, looking for the nth server for this realm */
+ for (i = 1; i <= n;) {
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (sscanf(linebuf, "%s %s", tr, h) != 2)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_krbrlm.c b/eBones/krb/get_krbrlm.c
new file mode 100644
index 0000000..7df073d
--- /dev/null
+++ b/eBones/krb/get_krbrlm.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $
+ * $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_get_lrealm takes a pointer to a string, and a number, n. It fills
+ * in the string, r, with the name of the nth realm specified on the
+ * first line of the kerberos config file (KRB_CONF, defined in "krb.h").
+ * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the
+ * config file does not exist, and if n=1, a successful return will occur
+ * with r = KRB_REALM (also defined in "krb.h").
+ *
+ * NOTE: for archaic & compatibility reasons, this routine will only return
+ * valid results when n = 1.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ */
+
+krb_get_lrealm(r,n)
+ char *r;
+ int n;
+{
+ FILE *cnffile, *fopen();
+
+ if (n > 1)
+ return(KFAILURE); /* Temporary restriction */
+
+ if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+ if (n == 1) {
+ (void) strcpy(r, KRB_REALM);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+
+ if (fscanf(cnffile,"%s",r) != 1) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_phost.c b/eBones/krb/get_phost.c
new file mode 100644
index 0000000..9b12d10
--- /dev/null
+++ b/eBones/krb/get_phost.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $
+ * $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+
+char *index();
+
+/*
+ * This routine takes an alias for a host name and returns the first
+ * field, lower case, of its domain name. For example, if "menel" is
+ * an alias for host officially named "menelaus" (in /etc/hosts), for
+ * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
+ * is returned.
+ *
+ * This is done for historical Athena reasons: the Kerberos name of
+ * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
+ * where "host"is the lowercase for of the host name ("menelaus").
+ * This should go away: the instance should be the domain name
+ * (MENELAUS.MIT.EDU). But for now we need this routine...
+ *
+ * A pointer to the name is returned, if found, otherwise a pointer
+ * to the original "alias" argument is returned.
+ */
+
+char * krb_get_phost(alias)
+ char *alias;
+{
+ struct hostent *h;
+ char *phost = alias;
+ if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
+ char *p = index( h->h_name, '.' );
+ if (p)
+ *p = NULL;
+ p = phost = h->h_name;
+ do {
+ if (isupper(*p)) *p=tolower(*p);
+ } while (*p++);
+ }
+ return(phost);
+}
diff --git a/eBones/krb/get_pw_tkt.c b/eBones/krb/get_pw_tkt.c
new file mode 100644
index 0000000..48a003c
--- /dev/null
+++ b/eBones/krb/get_pw_tkt.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $
+ * $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $";
+#endif /* lint */
+
+
+#include <krb.h>
+
+/*
+ * Get a ticket for the password-changing server ("changepw.KRB_MASTER").
+ *
+ * Given the name, instance, realm, and current password of the
+ * principal for which the user wants a password-changing-ticket,
+ * return either:
+ *
+ * GT_PW_BADPW if current password was wrong,
+ * GT_PW_NULL if principal had a NULL password,
+ * or the result of the krb_get_pw_in_tkt() call.
+ *
+ * First, try to get a ticket for "user.instance@realm" to use the
+ * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
+ * The requested lifetime for the ticket is "1", and the current
+ * password is the "cpw" argument given.
+ *
+ * If the password was bad, give up.
+ *
+ * If the principal had a NULL password in the Kerberos database
+ * (indicating that the principal is known to Kerberos, but hasn't
+ * got a password yet), try instead to get a ticket for the principal
+ * "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
+ * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL
+ * if all goes well, otherwise the error.
+ *
+ * If this routine succeeds, a ticket and session key for either the
+ * principal "user.instance@realm" or "default.changepw@realm" to use
+ * the password-changing server will be in the user's ticket file.
+ */
+
+get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ int kerror;
+
+ kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
+ KRB_MASTER, 1, cpw);
+
+ if (kerror == INTK_BADPW)
+ return(GT_PW_BADPW);
+
+ if (kerror == KDC_NULL_KEY) {
+ kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
+ KRB_MASTER,1,"changepwkrb");
+ if (kerror)
+ return(kerror);
+ return(GT_PW_NULL);
+ }
+
+ return(kerror);
+}
diff --git a/eBones/krb/get_request.c b/eBones/krb/get_request.c
new file mode 100644
index 0000000..131ffd5
--- /dev/null
+++ b/eBones/krb/get_request.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $
+ * $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * This procedure is obsolete. It is used in the kerberos_slave
+ * code for Version 3 tickets.
+ *
+ * This procedure sets s_name, and instance to point to
+ * the corresponding fields from tne nth request in the packet.
+ * it returns the lifetime requested. Garbage will be returned
+ * if there are less than n requests in the packet.
+ */
+
+get_request(pkt, n, s_name, instance)
+ KTEXT pkt; /* The packet itself */
+ int n; /* Which request do we want */
+ char **s_name; /* Service name to be filled in */
+ char **instance; /* Instance name to be filled in */
+{
+ /* Go to the beginning of the request list */
+ char *ptr = (char *) pkt_a_realm(pkt) + 6 +
+ strlen((char *)pkt_a_realm(pkt));
+
+ /* Read requests until we hit the right one */
+ while (n-- > 1) {
+ ptr++;
+ ptr += 1 + strlen(ptr);
+ ptr += 1 + strlen(ptr);
+ }
+
+ /* Set the arguments to point to the right place */
+ *s_name = 1 + ptr;
+ *instance = 2 + ptr + strlen(*s_name);
+
+ /* Return the requested lifetime */
+ return((int) *ptr);
+}
diff --git a/eBones/krb/get_svc_in_tkt.c b/eBones/krb/get_svc_in_tkt.c
new file mode 100644
index 0000000..6d9702f
--- /dev/null
+++ b/eBones/krb/get_svc_in_tkt.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $
+ * $Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: srvtab_to_key(), which gets
+ * a server's key from a srvtab file, and krb_get_svc_in_tkt() which
+ * gets an initial ticket for a server.
+ */
+
+/*
+ * srvtab_to_key(): given a "srvtab" file (where the keys for the
+ * service on a host are stored), return the private key of the
+ * given service (user.instance@realm).
+ *
+ * srvtab_to_key() passes its arguments on to read_service_key(),
+ * plus one additional argument, the key version number.
+ * (Currently, the key version number is always 0; this value
+ * is treated as a wildcard by read_service_key().)
+ *
+ * If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
+ * is passed in its place.
+ *
+ * It returns the return value of the read_service_key() call.
+ * The service key is placed in "key".
+ */
+
+static int srvtab_to_key(user, instance, realm, srvtab, key)
+ char *user, *instance, *realm, *srvtab;
+ C_Block key;
+{
+ if (!srvtab)
+ srvtab = KEYFILE;
+
+ return(read_service_key(user, instance, realm, 0, srvtab,
+ (char *)key));
+}
+
+/*
+ * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
+ * plus two additional arguments: a pointer to the srvtab_to_key()
+ * function to be used to get the key from the key file and a NULL
+ * for the decryption procedure indicating that krb_get_in_tkt should
+ * use the default method of decrypting the response from the KDC.
+ *
+ * It returns the return value of the krb_get_in_tkt() call.
+ */
+
+krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return(krb_get_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab_to_key, NULL, srvtab));
+}
diff --git a/eBones/krb/get_tf_fullname.c b/eBones/krb/get_tf_fullname.c
new file mode 100644
index 0000000..753ad1e
--- /dev/null
+++ b/eBones/krb/get_tf_fullname.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $
+ * $Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+#include <stdio.h>
+
+/*
+ * This file contains a routine to extract the fullname of a user
+ * from the ticket file.
+ */
+
+/*
+ * krb_get_tf_fullname() takes four arguments: the name of the
+ * ticket file, and variables for name, instance, and realm to be
+ * returned in. Since the realm of a ticket file is not really fully
+ * supported, the realm used will be that of the the first ticket in
+ * the file as this is the one that was obtained with a password by
+ * krb_get_in_tkt().
+ */
+
+krb_get_tf_fullname(ticket_file, name, instance, realm)
+ char *ticket_file;
+ char *name;
+ char *instance;
+ char *realm;
+{
+ int tf_status;
+ CREDENTIALS c;
+
+ if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
+ ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
+ return (tf_status);
+
+ if (name)
+ strcpy(name, c.pname);
+ if (instance)
+ strcpy(instance, c.pinst);
+ if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
+ if (realm)
+ strcpy(realm, c.realm);
+ }
+ else {
+ if (tf_status == EOF)
+ return(KFAILURE);
+ else
+ return(tf_status);
+ }
+ (void) tf_close();
+
+ return(tf_status);
+}
diff --git a/eBones/krb/get_tf_realm.c b/eBones/krb/get_tf_realm.c
new file mode 100644
index 0000000..f405dcb
--- /dev/null
+++ b/eBones/krb/get_tf_realm.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $
+ * $Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * This file contains a routine to extract the realm of a kerberos
+ * ticket file.
+ */
+
+/*
+ * krb_get_tf_realm() takes two arguments: the name of a ticket
+ * and a variable to store the name of the realm in.
+ *
+ */
+
+krb_get_tf_realm(ticket_file, realm)
+ char *ticket_file;
+ char *realm;
+{
+ return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
+}
diff --git a/eBones/krb/getrealm.c b/eBones/krb/getrealm.c
new file mode 100644
index 0000000..96e9588
--- /dev/null
+++ b/eBones/krb/getrealm.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * routine to convert hostname into realm name.
+ *
+ * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $
+ * $Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $";
+#endif lint
+
+#include <strings.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <krb.h>
+#include <sys/param.h>
+
+/* for Ultrix and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+/*
+ * krb_realmofhost.
+ * Given a fully-qualified domain-style primary host name,
+ * return the name of the Kerberos realm for the host.
+ * If the hostname contains no discernable domain, or an error occurs,
+ * return the local realm name, as supplied by get_krbrlm().
+ * If the hostname contains a domain, but no translation is found,
+ * the hostname's domain is converted to upper-case and returned.
+ *
+ * The format of each line of the translation file is:
+ * domain_name kerberos_realm
+ * -or-
+ * host_name kerberos_realm
+ *
+ * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
+ * host names should be in the usual form (e.g. FOO.BAR.BAZ)
+ */
+
+static char ret_realm[REALM_SZ+1];
+
+char *
+krb_realmofhost(host)
+char *host;
+{
+ char *domain;
+ FILE *trans_file;
+ char trans_host[MAXHOSTNAMELEN+1];
+ char trans_realm[REALM_SZ+1];
+ int retval;
+
+ domain = index(host, '.');
+
+ /* prepare default */
+ if (domain) {
+ char *cp;
+
+ strncpy(ret_realm, &domain[1], REALM_SZ);
+ ret_realm[REALM_SZ] = '\0';
+ /* Upper-case realm */
+ for (cp = ret_realm; *cp; cp++)
+ if (islower(*cp))
+ *cp = toupper(*cp);
+ } else {
+ krb_get_lrealm(ret_realm, 1);
+ }
+
+ if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
+ /* krb_errno = KRB_NO_TRANS */
+ return(ret_realm);
+ }
+ while (1) {
+ if ((retval = fscanf(trans_file, "%s %s",
+ trans_host, trans_realm)) != 2) {
+ if (retval == EOF) {
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ continue; /* ignore broken lines */
+ }
+ trans_host[MAXHOSTNAMELEN] = '\0';
+ trans_realm[REALM_SZ] = '\0';
+ if (!strcasecmp(trans_host, host)) {
+ /* exact match of hostname, so return the realm */
+ (void) strcpy(ret_realm, trans_realm);
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ if ((trans_host[0] == '.') && domain) {
+ /* this is a domain match */
+ if (!strcasecmp(trans_host, domain)) {
+ /* domain match, save for later */
+ (void) strcpy(ret_realm, trans_realm);
+ continue;
+ }
+ }
+ }
+}
diff --git a/eBones/krb/getst.c b/eBones/krb/getst.c
new file mode 100644
index 0000000..edd55ec
--- /dev/null
+++ b/eBones/krb/getst.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $
+ * $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $";
+#endif /* lint */
+
+/*
+ * getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. getst() returns the number of characters read, including
+ * the null terminator.
+ */
+
+getst(fd, s, n)
+ int fd;
+ register char *s;
+{
+ register count = n;
+ while (read(fd, s, 1) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/krb/in_tkt.c b/eBones/krb/in_tkt.c
new file mode 100644
index 0000000..53510da
--- /dev/null
+++ b/eBones/krb/in_tkt.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $
+ * $Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+extern int krb_debug;
+
+/*
+ * in_tkt() is used to initialize the ticket store. It creates the
+ * file to contain the tickets and writes the given user's name "pname"
+ * and instance "pinst" in the file. in_tkt() returns KSUCCESS on
+ * success, or KFAILURE if something goes wrong.
+ */
+
+in_tkt(pname,pinst)
+ char *pname;
+ char *pinst;
+{
+ int tktfile;
+ uid_t me, metoo;
+ struct stat buf;
+ int count;
+ char *file = TKT_FILE;
+ int fd;
+ register int i;
+ char charbuf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ me = getuid ();
+ metoo = geteuid();
+ if (lstat(file,&buf) == 0) {
+ if (buf.st_uid != me && me == 0) {
+ unlink(file);
+ } else {
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",file);
+ return(KFAILURE);
+ }
+ /* file already exists, and permissions appear ok, so nuke it */
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out; /* can't zero it, but we can still try truncating it */
+
+ bzero(charbuf, sizeof(charbuf));
+
+ for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+ if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+ }
+ }
+ out:
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary).
+ This isn't a security problem, since the ticket file, if it already
+ exists, has the right uid (== ruid) and mode. */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid2");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+ if (lstat(file,&buf) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ count = strlen(pname)+1;
+ if (write(tktfile,pname,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ count = strlen(pinst)+1;
+ if (write(tktfile,pinst,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ (void) close(tktfile);
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ return(krb_shm_create(shmidname));
+#else /* !TKT_SHMEM */
+ return(KSUCCESS);
+#endif /* TKT_SHMEM */
+}
diff --git a/eBones/krb/k_gethostname.c b/eBones/krb/k_gethostname.c
new file mode 100644
index 0000000..e5c11ca
--- /dev/null
+++ b/eBones/krb/k_gethostname.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $
+ * $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $";
+#endif /* lint */
+
+#ifndef PC
+#ifndef BSD42
+/* teach me how to k_gethostname for your system here */
+#endif
+#endif
+
+#ifdef PC
+#include <stdio.h>
+typedef long in_name;
+#include "custom.h" /* where is this file? */
+extern get_custom();
+#define LEN 64 /* just a guess */
+#endif /* PC */
+
+/*
+ * Return the local host's name in "name", up to "namelen" characters.
+ * "name" will be null-terminated if "namelen" is big enough.
+ * The return code is 0 on success, -1 on failure. (The calling
+ * interface is identical to gethostname(2).)
+ *
+ * Currently defined for BSD 4.2 and PC. The BSD version just calls
+ * gethostname(); the PC code was taken from "kinit.c", and may or may
+ * not work.
+ */
+
+k_gethostname(name, namelen)
+ char *name;
+{
+#ifdef BSD42
+ return gethostname(name, namelen);
+#endif
+
+#ifdef PC
+ char buf[LEN];
+ char b1, b2, b3, b4;
+ register char *ptr;
+
+ get_custom(); /* should check for errors,
+ * return -1 on failure */
+ ptr = (char *) &(custom.c_me);
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr;
+ (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4);
+ if (strlen(buf) > namelen)
+ fprintf(stderr, "gethostname: namelen too small; truncating");
+ strnpcy(name, buf, namelen);
+ return 0;
+#endif
+}
diff --git a/eBones/krb/klog.c b/eBones/krb/klog.c
new file mode 100644
index 0000000..b530e8b
--- /dev/null
+++ b/eBones/krb/klog.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $
+ * $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static int is_open;
+static char logtxt[1000];
+
+/*
+ * This file contains two logging routines: kset_logfile()
+ * to determine the file to which log entries should be written;
+ * and klog() to write log entries to the file.
+ */
+
+/*
+ * klog() is used to add entries to the logfile (see kset_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format" string.
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * If the given log type "type" is unknown, or if the log file
+ * cannot be opened, no entry is made to the log file.
+ *
+ * The return value is always a pointer to the formatted log
+ * text string "logtxt".
+ */
+
+char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ int type;
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ char *month_sname();
+ struct tm *tm;
+ static int logtype_array[NLOGTYPE] = {0,0};
+ static int array_initialized;
+
+ if (!(array_initialized++)) {
+ logtype_array[L_NET_ERR] = 1;
+ logtype_array[L_KRB_PERR] = 1;
+ logtype_array[L_KRB_PWARN] = 1;
+ logtype_array[L_APPL_REQ] = 1;
+ logtype_array[L_INI_REQ] = 1;
+ logtype_array[L_DEATH_REQ] = 1;
+ logtype_array[L_NTGT_INTK] = 1;
+ logtype_array[L_ERR_SEXP] = 1;
+ logtype_array[L_ERR_MKV] = 1;
+ logtype_array[L_ERR_NKY] = 1;
+ logtype_array[L_ERR_NUN] = 1;
+ logtype_array[L_ERR_UNK] = 1;
+ }
+
+ (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+
+ if (!logtype_array[type])
+ return(logtxt);
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return(logtxt);
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,"%s\n",logtxt);
+ (void) fclose(logfile);
+ return(logtxt);
+}
+
+/*
+ * kset_logfile() changes the name of the file to which
+ * messages are logged. If kset_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+kset_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
diff --git a/eBones/krb/kname_parse.c b/eBones/krb/kname_parse.c
new file mode 100644
index 0000000..dd5fe0b
--- /dev/null
+++ b/eBones/krb/kname_parse.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $
+ * $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/* max size of full name */
+#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
+
+#define NAME 0 /* which field are we in? */
+#define INST 1
+#define REALM 2
+
+extern char *krb_err_txt[];
+
+/*
+ * This file contains four routines for handling Kerberos names.
+ *
+ * kname_parse() breaks a Kerberos name into its name, instance,
+ * and realm components.
+ *
+ * k_isname(), k_isinst(), and k_isrealm() check a given string to see if
+ * it's a syntactically legitimate respective part of a Kerberos name,
+ * returning 1 if it is, 0 if it isn't.
+ *
+ * Definition of "syntactically legitimate" names is according to
+ * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
+ * names", version dated 21 Dec 1987.
+ * /
+
+/*
+ * kname_parse() takes a Kerberos name "fullname" of the form:
+ *
+ * username[.instance][@realm]
+ *
+ * and returns the three components ("name", "instance", and "realm"
+ * in the example above) in the given arguments "np", "ip", and "rp".
+ *
+ * If successful, it returns KSUCCESS. If there was an error,
+ * KNAME_FMT is returned.
+ */
+
+kname_parse(np, ip, rp, fullname)
+ char *np, *ip, *rp, *fullname;
+{
+ static char buf[FULL_SZ];
+ char *rnext, *wnext; /* next char to read, write */
+ register char c;
+ int backslash;
+ int field;
+
+ backslash = 0;
+ rnext = buf;
+ wnext = np;
+ field = NAME;
+
+ if (strlen(fullname) > FULL_SZ)
+ return KNAME_FMT;
+ (void) strcpy(buf, fullname);
+
+ while (c = *rnext++) {
+ if (backslash) {
+ *wnext++ = c;
+ backslash = 0;
+ continue;
+ }
+ switch (c) {
+ case '\\':
+ backslash++;
+ break;
+ case '.':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *wnext = '\0';
+ field = INST;
+ wnext = ip;
+ break;
+ case INST:
+ return KNAME_FMT;
+ /* break; */
+ case REALM:
+ *wnext++ = c;
+ break;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ case '@':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *ip = '\0';
+ /* fall through */
+ case INST:
+ *wnext = '\0';
+ field = REALM;
+ wnext = rp;
+ break;
+ case REALM:
+ return KNAME_FMT;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ default:
+ *wnext++ = c;
+ }
+ }
+ *wnext = '\0';
+ if ((strlen(np) > ANAME_SZ - 1) ||
+ (strlen(ip) > INST_SZ - 1) ||
+ (strlen(rp) > REALM_SZ - 1))
+ return KNAME_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * k_isname() returns 1 if the given name is a syntactically legitimate
+ * Kerberos name; returns 0 if it's not.
+ */
+
+k_isname(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > ANAME_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * k_isinst() returns 1 if the given name is a syntactically legitimate
+ * Kerberos instance; returns 0 if it's not.
+ */
+
+k_isinst(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (strlen(s) > INST_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+/*
+ * k_isrealm() returns 1 if the given name is a syntactically legitimate
+ * Kerberos realm; returns 0 if it's not.
+ */
+
+k_isrealm(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > REALM_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
diff --git a/eBones/krb/kntoln.c b/eBones/krb/kntoln.c
new file mode 100644
index 0000000..62ec1b5
--- /dev/null
+++ b/eBones/krb/kntoln.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $
+ * $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_kntoln converts an auth name into a local name by looking up
+ * the auth name in the /etc/aname file. The format of the aname
+ * file is:
+ *
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | anl | inl | rll | lnl | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | 1by | 1by | 1by | 1by | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ *
+ * If the /etc/aname file can not be opened it will set the
+ * local name to the auth name. Thus, in this case it performs as
+ * the identity function.
+ *
+ * The name instance and realm are passed to krb_kntoln through
+ * the AUTH_DAT structure (ad).
+ *
+ * Now here's what it *really* does:
+ *
+ * Given a Kerberos name in an AUTH_DAT structure, check that the
+ * instance is null, and that the realm is the same as the local
+ * realm, and return the principal's name in "lname". Return
+ * KSUCCESS if all goes well, otherwise KFAILURE.
+ */
+
+krb_kntoln(ad,lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ static char lrealm[REALM_SZ] = "";
+
+ if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
+ return(KFAILURE);
+
+ if (strcmp(ad->pinst,""))
+ return(KFAILURE);
+ if (strcmp(ad->prealm,lrealm))
+ return(KFAILURE);
+ (void) strcpy(lname,ad->pname);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/kparse.c b/eBones/krb/kparse.c
new file mode 100644
index 0000000..d79f1cf
--- /dev/null
+++ b/eBones/krb/kparse.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Purpose:
+ * This module was developed to parse the "~/.klogin" files for
+ * Kerberos-authenticated rlogin/rcp/rsh services. However, it is
+ * general purpose and can be used to parse any such parameter file.
+ *
+ * The parameter file should consist of one or more entries, with each
+ * entry on a separate line and consisting of zero or more
+ * "keyword=value" combinations. The keyword is case insensitive, but
+ * the value is not. Any string may be enclosed in quotes, and
+ * c-style "\" literals are supported. A comma may be used to
+ * separate the k/v combinations, and multiple commas are ignored.
+ * Whitespace (blank or tab) may be used freely and is ignored.
+ *
+ * Full error processing is available. When PS_BAD_KEYWORD or
+ * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
+ * contains a meaningful error message.
+ *
+ * Keywords and their default values are programmed by an external
+ * table.
+ *
+ * Routines:
+ * fGetParameterSet() parse one line of the parameter file
+ * fGetKeywordValue() parse one "keyword=value" combo
+ * fGetToken() parse one token
+ *
+ *
+ * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
+ * $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <ctype.h>
+#include <kparse.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define void int
+
+#define MAXKEY 80
+#define MAXVALUE 80
+
+char *malloc();
+char *strcpy();
+
+int LineNbr=1; /* current line nbr in parameter file */
+char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX,
+ * or PS_BAD_KEYWORD is returned by
+ * fGetKeywordValue or fGetParameterSet */
+
+int fGetParameterSet( fp,parm,parmcount )
+ FILE *fp;
+ parmtable parm[];
+ int parmcount;
+{
+ int rc,i;
+ char keyword[MAXKEY];
+ char value[MAXVALUE];
+
+ while (TRUE) {
+ rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
+
+ switch (rc) {
+
+ case KV_EOF:
+ return(PS_EOF);
+
+ case KV_EOL:
+ return(PS_OKAY);
+
+ case KV_SYNTAX:
+ return(PS_SYNTAX);
+
+ case KV_OKAY:
+ /*
+ * got a reasonable keyword/value pair. Search the
+ * parameter table to see if we recognize the keyword; if
+ * not, return an error. If we DO recognize it, make sure
+ * it has not already been given. If not already given,
+ * save the value.
+ */
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(strutol(keyword),parm[i].keyword)==0) {
+ if (parm[i].value) {
+ sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ parm[i].value = strsave( value );
+ break;
+ }
+ }
+ if (i >= parmcount) {
+ sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ break;
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ break;
+ }
+ }
+}
+
+/*
+ * Routine: ParmCompare
+ *
+ * Purpose:
+ * ParmCompare checks a specified value for a particular keyword.
+ * fails if keyword not found or keyword found but the value was
+ * different. Like strcmp, ParmCompare returns 0 for a match found, -1
+ * otherwise
+ */
+int ParmCompare( parm, parmcount, keyword, value )
+ parmtable parm[];
+ int parmcount;
+ char *keyword;
+ char *value;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(parm[i].keyword,keyword)==0) {
+ if (parm[i].value) {
+ return(strcmp(parm[i].value,value));
+ } else {
+ return(strcmp(parm[i].defvalue,value));
+ }
+ }
+ }
+ return(-1);
+}
+
+void FreeParameterSet(parm,parmcount)
+ parmtable parm[];
+ int parmcount;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (parm[i].value) {
+ free(parm[i].value);
+ parm[i].value = (char *)NULL;
+ }
+ }
+}
+
+int fGetKeywordValue( fp, keyword, klen, value, vlen )
+ FILE *fp;
+ char *keyword;
+ int klen;
+ char *value;
+ int vlen;
+{
+ int rc;
+ int gotit;
+
+ *keyword = *value = '\0'; /* preset strings to NULL */
+
+ /*
+ * Looking for a keyword.
+ * return an exception for EOF or BAD_QSTRING
+ * ignore leading WHITEspace
+ * ignore any number of leading commas
+ * newline means we have all the parms for this
+ * statement; give an indication that there is
+ * nothing more on this line.
+ * stop looking if we find QSTRING, STRING, or NUMBER
+ * return syntax error for any other PUNKtuation
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,keyword,klen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ return(KV_EOF);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",keyword)==0) {
+ return(KV_EOL);
+ } else if (strcmp(",",keyword)!=0) {
+ sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ break;
+
+ default:
+ sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while (!gotit);
+
+ /*
+ * now we expect an equal sign.
+ * skip any whitespace
+ * stop looking if we find an equal sign
+ * anything else causes a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,
+ "expecting \'=\', found unterminated string \"%s",
+ value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("=",value)==0) {
+ gotit = TRUE;
+ } else {
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting \"=\", found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",keyword);
+ }
+ return(KV_SYNTAX);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
+ return(KV_SYNTAX);
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting \'=\', found EOF");
+ return(KV_SYNTAX);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+
+ /*
+ * got the keyword and equal sign, now get a value.
+ * ignore any whitespace
+ * any punctuation is a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting rvalue, found EOF");
+ return(KV_SYNTAX);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting rvalue, found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",value);
+ }
+ return(KV_SYNTAX);
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ return(KV_OKAY);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+ /*NOTREACHED*/
+}
+
+/*
+ * Routine Name: fGetToken
+ *
+ * Function: read the next token from the specified file.
+ * A token is defined as a group of characters
+ * terminated by a white space char (SPACE, CR,
+ * LF, FF, TAB). The token returned is stripped of
+ * both leading and trailing white space, and is
+ * terminated by a NULL terminator. An alternate
+ * definition of a token is a string enclosed in
+ * single or double quotes.
+ *
+ * Explicit Parameters:
+ * fp pointer to the input FILE
+ * dest pointer to destination buffer
+ * maxlen length of the destination buffer. The buffer
+ * length INCLUDES the NULL terminator.
+ *
+ * Implicit Parameters: stderr where the "token too long" message goes
+ *
+ * External Procedures: fgetc
+ *
+ * Side Effects: None
+ *
+ * Return Value: A token classification value, as
+ * defined in kparse.h. Note that the
+ * classification for end of file is
+ * always zero.
+ */
+int fGetToken(fp, dest, maxlen)
+ FILE *fp;
+ char *dest;
+ int maxlen;
+{
+ int ch='\0';
+ int len=0;
+ char *p = dest;
+ int digits;
+
+ ch=fGetChar(fp);
+
+ /*
+ * check for a quoted string. If found, take all characters
+ * that fit until a closing quote is found. Note that this
+ * algorithm will not behave well for a string which is too long.
+ */
+ if (ISQUOTE(ch)) {
+ int done = FALSE;
+ do {
+ ch = fGetChar(fp);
+ done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
+ ||ISQUOTE(ch));
+ if (ch=='\\')
+ ch = fGetLiteral(fp);
+ if (!done)
+ *p++ = ch;
+ else if ((ch!=EOF) && !ISQUOTE(ch))
+ fUngetChar(ch,fp);
+ } while (!done);
+ *p = '\0';
+ if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
+ return(GTOK_QSTRING);
+ }
+
+ /*
+ * Not a quoted string. If its a token character (rules are
+ * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
+ * token chars following it until we run out of space.
+ */
+ digits=TRUE;
+ if (ISTOKENCHAR(ch)) {
+ while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
+ if (!isdigit(ch)) digits=FALSE;
+ *p++ = ch;
+ len++;
+ ch = fGetChar(fp);
+ };
+ *p = '\0';
+
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ if (digits) {
+ return(GTOK_NUMBER);
+ } else {
+ return(GTOK_STRING);
+ }
+ }
+
+ /*
+ * Neither a quoted string nor a token character. Return a string
+ * with just that one character in it.
+ */
+ if (ch==EOF) {
+ return(GTOK_EOF);
+ }
+ if (!ISWHITESPACE(ch)) {
+ *p++ = ch;
+ *p='\0';
+ } else {
+ *p++ = ' '; /* white space is always the
+ * blank character */
+ *p='\0';
+ /*
+ * The character is a white space. Flush all additional white
+ * space.
+ */
+ while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
+ ;
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ return(GTOK_WHITE);
+ }
+ return(GTOK_PUNK);
+}
+
+/*
+ * fGetLiteral is called after we find a '\' in the input stream. A
+ * string of numbers following the backslash are converted to the
+ * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
+ * are all supported. If the char after the \ is not a number, we
+ * special case certain values (\n, \f, \r, \b) or return a literal
+ * otherwise (useful for \", for example).
+ */
+fGetLiteral(fp)
+ FILE *fp;
+{
+ int ch;
+ int n=0;
+ int base;
+
+ ch = fGetChar(fp);
+
+ if (!isdigit(ch)) {
+ switch (ch) {
+ case 'n': return('\n');
+ case 'f': return('\f');
+ case 'r': return('\r');
+ case 'b': return('\b');
+ default: return(ch);
+ }
+ }
+
+ /*
+ * got a number. might be decimal (no prefix), octal (prefix 0),
+ * or hexadecimal (prefix 0x). Set the base appropriately.
+ */
+ if (ch!='0') {
+ base=10; /* its a decimal number */
+ } else {
+ /*
+ * found a zero, its either hex or octal
+ */
+ ch = fGetChar(fp);
+ if ((ch!='x') && (ch!='X')) {
+ base=010;
+ } else {
+ ch = fGetChar(fp);
+ base=0x10;
+ }
+ }
+
+ switch (base) {
+
+ case 010: /* octal */
+ while (ISOCTAL(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+
+ case 10: /* decimal */
+ while (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+ case 0x10: /* hexadecimal */
+ while (isxdigit(ch)) {
+ if (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ } else {
+ n = (n*base) + toupper(ch) - 'A' + 0xA ;
+ }
+ ch = fGetChar(fp);
+ }
+ break;
+ default:
+ fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
+ exit(1);
+ break;
+ }
+ fUngetChar(ch,fp);
+ return(n);
+}
+
+/*
+ * exactly the same as ungetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fUngetChar(ch,fp)
+ int ch;
+ FILE *fp;
+{
+ if (ch=='\n') LineNbr--;
+ return(ungetc(ch,fp));
+}
+
+
+/*
+ * exactly the same as fgetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fGetChar(fp)
+ FILE *fp;
+{
+ int ch = fgetc(fp);
+ if (ch=='\n') LineNbr++;
+ 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
+ *
+ */
+char * strsave(p)
+ char *p;
+{
+ return(strcpy(malloc(strlen(p)+1),p));
+}
+
+
+/*
+ * strutol changes all characters in a string to lower case, in place.
+ * the pointer to the beginning of the string is returned.
+ */
+
+char * strutol( start )
+ char *start;
+{
+ char *q;
+ for (q=start; *q; q++)
+ if (isupper(*q))
+ *q=tolower(*q);
+ return(start);
+}
+
+#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
+
+#define MAXTOKEN 100
+
+char *pgm = "gettoken";
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char *p;
+ int type;
+ FILE *fp;
+
+ if (--argc) {
+ fp = fopen(*++argv,"ra");
+ if (fp == (FILE *)NULL) {
+ fprintf(stderr,"can\'t open \"%s\"\n",*argv);
+ }
+ } else
+ fp = stdin;
+
+ p = malloc(MAXTOKEN);
+ while (type = fGetToken(fp,p,MAXTOKEN)) {
+ switch(type) {
+ case GTOK_BAD_QSTRING:
+ printf("BAD QSTRING!\t");
+ break;
+ case GTOK_EOF:
+ printf("EOF!\t");
+ break;
+ case GTOK_QSTRING:
+ printf("QSTRING\t");
+ break;
+ case GTOK_STRING:
+ printf("STRING\t");
+ break;
+ case GTOK_NUMBER:
+ printf("NUMBER\t");
+ break;
+ case GTOK_PUNK:
+ printf("PUNK\t");
+ break;
+ case GTOK_WHITE:
+ printf("WHITE\t");
+ break;
+ default:
+ printf("HUH?\t");
+ break;
+ }
+ if (*p=='\n')
+ printf("\\n\n");
+ else
+ printf("%s\n",p);
+ }
+ exit(0);
+}
+#endif
+
+#ifdef KVTEST
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,ch;
+ FILE *fp;
+ char key[MAXKEY],valu[MAXVALUE];
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
+
+ switch (rc) {
+
+ case KV_EOL:
+ printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
+ break;
+
+ case KV_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case KV_OKAY:
+ printf("%s, line %d: okay, %s=\"%s\"\n",
+ filename,LineNbr,key,valu);
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
+ break;
+ }
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
+
+#ifdef PSTEST
+
+parmtable kparm[] = {
+ /* keyword, default, found value */
+ { "user", "", (char *)NULL },
+ { "realm", "Athena", (char *)NULL },
+ { "instance", "", (char *)NULL }
+};
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,i,ch;
+ FILE *fp;
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
+
+ switch (rc) {
+
+ case PS_BAD_KEYWORD:
+ printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_OKAY:
+ printf("%s, line %d: valid parameter set found:\n",
+ filename,LineNbr-1);
+ for (i=0; i<PARMCOUNT(kparm); i++) {
+ printf("\t%s = \"%s\"\n",kparm[i].keyword,
+ (kparm[i].value ? kparm[i].value
+ : kparm[i].defvalue));
+ }
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetParameterSet\n",rc);
+ break;
+ }
+ FreeParameterSet(kparm,PARMCOUNT(kparm));
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
diff --git a/eBones/krb/krb_err.et b/eBones/krb/krb_err.et
new file mode 100644
index 0000000..2c6830b
--- /dev/null
+++ b/eBones/krb/krb_err.et
@@ -0,0 +1,257 @@
+# Copyright 1987,1988 Massachusetts Institute of Technology
+# For copying and distribution information, see the file
+# "Copyright.MIT".
+#
+# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $
+# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $
+#
+ error_table krb
+
+ ec KRBET_KSUCCESS,
+ "Kerberos successful"
+
+ ec KRBET_KDC_NAME_EXP,
+ "Kerberos principal expired"
+
+ ec KRBET_KDC_SERVICE_EXP,
+ "Kerberos service expired"
+
+ ec KRBET_KDC_AUTH_EXP,
+ "Kerberos auth expired"
+
+ ec KRBET_KDC_PKT_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_P_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_S_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_BYTE_ORDER,
+ "Kerberos error: byte order unknown"
+
+ ec KRBET_KDC_PR_UNKNOWN,
+ "Kerberos principal unknown"
+
+ ec KRBET_KDC_PR_N_UNIQUE,
+ "Kerberos principal not unique"
+
+ ec KRBET_KDC_NULL_KEY,
+ "Kerberos principal has null key"
+
+ ec KRBET_KRB_RES11,
+ "Reserved 11"
+
+ ec KRBET_KRB_RES12,
+ "Reserved 12"
+
+ ec KRBET_KRB_RES13,
+ "Reserved 13"
+
+ ec KRBET_KRB_RES14,
+ "Reserved 14"
+
+ ec KRBET_KRB_RES15,
+ "Reserved 15"
+
+ ec KRBET_KRB_RES16,
+ "Reserved 16"
+
+ ec KRBET_KRB_RES17,
+ "Reserved 17"
+
+ ec KRBET_KRB_RES18,
+ "Reserved 18"
+
+ ec KRBET_KRB_RES19,
+ "Reserved 19"
+
+ ec KRBET_KDC_GEN_ERR,
+ "Generic error from Kerberos KDC"
+
+ ec KRBET_GC_TKFIL,
+ "Can't read Kerberos ticket file"
+
+ ec KRBET_GC_NOTKT,
+ "Can't find Kerberos ticket or TGT"
+
+ ec KRBET_KRB_RES23,
+ "Reserved 23"
+
+ ec KRBET_KRB_RES24,
+ "Reserved 24"
+
+ ec KRBET_KRB_RES25,
+ "Reserved 25"
+
+ ec KRBET_MK_AP_TGTEXP,
+ "Kerberos TGT Expired"
+
+ ec KRBET_KRB_RES27,
+ "Reserved 27"
+
+ ec KRBET_KRB_RES28,
+ "Reserved 28"
+
+ ec KRBET_KRB_RES29,
+ "Reserved 29"
+
+ ec KRBET_KRB_RES30,
+ "Reserved 30"
+
+ ec KRBET_RD_AP_UNDEC,
+ "Kerberos error: Can't decode authenticator"
+
+ ec KRBET_RD_AP_EXP,
+ "Kerberos ticket expired"
+
+ ec KRBET_RD_AP_NYV,
+ "Kerberos ticket not yet valid"
+
+ ec KRBET_RD_AP_REPEAT,
+ "Kerberos error: Repeated request"
+
+ ec KRBET_RD_AP_NOT_US,
+ "The kerberos ticket isn't for us"
+
+ ec KRBET_RD_AP_INCON,
+ "Kerberos request inconsistent"
+
+ ec KRBET_RD_AP_TIME,
+ "Kerberos error: delta_t too big"
+
+ ec KRBET_RD_AP_BADD,
+ "Kerberos error: incorrect net address"
+
+ ec KRBET_RD_AP_VERSION,
+ "Kerberos protocol version mismatch"
+
+ ec KRBET_RD_AP_MSG_TYPE,
+ "Kerberos error: invalid msg type"
+
+ ec KRBET_RD_AP_MODIFIED,
+ "Kerberos error: message stream modified"
+
+ ec KRBET_RD_AP_ORDER,
+ "Kerberos error: message out of order"
+
+ ec KRBET_RD_AP_UNAUTHOR,
+ "Kerberos error: unauthorized request"
+
+ ec KRBET_KRB_RES44,
+ "Reserved 44"
+
+ ec KRBET_KRB_RES45,
+ "Reserved 45"
+
+ ec KRBET_KRB_RES46,
+ "Reserved 46"
+
+ ec KRBET_KRB_RES47,
+ "Reserved 47"
+
+ ec KRBET_KRB_RES48,
+ "Reserved 48"
+
+ ec KRBET_KRB_RES49,
+ "Reserved 49"
+
+ ec KRBET_KRB_RES50,
+ "Reserved 50"
+
+ ec KRBET_GT_PW_NULL,
+ "Kerberos error: current PW is null"
+
+ ec KRBET_GT_PW_BADPW,
+ "Kerberos error: Incorrect current password"
+
+ ec KRBET_GT_PW_PROT,
+ "Kerberos protocol error"
+
+ ec KRBET_GT_PW_KDCERR,
+ "Error returned by Kerberos KDC"
+
+ ec KRBET_GT_PW_NULLTKT,
+ "Null Kerberos ticket returned by KDC"
+
+ ec KRBET_SKDC_RETRY,
+ "Kerberos error: Retry count exceeded"
+
+ ec KRBET_SKDC_CANT,
+ "Kerberos error: Can't send request"
+
+ ec KRBET_KRB_RES58,
+ "Reserved 58"
+
+ ec KRBET_KRB_RES59,
+ "Reserved 59"
+
+ ec KRBET_KRB_RES60,
+ "Reserved 60"
+
+ ec KRBET_INTK_W_NOTALL,
+ "Kerberos error: not all tickets returned"
+
+ ec KRBET_INTK_BADPW,
+ "Kerberos error: incorrect password"
+
+ ec KRBET_INTK_PROT,
+ "Kerberos error: Protocol Error"
+
+ ec KRBET_KRB_RES64,
+ "Reserved 64"
+
+ ec KRBET_KRB_RES65,
+ "Reserved 65"
+
+ ec KRBET_KRB_RES66,
+ "Reserved 66"
+
+ ec KRBET_KRB_RES67,
+ "Reserved 67"
+
+ ec KRBET_KRB_RES68,
+ "Reserved 68"
+
+ ec KRBET_KRB_RES69,
+ "Reserved 69"
+
+ ec KRBET_INTK_ERR,
+ "Other error"
+
+ ec KRBET_AD_NOTGT,
+ "Don't have Kerberos ticket-granting ticket"
+
+ ec KRBET_KRB_RES72,
+ "Reserved 72"
+
+ ec KRBET_KRB_RES73,
+ "Reserved 73"
+
+ ec KRBET_KRB_RES74,
+ "Reserved 74"
+
+ ec KRBET_KRB_RES75,
+ "Reserved 75"
+
+ ec KRBET_NO_TKT_FIL,
+ "No ticket file found"
+
+ ec KRBET_TKT_FIL_ACC,
+ "Couldn't access ticket file"
+
+ ec KRBET_TKT_FIL_LCK,
+ "Couldn't lock ticket file"
+
+ ec KRBET_TKT_FIL_FMT,
+ "Bad ticket file format"
+
+ ec KRBET_TKT_FIL_INI,
+ "tf_init not called first"
+
+ ec KRBET_KNAME_FMT,
+ "Bad Kerberos name format"
+
+ end
+
diff --git a/eBones/krb/krb_err_txt.c b/eBones/krb/krb_err_txt.c
new file mode 100644
index 0000000..785563f
--- /dev/null
+++ b/eBones/krb/krb_err_txt.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $
+ * $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $";
+#endif lint
+
+/*
+ * This file contains an array of error text strings.
+ * The associated error codes (which are defined in "krb.h")
+ * follow the string in the comments at the end of each line.
+ */
+
+char *krb_err_txt[256] = {
+ "OK", /* 000 */
+ "Principal expired (kerberos)", /* 001 */
+ "Service expired (kerberos)", /* 002 */
+ "Authentication expired (kerberos)", /* 003 */
+ "Unknown protocol version number (kerberos)", /* 004 */
+ "Principal: Incorrect master key version (kerberos)", /* 005 */
+ "Service: Incorrect master key version (kerberos)", /* 006 */
+ "Bad byte order (kerberos)", /* 007 */
+ "Principal unknown (kerberos)", /* 008 */
+ "Principal not unique (kerberos)", /* 009 */
+ "Principal has null key (kerberos)", /* 010 */
+ "Reserved error message 11 (kerberos)", /* 011 */
+ "Reserved error message 12 (kerberos)", /* 012 */
+ "Reserved error message 13 (kerberos)", /* 013 */
+ "Reserved error message 14 (kerberos)", /* 014 */
+ "Reserved error message 15 (kerberos)", /* 015 */
+ "Reserved error message 16 (kerberos)", /* 016 */
+ "Reserved error message 17 (kerberos)", /* 017 */
+ "Reserved error message 18 (kerberos)", /* 018 */
+ "Reserved error message 19 (kerberos)", /* 019 */
+ "Permission Denied (kerberos)", /* 020 */
+ "Can't read ticket file (krb_get_cred)", /* 021 */
+ "Can't find ticket (krb_get_cred)", /* 022 */
+ "Reserved error message 23 (krb_get_cred)", /* 023 */
+ "Reserved error message 24 (krb_get_cred)", /* 024 */
+ "Reserved error message 25 (krb_get_cred)", /* 025 */
+ "Ticket granting ticket expired (krb_mk_req)", /* 026 */
+ "Reserved error message 27 (krb_mk_req)", /* 027 */
+ "Reserved error message 28 (krb_mk_req)", /* 028 */
+ "Reserved error message 29 (krb_mk_req)", /* 029 */
+ "Reserved error message 30 (krb_mk_req)", /* 030 */
+ "Can't decode authenticator (krb_rd_req)", /* 031 */
+ "Ticket expired (krb_rd_req)", /* 032 */
+ "Ticket issue date too far in the future (krb_rd_req)",/* 033 */
+ "Repeat request (krb_rd_req)", /* 034 */
+ "Ticket for wrong server (krb_rd_req)", /* 035 */
+ "Request inconsistent (krb_rd_req)", /* 036 */
+ "Time is out of bounds (krb_rd_req)", /* 037 */
+ "Incorrect network address (krb_rd_req)", /* 038 */
+ "Protocol version mismatch (krb_rd_req)", /* 039 */
+ "Illegal message type (krb_rd_req)", /* 040 */
+ "Message integrity error (krb_rd_req)", /* 041 */
+ "Message duplicate or out of order (krb_rd_req)", /* 042 */
+ "Unauthorized request (krb_rd_req)", /* 043 */
+ "Reserved error message 44 (krb_rd_req)", /* 044 */
+ "Reserved error message 45 (krb_rd_req)", /* 045 */
+ "Reserved error message 46 (krb_rd_req)", /* 046 */
+ "Reserved error message 47 (krb_rd_req)", /* 047 */
+ "Reserved error message 48 (krb_rd_req)", /* 048 */
+ "Reserved error message 49 (krb_rd_req)", /* 049 */
+ "Reserved error message 50 (krb_rd_req)", /* 050 */
+ "Current password is NULL (get_pw_tkt)", /* 051 */
+ "Current password incorrect (get_pw_tkt)", /* 052 */
+ "Protocol error (gt_pw_tkt)", /* 053 */
+ "Error returned by KDC (gt_pw_tkt)", /* 054 */
+ "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */
+ "Retry count exceeded (send_to_kdc)", /* 056 */
+ "Can't send request (send_to_kdc)", /* 057 */
+ "Reserved error message 58 (send_to_kdc)", /* 058 */
+ "Reserved error message 59 (send_to_kdc)", /* 059 */
+ "Reserved error message 60 (send_to_kdc)", /* 060 */
+ "Warning: Not ALL tickets returned", /* 061 */
+ "Password incorrect", /* 062 */
+ "Protocol error (get_intkt)", /* 063 */
+ "Reserved error message 64 (get_in_tkt)", /* 064 */
+ "Reserved error message 65 (get_in_tkt)", /* 065 */
+ "Reserved error message 66 (get_in_tkt)", /* 066 */
+ "Reserved error message 67 (get_in_tkt)", /* 067 */
+ "Reserved error message 68 (get_in_tkt)", /* 068 */
+ "Reserved error message 69 (get_in_tkt)", /* 069 */
+ "Generic error (get_intkt)", /* 070 */
+ "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */
+ "Reserved error message 72 (get_ad_tkt)", /* 072 */
+ "Reserved error message 73 (get_ad_tkt)", /* 073 */
+ "Reserved error message 74 (get_ad_tkt)", /* 074 */
+ "Reserved error message 75 (get_ad_tkt)", /* 075 */
+ "No ticket file (tf_util)", /* 076 */
+ "Can't access ticket file (tf_util)", /* 077 */
+ "Can't lock ticket file; try later (tf_util)", /* 078 */
+ "Bad ticket file format (tf_util)", /* 079 */
+ "Read ticket file before tf_init (tf_util)", /* 080 */
+ "Bad Kerberos name format (kname_parse)", /* 081 */
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "Generic kerberos error (kfailure)", /* 255 */
+};
diff --git a/eBones/krb/krb_get_in_tkt.c b/eBones/krb/krb_get_in_tkt.c
new file mode 100644
index 0000000..a37bb60
--- /dev/null
+++ b/eBones/krb/krb_get_in_tkt.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $
+ * $Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+int swap_bytes;
+
+/*
+ * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
+ * and the cipher text sent from the KDC, decrypt the cipher text
+ * using the key returned by key_proc.
+ */
+
+static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+
+#ifndef NOENCRYPTION
+ /* Attempt to decrypt it */
+#endif
+
+ /* generate a key */
+
+ {
+ register int rc;
+ rc = (*key_proc)(user,instance,realm,arg,key);
+ if (rc)
+ return(rc);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length,key_s,key,DES_DECRYPT);
+#endif /* !NOENCRYPTION */
+ /* Get rid of all traces of key */
+ bzero((char *)key,sizeof(key));
+ bzero((char *)key_s,sizeof(key_s));
+
+ return(0);
+}
+
+/*
+ * krb_get_in_tkt() gets a ticket for a given principal to use a given
+ * service and stores the returned ticket and session key for future
+ * use.
+ *
+ * The "user", "instance", and "realm" arguments give the identity of
+ * the client who will use the ticket. The "service" and "sinstance"
+ * arguments give the identity of the server that the client wishes
+ * to use. (The realm of the server is the same as the Kerberos server
+ * to whom the request is sent.) The "life" argument indicates the
+ * desired lifetime of the ticket; the "key_proc" argument is a pointer
+ * to the routine used for getting the client's private key to decrypt
+ * the reply from Kerberos. The "decrypt_proc" argument is a pointer
+ * to the routine used to decrypt the reply from Kerberos; and "arg"
+ * is an argument to be passed on to the "key_proc" routine.
+ *
+ * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
+ * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned
+ * by Kerberos, then the error code it contains is returned. Other
+ * error codes returned by this routine include INTK_PROT to indicate
+ * wrong protocol version, INTK_BADPW to indicate bad password (if
+ * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
+ * the wrong server or the ticket store couldn't be initialized.
+ *
+ * The format of the message sent to Kerberos is as follows:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_KDC_REQUEST | message type
+ * HOST_BYTE_ORDER local byte order in lsb
+ * string user client's name
+ * string instance client's instance
+ * string realm client's realm
+ * 4 bytes tlocal.tv_sec timestamp in seconds
+ * 1 byte life desired lifetime
+ * string service service's name
+ * string sinstance service's instance
+ */
+
+krb_get_in_tkt(user, instance, realm, service, sinstance, life,
+ key_proc, decrypt_proc, arg)
+ char *user;
+ char *instance;
+ char *realm;
+ char *service;
+ char *sinstance;
+ int life;
+ int (*key_proc)();
+ int (*decrypt_proc)();
+ char *arg;
+{
+ KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st; /* Packet to KDC */
+ KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ int kvno; /* Kvno for session key */
+ unsigned char *v = pkt->dat; /* Prot vers no */
+ unsigned char *t = (pkt->dat+1); /* Prot msg type */
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ char rlm[REALM_SZ];
+ int lifetime;
+ int msg_byte_order;
+ int kerror;
+ unsigned long exp_date;
+ char *ptr;
+
+ struct timeval t_local;
+
+ unsigned long rep_err_code;
+
+ unsigned long kdc_time; /* KDC time */
+
+ /* BUILD REQUEST PACKET */
+
+ /* Set up the fixed part of the packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Now for the variable info */
+ (void) strcpy((char *)(pkt->dat+2),user); /* aname */
+ pkt->length = 3 + strlen(user);
+ (void) strcpy((char *)(pkt->dat+pkt->length),
+ instance); /* instance */
+ pkt->length += 1 + strlen(instance);
+ (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
+ pkt->length += 1 + strlen(realm);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ /* timestamp */
+ bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+
+ *(pkt->dat+(pkt->length)++) = (char) life;
+ (void) strcpy((char *)(pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION)
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
+ if (swap_bytes) swap_u_long(rep_err_code);
+ return((int)rep_err_code);
+ default:
+ return(INTK_PROT);
+ }
+
+ /* EXTRACT INFORMATION FROM RETURN PACKET */
+
+ /* get the principal's expiration date */
+ bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
+ if (swap_bytes) swap_u_long(exp_date);
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
+ return(INTK_ERR); /* no appropriate error code
+ currently defined for INTK_ */
+ /* copy information from return packet into "cip" */
+ bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
+
+ /* Attempt to decrypt the reply. */
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+ (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
+
+ ptr = (char *) cip->dat;
+
+ /* extract session key */
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's name */
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's instance */
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's realm */
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ /* extract ticket lifetime, server key version, ticket length */
+ /* be sure to avoid sign extension on lifetime! */
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
+ ptr += 3;
+
+ if ((tkt->length < 0) ||
+ ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
+ return(INTK_BADPW);
+
+ /* extract ticket itself */
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ /* initialize ticket cache */
+ if (in_tkt(user,instance) != KSUCCESS)
+ return(INTK_ERR);
+
+ /* stash ticket, session key, etc. for future use */
+ if (kerror = save_credentials(s_name, s_instance, rlm, ses,
+ lifetime, kvno, tkt, t_local.tv_sec))
+ return(kerror);
+
+ return(INTK_OK);
+}
diff --git a/eBones/krb/krb_realmofhost.3 b/eBones/krb/krb_realmofhost.3
new file mode 100644
index 0000000..f284069
--- /dev/null
+++ b/eBones/krb/krb_realmofhost.3
@@ -0,0 +1,161 @@
+.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
+.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question. In order to prevent certain security attacks, this routine
+must either have
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+The configuration file is described by
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned. If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports
+.I n
+= 1. It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/eBones/krb/krb_sendauth.3 b/eBones/krb/krb_sendauth.3
new file mode 100644
index 0000000..f5e95b7
--- /dev/null
+++ b/eBones/krb/krb_sendauth.3
@@ -0,0 +1,348 @@
+.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
+.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated. They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters. It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <mit-copyright.h>.
diff --git a/eBones/krb/krb_set_tkt_string.3 b/eBones/krb/krb_set_tkt_string.3
new file mode 100644
index 0000000..c9f3dcf
--- /dev/null
+++ b/eBones/krb/krb_set_tkt_string.3
@@ -0,0 +1,43 @@
+.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $
+.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_set_tkt_string \- set Kerberos ticket cache file name
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+void krb_set_tkt_string(filename)
+char *filename;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_set_tkt_string
+sets the name of the file that holds the user's
+cache of Kerberos server tickets and associated session keys.
+.PP
+The string
+.I filename
+passed in is copied into local storage.
+Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
+copied in for use as the cache file name.
+.PP
+This routine should be called during initialization, before other
+Kerberos routines are called; otherwise the routines which fetch the
+ticket cache file name may be called and return an undesired ticket file
+name until this routine is called.
+.SH FILES
+.TP 20n
+/tmp/tkt[uid]
+default ticket file name, unless the environment variable KRBTKFILE is set.
+[uid] denotes the user's uid, in decimal.
+.SH SEE ALSO
+kerberos(3), setenv(3)
diff --git a/eBones/krb/krbglue.c b/eBones/krb/krbglue.c
new file mode 100644
index 0000000..8e864c1
--- /dev/null
+++ b/eBones/krb/krbglue.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $
+ * $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $";
+#endif lint
+
+#ifndef NCOMPAT
+/*
+ * glue together new libraries and old clients
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "des.h"
+#include "krb.h"
+
+/* These definitions should be in krb.h, no? */
+#if defined(__HIGHC__)
+#undef __STDC__
+#endif
+#ifdef __STDC__
+extern int krb_mk_req (KTEXT, char *, char *, char *, long);
+extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *);
+extern int krb_kntoln (AUTH_DAT *, char *);
+extern int krb_set_key (char *, int);
+extern int krb_get_cred (char *, char *, char *, CREDENTIALS *);
+extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *);
+extern long krb_rd_priv (u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *, MSG_DAT *);
+extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *);
+extern long krb_rd_safe (u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *,
+ MSG_DAT *);
+extern long krb_mk_err (u_char *, long, char *);
+extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *);
+extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_pw_tkt (char *, char *, char *, char *);
+extern int krb_get_lrealm (char *, char *);
+extern int krb_realmofhost (char *);
+extern char *krb_get_phost (char *);
+extern int krb_get_krbhst (char *, char *, int);
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet (char *);
+#endif /* DEBUG */
+#else
+extern int krb_mk_req ();
+extern int krb_rd_req ();
+extern int krb_kntoln ();
+extern int krb_set_key ();
+extern int krb_get_cred ();
+extern long krb_mk_priv ();
+extern long krb_rd_priv ();
+extern long krb_mk_safe ();
+extern long krb_rd_safe ();
+extern long krb_mk_err ();
+extern int krb_rd_err ();
+extern int krb_get_pw_in_tkt ();
+extern int krb_get_svc_in_tkt ();
+extern int krb_get_pw_tkt ();
+extern int krb_get_lrealm ();
+extern int krb_realmofhost ();
+extern char *krb_get_phost ();
+extern int krb_get_krbhst ();
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet ();
+#endif /* DEBUG */
+#endif /* STDC */
+int mk_ap_req(authent, service, instance, realm, checksum)
+ KTEXT authent;
+ char *service, *instance, *realm;
+ u_long checksum;
+{
+ return krb_mk_req(authent,service,instance,realm,checksum);
+}
+
+int rd_ap_req(authent, service, instance, from_addr, ad, fn)
+ KTEXT authent;
+ char *service, *instance;
+ u_long from_addr;
+ AUTH_DAT *ad;
+ char *fn;
+{
+ return krb_rd_req(authent,service,instance,from_addr,ad,fn);
+}
+
+int an_to_ln(ad, lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ return krb_kntoln (ad,lname);
+}
+
+int set_serv_key (key, cvt)
+ char *key;
+ int cvt;
+{
+ return krb_set_key(key,cvt);
+}
+
+int get_credentials (svc,inst,rlm,cred)
+ char *svc, *inst, *rlm;
+ CREDENTIALS *cred;
+{
+ return krb_get_cred (svc, inst, rlm, cred);
+}
+
+long mk_private_msg (in,out,in_length,schedule,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver);
+}
+
+long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data);
+}
+
+long mk_safe_msg (in,out,in_length,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_safe (in,out,in_length,key,sender,receiver);
+}
+
+long rd_safe_msg (in,length,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_safe (in,length,key,sender,receiver,msg_data);
+}
+
+long mk_appl_err_msg (out,code,string)
+ u_char *out;
+ long code;
+ char *string;
+{
+ return krb_mk_err (out,code,string);
+}
+
+long rd_appl_err_msg (in,length,code,msg_data)
+ u_char *in;
+ u_long length;
+ long *code;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_err (in,length,code,msg_data);
+}
+
+int get_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return krb_get_pw_in_tkt(user,instance,realm,service,sinstance,
+ life,password);
+}
+
+int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return krb_get_svc_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab);
+}
+
+int get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ return krb_get_pw_tkt(user,instance,realm,cpw);
+}
+
+int
+get_krbrlm (r, n)
+char *r;
+int n;
+{
+ return krb_get_lream(r,n);
+}
+
+int
+krb_getrealm (host)
+{
+ return krb_realmofhost(host);
+}
+
+char *
+get_phost (host)
+char *host
+{
+ return krb_get_phost(host);
+}
+
+int
+get_krbhst (h, r, n)
+char *h;
+char *r;
+int n;
+{
+ return krb_get_krbhst(h,r,n);
+}
+#ifdef DEBUG
+struct ktext *create_death_packet(a_name)
+ char *a_name;
+{
+ return krb_create_death_packet(a_name);
+}
+#endif /* DEBUG */
+
+#if 0
+extern int krb_ck_repl ();
+
+int check_replay ()
+{
+ return krb_ck_repl ();
+}
+#endif
+#endif /* NCOMPAT */
diff --git a/eBones/krb/kuserok.3 b/eBones/krb/kuserok.3
new file mode 100644
index 0000000..36968ba
--- /dev/null
+++ b/eBones/krb/kuserok.3
@@ -0,0 +1,63 @@
+.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $
+.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kuserok \- Kerberos version of ruserok
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+kuserok(kdata, localuser)
+AUTH_DAT *auth_data;
+char *localuser;
+.fi
+.ft R
+.SH DESCRIPTION
+.I kuserok
+determines whether a Kerberos principal described by the structure
+.I auth_data
+is authorized to login as user
+.I localuser
+according to the authorization file
+("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized,
+1 (one) if not authorized.
+.PP
+If there is no account for
+.I localuser
+on the local machine, authorization is not granted.
+If there is no authorization file, and the Kerberos principal described
+by
+.I auth_data
+translates to
+.I localuser
+(using
+.IR krb_kntoln (3)),
+authorization is granted.
+If the authorization file
+can't be accessed, or the file is not owned by
+.IR localuser,
+authorization is denied. Otherwise, the file is searched for
+a matching principal name, instance, and realm. If a match is found,
+authorization is granted, else authorization is denied.
+.PP
+The file entries are in the format:
+.nf
+.in +5n
+ name.instance@realm
+.in -5n
+.fi
+with one entry per line.
+.SH SEE ALSO
+kerberos(3), ruserok(3), krb_kntoln(3)
+.SH FILES
+.TP 20n
+~\fIlocaluser\fR/.klogin
+authorization list
diff --git a/eBones/krb/kuserok.c b/eBones/krb/kuserok.c
new file mode 100644
index 0000000..cb1f708
--- /dev/null
+++ b/eBones/krb/kuserok.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * kuserok: check if a kerberos principal has
+ * access to a local account
+ *
+ * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $
+ * $Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <strings.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "kdata", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default). Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK. If there is no authorization file, and the given Kerberos
+ * name "kdata" translates to the same name as "luser" (using
+ * krb_kntoln()), returns OK. Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK. Otherwise, the file is read for
+ * a matching principal name, instance, and realm. If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format:
+ *
+ * name.instance@realm
+ *
+ * one entry per line.
+ *
+ * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
+ * file entries. See the file "kparse.c".
+ */
+
+#ifdef ATHENA_COMPAT
+
+#include <kparse.h>
+
+/*
+ * The parmtable defines the keywords we will recognize with their
+ * default values, and keeps a pointer to the found value. The found
+ * value should be filled in with strsave(), since FreeParameterSet()
+ * will release memory for all non-NULL found strings.
+ *
+*** NOTE WELL! ***
+ *
+ * The table below is very nice, but we cannot hard-code a default for the
+ * realm: we have to get the realm via krb_get_lrealm(). Even though the
+ * default shows as "from krb_get_lrealm, below", it gets changed in
+ * kuserok to whatever krb_get_lrealm() tells us. That code assumes that
+ * the realm will be the entry number in the table below, so if you
+ * change the order of the entries below, you have to change the
+ * #definition of REALM_SCRIPT to reflect it.
+ */
+#define REALM_SUBSCRIPT 1
+parmtable kparm[] = {
+
+/* keyword default found value */
+{"user", "", (char *) NULL},
+{"realm", "see krb_get_lrealm, below", (char *) NULL},
+{"instance", "", (char *) NULL},
+};
+#define KPARMS kparm,PARMCOUNT(kparm)
+#endif ATHENA_COMPAT
+
+kuserok(kdata, luser)
+ AUTH_DAT *kdata;
+ char *luser;
+{
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+ int isok = NOTOK, rc;
+ FILE *fp;
+ char kuser[MAX_USERNAME];
+ char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char *newline;
+ int gobble;
+#ifdef ATHENA_COMPAT
+ char local_realm[REALM_SZ];
+#endif ATHENA_COMPAT
+
+ /* no account => no access */
+ if ((pwd = getpwnam(luser)) == NULL) {
+ return(NOTOK);
+ }
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, "/.klogin");
+
+ if (access(pbuf, F_OK)) { /* not accessible */
+ /*
+ * if he's trying to log in as himself, and there is no .klogin file,
+ * let him. To find out, call
+ * krb_kntoln to convert the triple in kdata to a name which we can
+ * string compare.
+ */
+ if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
+ return(OK);
+ }
+ }
+ /* open ~/.klogin */
+ if ((fp = fopen(pbuf, "r")) == NULL) {
+ return(NOTOK);
+ }
+ /*
+ * security: if the user does not own his own .klogin file,
+ * do not grant access
+ */
+ if (fstat(fileno(fp), &sbuf)) {
+ fclose(fp);
+ return(NOTOK);
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ fclose(fp);
+ return(NOTOK);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* Accept old-style .klogin files */
+
+ /*
+ * change the default realm from the hard-coded value to the
+ * accepted realm that Kerberos specifies.
+ */
+ rc = krb_get_lrealm(local_realm, 1);
+ if (rc == KSUCCESS)
+ kparm[REALM_SUBSCRIPT].defvalue = local_realm;
+ else
+ return (rc);
+
+ /* check each line */
+ while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
+ switch (rc) {
+ case PS_BAD_KEYWORD:
+ case PS_SYNTAX:
+ while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
+ break;
+
+ case PS_OKAY:
+ isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
+ ParmCompare(KPARMS, "instance", kdata->pinst) ||
+ ParmCompare(KPARMS, "realm", kdata->prealm));
+ break;
+
+ default:
+ break;
+ }
+ FreeParameterSet(kparm, PARMCOUNT(kparm));
+ }
+ /* reset the stream for parsing new-style names, if necessary */
+ rewind(fp);
+#endif ATHENA_COMPAT
+
+ /* check each line */
+ while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+ /* null-terminate the input string */
+ linebuf[BUFSIZ-1] = '\0';
+ newline = NULL;
+ /* nuke the newline if it exists */
+ if (newline = index(linebuf, '\n'))
+ *newline = '\0';
+ rc = kname_parse(principal, inst, realm, linebuf);
+ if (rc == KSUCCESS) {
+ isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
+ strncmp(kdata->pinst, inst, INST_SZ) ||
+ strncmp(kdata->prealm, realm, REALM_SZ));
+ }
+ /* clean up the rest of the line if necessary */
+ if (!newline)
+ while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+ }
+ fclose(fp);
+ return(isok);
+}
diff --git a/eBones/krb/log.c b/eBones/krb/log.c
new file mode 100644
index 0000000..42fccfb
--- /dev/null
+++ b/eBones/krb/log.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $
+ * $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static is_open;
+
+/*
+ * This file contains three logging routines: set_logfile()
+ * to determine the file that log entries should be written to;
+ * and log() and new_log() to write log entries to the file.
+ */
+
+/*
+ * log() is used to add entries to the logfile (see set_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format".
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * The return value is undefined.
+ */
+
+__BEGIN_DECLS
+char *month_sname __P((int));
+__END_DECLS
+
+
+/*VARARGS1 */
+void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ struct tm *tm;
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return;
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+ fprintf(logfile,"\n");
+ (void) fclose(logfile);
+ return;
+}
+
+/*
+ * set_logfile() changes the name of the file to which
+ * messages are logged. If set_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+set_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
+
+/*
+ * new_log() appends a log entry containing the give time "t" and the
+ * string "string" to the logfile (see set_logfile() above). The file
+ * is opened once and left open. The routine returns 1 on failure, 0
+ * on success.
+ */
+
+new_log(t,string)
+ long t;
+ char *string;
+{
+ static FILE *logfile;
+
+ long time();
+ struct tm *tm;
+
+ if (!is_open) {
+ if ((logfile = fopen(log_name,"a")) == NULL) return(1);
+ is_open = 1;
+ }
+
+ if (t) {
+ tm = localtime(&t);
+
+ fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, string);
+ }
+ else {
+ fprintf(logfile,"\n%20s%s","",string);
+ }
+
+ (void) fflush(logfile);
+ return(0);
+}
diff --git a/eBones/krb/mk_err.c b/eBones/krb/mk_err.c
new file mode 100644
index 0000000..331cba9
--- /dev/null
+++ b/eBones/krb/mk_err.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $
+ * $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a general purpose error reply message. It
+ * doesn't use KTEXT because application protocol may have long
+ * messages, and may want this part of buffer contiguous to other
+ * stuff.
+ *
+ * The error reply is built in "p", using the error code "e" and
+ * error text "e_string" given. The length of the error reply is
+ * returned.
+ *
+ * The error reply is in the following format:
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_ERR message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte order
+ * 4 bytes e given error code
+ * string e_string given error text
+ */
+
+long krb_mk_err(p,e,e_string)
+ u_char *p; /* Where to build error packet */
+ long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *start;
+
+ start = p;
+
+ /* Create fixed part of packet */
+ *p++ = (unsigned char) KRB_PROT_VERSION;
+ *p = (unsigned char) AUTH_MSG_APPL_ERR;
+ *p++ |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ bcopy((char *)&e,(char *)p,4); /* err code */
+ p += sizeof(e);
+ (void) strcpy((char *)p,e_string); /* err text */
+ p += strlen(e_string);
+
+ /* And return the length */
+ return p-start;
+}
diff --git a/eBones/krb/mk_priv.c b/eBones/krb/mk_priv.c
new file mode 100644
index 0000000..3bae4ed
--- /dev/null
+++ b/eBones/krb/mk_priv.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'private msg', i.e.
+ * cryptographically sealed with a private session key.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT.
+ *
+ * Note-- It's too bad that it did a long int compare on the RT before.
+ *
+ * Returns either < 0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $
+ * $Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+
+static u_long c_length;
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+#ifndef NOENCRYTION
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+#endif
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum. Also, the protocol version
+ * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte private_msg_ver protocol version number
+ * 1 byte AUTH_MSG_PRIVATE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * 4 bytes c_length length of data
+#ifndef NOENCRYPT
+ * we encrypt from here with pcbc_encrypt
+#endif
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * 0<=n<=7 bytes pad to 8 byte multiple zeroes
+ */
+
+long krb_mk_priv(in,out,length,schedule,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /* put msg here, leave room for
+ * header! breaks if in and out
+ * (header stuff) overlap */
+ u_long length; /* of in data */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+ static u_char *c_length_ptr;
+ extern int private_msg_ver; /* in krb_rd_priv.c */
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = private_msg_ver;
+ *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+
+ /* calculate cipher length */
+ c_length_ptr = p;
+ p += sizeof(c_length);
+
+ q = p;
+
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+#ifdef NOENCRYPTION
+ /* make all the stuff contiguous for checksum */
+#else
+ /* make all the stuff contiguous for checksum and encryption */
+#endif
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok
+ * until 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+#ifdef notdef
+ /*
+ * calculate the checksum of the length, address, sequence, and
+ * inp data
+ */
+ cksum = quad_cksum(q,NULL,p-q,0,key);
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+ /* stuff checksum */
+ bcopy((char *) &cksum,(char *) p,sizeof(cksum));
+ p += sizeof(cksum);
+#endif
+
+ /*
+ * All the data have been assembled, compute length
+ */
+
+ c_length = p - q;
+ c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
+ sizeof(C_Block);
+ /* stuff the length */
+ bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return (q - out + c_length); /* resulting size */
+}
diff --git a/eBones/krb/mk_req.c b/eBones/krb/mk_req.c
new file mode 100644
index 0000000..bb0f097
--- /dev/null
+++ b/eBones/krb/mk_req.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $
+ * $Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <des.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+static struct timeval tv_local = { 0, 0 };
+static int lifetime = DEFAULT_TKT_LIFE;
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum. It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument. krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req. When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_REQUEST message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte ordering
+ * unsigned char kvno from ticket server's key version
+ * string realm server's realm
+ * unsigned char tl ticket length
+ * unsigned char idl request id length
+ * text ticket->dat ticket for server
+ * text req_id->dat request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos. The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string cr.pname {name, instance, and
+ * string cr.pinst realm of principal
+ * string myrealm making this request}
+ * 4 bytes checksum checksum argument given
+ * unsigned char tv_local.tf_usec time (milliseconds)
+ * 4 bytes tv_local.tv_sec time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ * all rounded up to multiple of 8.
+ */
+
+krb_mk_req(authent,service,instance,realm,checksum)
+ register KTEXT authent; /* Place to build the authenticator */
+ char *service; /* Name of the service */
+ char *instance; /* Service instance */
+ char *realm; /* Authentication domain of service */
+ long checksum; /* Checksum of data (optional) */
+{
+ static KTEXT_ST req_st; /* Temp storage for req id */
+ register KTEXT req_id = &req_st;
+ unsigned char *v = authent->dat; /* Prot version number */
+ unsigned char *t = (authent->dat+1); /* Message type */
+ unsigned char *kv = (authent->dat+2); /* Key version no */
+ unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
+ unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
+ CREDENTIALS cr; /* Credentials used by retr */
+ register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+ int retval; /* Returned by krb_get_cred */
+ static Key_schedule key_s;
+ char myrealm[REALM_SZ];
+
+ /* The fixed parts of the authenticator */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Get the ticket and move it into the authenticator */
+ if (krb_ap_req_debug)
+ printf("Realm: %s\n",realm);
+ /*
+ * Determine realm of these tickets. We will send this to the
+ * KDC from which we are requesting tickets so it knows what to
+ * with our session key.
+ */
+ if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
+ return(retval);
+
+ retval = krb_get_cred(service,instance,realm,&cr);
+
+ if (retval == RET_NOTKT) {
+ if (retval = get_ad_tkt(service,instance,realm,lifetime))
+ return(retval);
+ if (retval = krb_get_cred(service,instance,realm,&cr))
+ return(retval);
+ }
+
+ if (retval != KSUCCESS) return (retval);
+
+ if (krb_ap_req_debug)
+ printf("%s %s %s %s %s\n", service, instance, realm,
+ cr.pname, cr.pinst);
+ *kv = (unsigned char) cr.kvno;
+ (void) strcpy((char *)(authent->dat+3),realm);
+ *tl = (unsigned char) ticket->length;
+ bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
+ ticket->length);
+ authent->length = 6 + strlen(realm) + ticket->length;
+ if (krb_ap_req_debug)
+ printf("Ticket->length = %d\n",ticket->length);
+ if (krb_ap_req_debug)
+ printf("Issue date: %d\n",cr.issue_date);
+
+ /* Build request id */
+ (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
+ req_id->length = strlen(cr.pname)+1;
+ /* Principal's instance */
+ (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
+ req_id->length += strlen(cr.pinst)+1;
+ /* Authentication domain */
+ (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
+ req_id->length += strlen(myrealm)+1;
+ /* Checksum */
+ bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
+ req_id->length += 4;
+
+ /* Fill in the times on the request id */
+ (void) gettimeofday(&tv_local,(struct timezone *) 0);
+ *(req_id->dat+(req_id->length)++) =
+ (unsigned char) tv_local.tv_usec;
+ /* Time (coarse) */
+ bcopy((char *)&(tv_local.tv_sec),
+ (char *)(req_id->dat+req_id->length), 4);
+ req_id->length += 4;
+
+ /* Fill to a multiple of 8 bytes for DES */
+ req_id->length = ((req_id->length+7)/8)*8;
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,key_s,cr.session,ENCRYPT);
+ bzero((char *) key_s, sizeof(key_s));
+#endif /* NOENCRYPTION */
+
+ /* Copy it into the authenticator */
+ bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
+ req_id->length);
+ authent->length += req_id->length;
+ /* And set the id length */
+ *idl = (unsigned char) req_id->length;
+ /* clean up */
+ bzero((char *)req_id, sizeof(*req_id));
+
+ if (krb_ap_req_debug)
+ printf("Authent->length = %d\n",authent->length);
+ if (krb_ap_req_debug)
+ printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
+
+ return(KSUCCESS);
+}
+
+/*
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ *
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(newval)
+int newval;
+{
+ int olife = lifetime;
+
+ lifetime = newval;
+ return(olife);
+}
diff --git a/eBones/krb/mk_safe.c b/eBones/krb/mk_safe.c
new file mode 100644
index 0000000..567004b
--- /dev/null
+++ b/eBones/krb/mk_safe.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'safe msg', i.e. authenticated
+ * using a private session key to seed a checksum. Msg is NOT
+ * encrypted.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT
+ *
+ * Returns either <0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $
+ * $Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long cksum;
+static C_Block big_cksum[2];
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key". The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_SAFE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes big_cksum quadratic checksum of
+ * above using "key"
+ */
+
+long krb_mk_safe(in,out,length,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /*
+ * put msg here, leave room for header!
+ * breaks if in and out (header stuff)
+ * overlap
+ */
+ u_long length; /* of in data */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = KRB_PROT_VERSION;
+ *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+
+ q = p; /* start for checksum stuff */
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+ /* make all the stuff contiguous for checksum */
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok until
+ * 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /*
+ * all that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+#ifdef NOENCRYPTION
+ cksum = 0;
+ bzero(big_cksum, sizeof(big_cksum));
+#else
+ cksum=quad_cksum(q,big_cksum,p-q,2,key);
+#endif
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+
+ /* stuff checksum */
+ bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
+ p += sizeof(big_cksum);
+
+ return ((long)(p - out)); /* resulting size */
+
+}
diff --git a/eBones/krb/month_sname.c b/eBones/krb/month_sname.c
new file mode 100644
index 0000000..e7a63ec
--- /dev/null
+++ b/eBones/krb/month_sname.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $
+ * $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $";
+#endif /* lint */
+
+
+/*
+ * Given an integer 1-12, month_sname() returns a string
+ * containing the first three letters of the corresponding
+ * month. Returns 0 if the argument is out of range.
+ */
+
+char *month_sname(n)
+ int n;
+{
+ static char *name[] = {
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+ };
+ return((n < 1 || n > 12) ? 0 : name [n-1]);
+}
diff --git a/eBones/krb/netread.c b/eBones/krb/netread.c
new file mode 100644
index 0000000..eb86327
--- /dev/null
+++ b/eBones/krb/netread.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $
+ * $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_read() reads from the file descriptor "fd" to the buffer
+ * "buf", until either 1) "len" bytes have been read or 2) cannot
+ * read anymore from "fd". It returns the number of bytes read
+ * or a read() error. (The calling interface is identical to
+ * read(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_read(fd, buf, len)
+int fd;
+register char *buf;
+register int len;
+{
+ int cc, len2 = 0;
+
+ do {
+ cc = read(fd, buf, len);
+ if (cc < 0)
+ return(cc); /* errno is already set */
+ else if (cc == 0) {
+ return(len2);
+ } else {
+ buf += cc;
+ len2 += cc;
+ len -= cc;
+ }
+ } while (len > 0);
+ return(len2);
+}
diff --git a/eBones/krb/netwrite.c b/eBones/krb/netwrite.c
new file mode 100644
index 0000000..5945ce0
--- /dev/null
+++ b/eBones/krb/netwrite.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $";
+ * $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_write() writes "len" bytes from "buf" to the file
+ * descriptor "fd". It returns the number of bytes written or
+ * a write() error. (The calling interface is identical to
+ * write(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_write(fd, buf, len)
+int fd;
+register char *buf;
+int len;
+{
+ int cc;
+ register int wrlen = len;
+ do {
+ cc = write(fd, buf, wrlen);
+ if (cc < 0)
+ return(cc);
+ else {
+ buf += cc;
+ wrlen -= cc;
+ }
+ } while (wrlen > 0);
+ return(len);
+}
diff --git a/eBones/krb/one.c b/eBones/krb/one.c
new file mode 100644
index 0000000..c0e8bc6
--- /dev/null
+++ b/eBones/krb/one.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $
+ * $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $";
+#endif lint
+
+/*
+ * definition of variable set to 1.
+ * used in krb_conf.h to determine host byte order.
+ */
+
+int krbONE = 1;
diff --git a/eBones/krb/pkt_cipher.c b/eBones/krb/pkt_cipher.c
new file mode 100644
index 0000000..6ef870c
--- /dev/null
+++ b/eBones/krb/pkt_cipher.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $
+ * $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+
+/*
+ * This routine takes a reply packet from the Kerberos ticket-granting
+ * service and returns a pointer to the beginning of the ciphertext in it.
+ *
+ * See "prot.h" for packet format.
+ */
+
+KTEXT
+pkt_cipher(packet)
+ KTEXT packet;
+{
+ unsigned char *ptr = pkt_a_realm(packet) + 6
+ + strlen((char *)pkt_a_realm(packet));
+ /* Skip a few more fields */
+ ptr += 3 + 4; /* add 4 for exp_date */
+
+ /* And return the pointer */
+ return((KTEXT) ptr);
+}
diff --git a/eBones/krb/pkt_clen.c b/eBones/krb/pkt_clen.c
new file mode 100644
index 0000000..23ad4c3
--- /dev/null
+++ b/eBones/krb/pkt_clen.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $
+ * $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+extern int krb_debug;
+extern int swap_bytes;
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion. The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order. pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+pkt_clen(pkt)
+ KTEXT pkt;
+{
+ static unsigned short temp,temp2;
+ int clen = 0;
+
+ /* Start of ticket list */
+ unsigned char *ptr = pkt_a_realm(pkt) + 10
+ + strlen((char *)pkt_a_realm(pkt));
+
+ /* Finally the length */
+ bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+ if (swap_bytes) {
+ /* assume a short is 2 bytes?? */
+ swab((char *)&temp,(char *)&temp2,2);
+ temp = temp2;
+ }
+
+ clen = (int) temp;
+
+ if (krb_debug)
+ printf("Clen is %d\n",clen);
+ return(clen);
+}
diff --git a/eBones/krb/rd_err.c b/eBones/krb/rd_err.c
new file mode 100644
index 0000000..e73c47b
--- /dev/null
+++ b/eBones/krb/rd_err.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg',
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $
+ * $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
+ * return the error code from the message in "code" and the text in
+ * "m_data" as follows:
+ *
+ * m_data->app_data points to the error text
+ * m_data->app_length points to the length of the error text
+ *
+ * If all goes well, return RD_AP_OK. If the version number
+ * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
+ * type message, return RD_AP_MSG_TYPE.
+ *
+ * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
+ */
+
+int
+krb_rd_err(in,in_length,code,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* of in msg */
+ long *code; /* received error code */
+ MSG_DAT *m_data;
+{
+ register u_char *p;
+ int swap_bytes = 0;
+ p = in; /* beginning of message */
+
+ if (*p++ != KRB_PROT_VERSION)
+ return(RD_AP_VERSION);
+ if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
+ return(RD_AP_MSG_TYPE);
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* safely get code */
+ bcopy((char *)p,(char *)code,sizeof(*code));
+ if (swap_bytes)
+ swap_u_long(*code);
+ p += sizeof(*code); /* skip over */
+
+ m_data->app_data = p; /* we're now at the error text
+ * message */
+ m_data->app_length = in_length;
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/krb/rd_priv.c b/eBones/krb/rd_priv.c
new file mode 100644
index 0000000..9adefec
--- /dev/null
+++ b/eBones/krb/rd_priv.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'private msg', decrypting it,
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
+ * the return value is RD_AP_TIME, then either the times are too far
+ * out of synch, OR the packet was modified.
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $
+ * $Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[]=
+"$Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long c_length;
+static int swap_bytes;
+static struct timeval local_time;
+static long delta_t;
+int private_msg_ver = KRB_PROT_VERSION;
+
+/*
+#ifdef NOENCRPYTION
+ * krb_rd_priv() checks the integrity of an
+#else
+ * krb_rd_priv() decrypts and checks the integrity of an
+#endif
+ * AUTH_MSG_PRIVATE message. Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data". The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender;
+ struct sockaddr_in *receiver;
+ MSG_DAT *m_data; /*various input/output data from msg */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+ return RD_AP_VERSION;
+ private_msg_ver = *(p-1);
+ if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+ return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* get cipher length */
+ bcopy((char *)p,(char *)&c_length,sizeof(c_length));
+ if (swap_bytes)
+ swap_u_long(c_length);
+ p += sizeof(c_length);
+ /* check for rational length so we don't go comatose */
+ if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+ return RD_AP_MODIFIED;
+
+
+ q = p; /* mark start of encrypted stuff */
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT);
+#endif
+
+ /* safely get application data length */
+ bcopy((char *) p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes)
+ swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
+ sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
+ sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
+ > in_length)
+ return RD_AP_MODIFIED;
+
+#ifndef NOENCRYPTION
+ /* we're now at the decrypted application data */
+#endif
+ m_data->app_data = p;
+
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *) p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *) p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes) swap_u_long(m_data->time_sec);
+
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ /*
+ * all that for one tiny bit!
+ * Heaven help those that talk to themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec
+ - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW)
+ return RD_AP_TIME;
+ if (krb_debug)
+ printf("\ndelta_t = %d",delta_t);
+
+ /*
+ * caller must check timestamps for proper order and
+ * replays, since server might have multiple clients
+ * each with its own timestamps and we don't assume
+ * tightly synchronized clocks.
+ */
+
+#ifdef notdef
+ bcopy((char *) p,(char *)&cksum,sizeof(cksum));
+ if (swap_bytes) swap_u_long(cksum)
+ /*
+ * calculate the checksum of the length, sequence,
+ * and input data, on the sending byte order!!
+ */
+ calc_cksum = quad_cksum(q,NULL,p-q,0,key);
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ calc_cksum, cksum);
+ if (cksum != calc_cksum)
+ return RD_AP_MODIFIED;
+#endif
+ return RD_AP_OK; /* OK == 0 */
+}
diff --git a/eBones/krb/rd_req.c b/eBones/krb/rd_req.c
new file mode 100644
index 0000000..22b6540
--- /dev/null
+++ b/eBones/krb/rd_req.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $
+ * $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+
+static struct timeval t_local = { 0, 0 };
+
+/*
+ * Keep the following information around for subsequent calls
+ * to this routine by the same server using the same key.
+ */
+
+static Key_schedule serv_key; /* Key sched to decrypt ticket */
+static C_Block ky; /* 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 */
+
+/*
+ * 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 static variable "ky". A key schedule is
+ * generated for "ky" and returned in the external static variable
+ * "serv_key".
+ *
+ * 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
+ bzero(ky, sizeof(ky));
+ return KSUCCESS;
+#else
+ if (cvt)
+ string_to_key(key,ky);
+ else
+ bcopy(key,(char *)ky,8);
+ return(des_key_sched(ky,serv_key));
+#endif
+}
+
+
+/*
+ * 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.
+ */
+
+krb_rd_req(authent,service,instance,from_addr,ad,fn)
+ register KTEXT authent; /* The received message */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ long from_addr; /* Net address of originating host */
+ AUTH_DAT *ad; /* Structure to be filled in */
+ char *fn; /* Filename to get keys from */
+{
+ static KTEXT_ST ticket; /* Temp storage for ticket */
+ static KTEXT tkt = &ticket;
+ static KTEXT_ST req_id_st; /* Temp storage for authenticator */
+ register KTEXT req_id = &req_id_st;
+
+ char realm[REALM_SZ]; /* Realm of issuing kerberos */
+ static Key_schedule seskey_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 */
+ register char *ptr; /* For stepping through */
+ unsigned long delta_t; /* Time in authenticator - local time */
+ long tkt_age; /* Age of ticket */
+ static int swap_bytes; /* Need to swap bytes? */
+ static int mutual; /* Mutual authentication requested? */
+ static 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 */
+ (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
+ ptr += strlen(ptr) + 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) || strcmp(st_inst,instance) ||
+ strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+ if (*fn == 0) fn = KEYFILE;
+ st_kvno = s_kvno;
+#ifndef NOENCRYPTION
+ if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey))
+ return(RD_AP_UNDEC);
+ if (status=krb_set_key((char *)skey,0)) return(status);
+#endif
+ (void) strcpy(st_rlm,realm);
+ (void) strcpy(st_nam,service);
+ (void) 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);
+ bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
+
+ if (krb_ap_req_debug)
+ 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,ky,serv_key))
+ return(RD_AP_UNDEC);
+
+ if (krb_ap_req_debug) {
+ log("Ticket Contents.");
+ log(" Aname: %s.%s",ad->pname,
+ ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+ 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);
+ bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
+
+#ifndef NOENCRYPTION
+ key_sched(ad->session,seskey_sched);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,seskey_sched,ad->session,DES_DECRYPT);
+#endif /* NOENCRYPTION */
+
+#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 */
+ ptr += strlen(r_aname)+1;
+ check_ptr();
+ (void) strcpy(r_inst,ptr); /* Authentication instance */
+ ptr += strlen(r_inst)+1;
+ check_ptr();
+ (void) strcpy(r_realm,ptr); /* Authentication name */
+ ptr += strlen(r_realm)+1;
+ check_ptr();
+ bcopy(ptr,(char *)&ad->checksum,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 ?? */
+ bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(r_time_sec);
+
+ /* Check for authenticity of the request */
+ if (krb_ap_req_debug)
+ 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)
+ log("Realm: %s %s",ad->prealm,r_realm);
+ if ((strcmp(ad->prealm,r_realm) != 0))
+ return(RD_AP_INCON);
+
+ if (krb_ap_req_debug)
+ log("Address: %d %d",ad->address,from_addr);
+ if (from_addr && (ad->address != from_addr))
+ return(RD_AP_BADD);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ delta_t = abs((int)(t_local.tv_sec - r_time_sec));
+ if (delta_t > CLOCK_SKEW) {
+ if (krb_ap_req_debug)
+ 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)
+ 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);
+}
diff --git a/eBones/krb/rd_safe.c b/eBones/krb/rd_safe.c
new file mode 100644
index 0000000..e500b4d
--- /dev/null
+++ b/eBones/krb/rd_safe.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg', checking its
+ * integrity, and returning a pointer to the application data
+ * contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $
+ * $Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static C_Block calc_cksum[2];
+static C_Block big_cksum[2];
+static int swap_bytes;
+static struct timeval local_time;
+static u_long delta_t;
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data". The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender's address */
+ struct sockaddr_in *receiver; /* receiver's address -- me */
+ MSG_DAT *m_data; /* where to put message information */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+ /* Be very conservative */
+ if (sizeof(u_long) != sizeof(struct in_addr)) {
+ fprintf(stderr,"\n\
+krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
+ exit(-1);
+ }
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION;
+ if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+
+ q = p; /* mark start of cksum stuff */
+
+ /* safely get length */
+ bcopy((char *)p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes) swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(in_length)
+ + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
+ + sizeof(big_cksum) + sizeof(src_addr)
+ + VERSION_SZ + MSG_TYPE_SZ > in_length)
+ return(RD_AP_MODIFIED);
+
+ m_data->app_data = p; /* we're now at the application data */
+
+ /* skip app data */
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *)p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
+
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *)p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes)
+ swap_u_long(m_data->time_sec);
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+ /*
+ * caller must check timestamps for proper order and replays, since
+ * server might have multiple clients each with its own timestamps
+ * and we don't assume tightly synchronized clocks.
+ */
+
+ bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
+ if (swap_bytes) swap_u_16(big_cksum);
+
+#ifdef NOENCRYPTION
+ bzero(calc_cksum, sizeof(calc_cksum));
+#else
+ quad_cksum(q,calc_cksum,p-q,2,key);
+#endif
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ (long) calc_cksum[0], (long) big_cksum[0]);
+ if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
+ return(RD_AP_MODIFIED);
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/krb/read_service_key.c b/eBones/krb/read_service_key.c
new file mode 100644
index 0000000..4d66710
--- /dev/null
+++ b/eBones/krb/read_service_key.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $
+ * $Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <stdio.h>
+#include <strings.h>
+
+/*
+ * The private keys for servers on a given host are stored in a
+ * "srvtab" file (typically "/etc/srvtab"). This routine extracts
+ * a given server's key from the file.
+ *
+ * read_service_key() takes the server's name ("service"), "instance",
+ * and "realm" and a key version number "kvno", and looks in the given
+ * "file" for the corresponding entry, and if found, returns the entry's
+ * key field in "key".
+ *
+ * If "instance" contains the string "*", then it will match
+ * any instance, and the chosen instance will be copied to that
+ * string. For this reason it is important that the there is enough
+ * space beyond the "*" to receive the entry.
+ *
+ * If "kvno" is 0, it is treated as a wild card and the first
+ * matching entry regardless of the "vno" field is returned.
+ *
+ * This routine returns KSUCCESS on success, otherwise KFAILURE.
+ *
+ * The format of each "srvtab" entry is as follows:
+ *
+ * Size Variable Field in file
+ * ---- -------- -------------
+ * string serv server name
+ * string inst server instance
+ * string realm server realm
+ * 1 byte vno server key version #
+ * 8 bytes key server's key
+ * ... ... ...
+ */
+
+
+/*ARGSUSED */
+read_service_key(service,instance,realm,kvno,file,key)
+ char *service; /* Service Name */
+ char *instance; /* Instance name or "*" */
+ char *realm; /* Realm */
+ int kvno; /* Key version number */
+ char *file; /* Filename */
+ char *key; /* Pointer to key to be filled in */
+{
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char vno; /* Key version number */
+ int wcard;
+
+ int stab, open();
+
+ if ((stab = open(file, 0, 0)) < NULL)
+ return(KFAILURE);
+
+ wcard = (instance[0] == '*') && (instance[1] == '\0');
+
+ while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
+ (void) getst(stab,inst,INST_SZ); /* Instance */
+ (void) getst(stab,rlm,REALM_SZ); /* Realm */
+ /* Vers number */
+ if (read(stab,(char *)&vno,1) != 1) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Key */
+ if (read(stab,key,8) != 8) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Is this the right service */
+ if (strcmp(serv,service))
+ continue;
+ /* How about instance */
+ if (!wcard && strcmp(inst,instance))
+ continue;
+ if (wcard)
+ (void) strncpy(instance,inst,INST_SZ);
+ /* Is this the right realm */
+#ifdef ATHENA_COMPAT
+ /* XXX For backward compatibility: if keyfile says "Athena"
+ and caller wants "ATHENA.MIT.EDU", call it a match */
+ if (strcmp(rlm,realm) &&
+ (strcmp(rlm,"Athena") ||
+ strcmp(realm,"ATHENA.MIT.EDU")))
+ continue;
+#else /* ! ATHENA_COMPAT */
+ if (strcmp(rlm,realm))
+ continue;
+#endif /* ATHENA_COMPAT */
+
+ /* How about the key version number */
+ if (kvno && kvno != (int) vno)
+ continue;
+
+ (void) close(stab);
+ return(KSUCCESS);
+ }
+
+ /* Can't find the requested service */
+ (void) close(stab);
+ return(KFAILURE);
+}
diff --git a/eBones/krb/recvauth.c b/eBones/krb/recvauth.c
new file mode 100644
index 0000000..fe26814
--- /dev/null
+++ b/eBones/krb/recvauth.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $";
+ * $Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
+ chars */
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_sendauth.c
+ * be sure to support old versions of krb_sendauth!
+ */
+
+extern int errno;
+
+/*
+ * krb_recvauth() reads (and optionally responds to) a message sent
+ * using krb_sendauth(). The "options" argument is a bit-field of
+ * selected options (see "sendauth.c" for options description).
+ * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
+ * (mutual authentication requested). The "fd" argument supplies
+ * a file descriptor to read from (and write to, if mutual authenti-
+ * cation is requested).
+ *
+ * Part of the received message will be a Kerberos ticket sent by the
+ * client; this is read into the "ticket" argument. The "service" and
+ * "instance" arguments supply the server's Kerberos name. If the
+ * "instance" argument is the string "*", it is treated as a wild card
+ * and filled in during the krb_rd_req() call (see read_service_key()).
+ *
+ * The "faddr" and "laddr" give the sending (client) and receiving
+ * (local server) network addresses. ("laddr" may be left NULL unless
+ * mutual authentication is requested, in which case it must be set.)
+ *
+ * The authentication information extracted from the message is returned
+ * in "kdata". The "filename" argument indicates the file where the
+ * server's key can be found. (It is passed on to krb_rd_req().) If
+ * left null, the default "/etc/srvtab" will be used.
+ *
+ * If mutual authentication is requested, the session key schedule must
+ * be computed in order to reply; this schedule is returned in the
+ * "schedule" argument. A string containing the application version
+ * number from the received message is returned in "version", which
+ * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
+ *
+ * See krb_sendauth() for the format of the received client message.
+ *
+ * This routine supports another client format, for backward
+ * compatibility, consisting of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * string tmp_buf, tkt_len length of ticket, in
+ * ascii
+ *
+ * char ' ' (space char) separator
+ *
+ * tkt_len ticket->dat the ticket
+ *
+ * This old-style version does not support mutual authentication.
+ *
+ * krb_recvauth() first reads the protocol version string from the
+ * given file descriptor. If it doesn't match the current protocol
+ * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In
+ * that case, the string of characters up to the first space is read
+ * and interpreted as the ticket length, then the ticket is read.
+ *
+ * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
+ * next reads the application protocol version string. Then the
+ * ticket length and ticket itself are read.
+ *
+ * The ticket is decrypted and checked by the call to krb_rd_req().
+ * If no mutual authentication is required, the result of the
+ * krb_rd_req() call is retured by this routine. If mutual authenti-
+ * cation is required, a message in the following format is returned
+ * on "fd":
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 4 bytes tkt_len length of ticket or -1
+ * if error occurred
+ *
+ * priv_len tmp_buf "private" message created
+ * by krb_mk_priv() which
+ * contains the incremented
+ * checksum sent by the client
+ * encrypted in the session
+ * key. (This field is not
+ * present in case of error.)
+ *
+ * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
+ * other error code is returned.
+ */
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+int
+krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+ filename, schedule, version)
+long options; /* bit-pattern of options */
+int fd; /* file descr. to read from */
+KTEXT ticket; /* storage for client's ticket */
+char *service; /* service expected */
+char *instance; /* inst expected (may be filled in) */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+struct sockaddr_in *laddr; /* local address */
+AUTH_DAT *kdata; /* kerberos data (returned) */
+char *filename; /* name of file with service keys */
+Key_schedule schedule; /* key schedule (return) */
+char *version; /* version string (filled in) */
+{
+
+ int i, cc, old_vers = 0;
+ char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
+ char *cp;
+ int rem;
+ long tkt_len, priv_len;
+ u_long cksum;
+ u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+ /* read the protocol version number */
+ if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ krb_vers[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* check version string */
+ if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
+ /* Assume the old version of sendkerberosdata: send ascii
+ length, ' ', and ticket. */
+ if (options & KOPT_DO_MUTUAL)
+ return(KFAILURE); /* XXX can't do old style with mutual auth */
+ old_vers = 1;
+
+ /* copy what we have read into tmp_buf */
+ (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
+
+ /* search for space, and make it a null */
+ for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
+ if (tmp_buf[i]== ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+
+ if (i == KRB_SENDAUTH_VLEN)
+ /* didn't find the space, keep reading to find it */
+ for (; i<20; i++) {
+ if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
+ return(KFAILURE);
+ }
+ if (tmp_buf[i] == ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+ }
+
+ tkt_len = (long) atoi((char *) tmp_buf);
+
+ /* sanity check the length */
+ if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
+ return(KFAILURE);
+
+ 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 */
+ 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))
+ return(errno);
+ } else {
+ if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
+ (int) tkt_len)
+ return(errno);
+ }
+ ticket->length = tkt_len;
+ /* copy the ticket into the struct */
+ (void) bcopy(cp, (char *) ticket->dat, ticket->length);
+
+ } else {
+ /* read the application version string */
+ if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ version[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* get the length of the ticket */
+ if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+
+ /* sanity check */
+ ticket->length = ntohl((unsigned long)tkt_len);
+ if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+ if (options & KOPT_DO_MUTUAL) {
+ rem = KFAILURE;
+ goto mutual_fail;
+ } else
+ return(KFAILURE); /* XXX there may still be junk on the fd? */
+ }
+
+ /* read the ticket */
+ if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+ != ticket->length)
+ return(errno);
+ }
+ /*
+ * now have the ticket. decrypt it to get the authenticated
+ * data.
+ */
+ rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+ kdata,filename);
+
+ if (old_vers) return(rem); /* XXX can't do mutual with old client */
+
+ /* if we are doing mutual auth, compose a response */
+ if (options & KOPT_DO_MUTUAL) {
+ if (rem != KSUCCESS)
+ /* the krb_rd_req failed */
+ goto mutual_fail;
+
+ /* add one to the (formerly) sealed checksum, and re-seal it
+ for return to the client */
+ cksum = kdata->checksum + 1;
+ cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+ key_sched(kdata->session,schedule);
+#endif
+ priv_len = krb_mk_priv((unsigned char *)&cksum,
+ tmp_buf,
+ (unsigned long) sizeof(cksum),
+ schedule,
+ kdata->session,
+ laddr,
+ faddr);
+ if (priv_len < 0) {
+ /* re-sealing failed; notify the client */
+ rem = KFAILURE; /* XXX */
+mutual_fail:
+ priv_len = -1;
+ tkt_len = htonl((unsigned long) priv_len);
+ /* a length of -1 is interpreted as an authentication
+ failure by the client */
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ return(rem);
+ } else {
+ /* re-sealing succeeded, send the private message */
+ tkt_len = htonl((unsigned long)priv_len);
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+ != (int) priv_len)
+ return(cc);
+ }
+ }
+ return(rem);
+}
diff --git a/eBones/krb/save_credentials.c b/eBones/krb/save_credentials.c
new file mode 100644
index 0000000..129c912
--- /dev/null
+++ b/eBones/krb/save_credentials.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $
+ * $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * This routine takes a ticket and associated info and calls
+ * tf_save_cred() to store them in the ticket cache. The peer
+ * routine for extracting a ticket and associated info from the
+ * ticket cache is krb_get_cred(). When changes are made to
+ * this routine, the corresponding changes should be made
+ * in krb_get_cred() as well.
+ *
+ * Returns KSUCCESS if all goes well, otherwise an error returned
+ * by the tf_init() or tf_save_cred() routines.
+ */
+
+save_credentials(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+ int tf_status; /* return values of the tf_util calls */
+
+ /* Open and lock the ticket file for writing */
+ if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Save credentials by appending to the ticket file */
+ tf_status = tf_save_cred(service, instance, realm, session,
+ lifetime, kvno, ticket, issue_date);
+ (void) tf_close();
+ return (tf_status);
+}
diff --git a/eBones/krb/send_to_kdc.c b/eBones/krb/send_to_kdc.c
new file mode 100644
index 0000000..aeaf389
--- /dev/null
+++ b/eBones/krb/send_to_kdc.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $
+ * $Id: send_to_kdc.c,v 1.2 1994/07/19 19:26:21 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid_send_to_kdc_c[] =
+"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp ";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef lint
+#include <sys/uio.h> /* struct iovec to make lint happy */
+#endif /* lint */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <strings.h>
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+extern int errno;
+extern int krb_debug;
+
+extern char *malloc(), *calloc(), *realloc();
+
+int krb_udp_port = 0;
+
+/* CLIENT_KRB_TIMEOUT indicates the time to wait before
+ * retrying a server. It's defined in "krb.h".
+ */
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};
+static char *prog = "send_to_kdc";
+static send_recv();
+
+/*
+ * This file contains two routines, send_to_kdc() and send_recv().
+ * send_recv() is a static routine used by send_to_kdc().
+ */
+
+/*
+ * send_to_kdc() sends a message to the Kerberos authentication
+ * server(s) in the given realm and returns the reply message.
+ * The "pkt" argument points to the message to be sent to Kerberos;
+ * the "rpkt" argument will be filled in with Kerberos' reply.
+ * The "realm" argument indicates the realm of the Kerberos server(s)
+ * to transact with. If the realm is null, the local realm is used.
+ *
+ * If more than one Kerberos server is known for a given realm,
+ * different servers will be queried until one of them replies.
+ * Several attempts (retries) are made for each server before
+ * giving up entirely.
+ *
+ * If an answer was received from a Kerberos host, KSUCCESS is
+ * returned. The following errors can be returned:
+ *
+ * SKDC_CANT - can't get local realm
+ * - can't find "kerberos" in /etc/services database
+ * - can't open socket
+ * - can't bind socket
+ * - all ports in use
+ * - couldn't find any Kerberos host
+ *
+ * SKDC_RETRY - couldn't get an answer from any Kerberos server,
+ * after several retries
+ */
+
+send_to_kdc(pkt,rpkt,realm)
+ KTEXT pkt;
+ KTEXT rpkt;
+ char *realm;
+{
+ int i, f;
+ int no_host; /* was a kerberos host found? */
+ int retry;
+ int n_hosts;
+ int retval;
+ struct sockaddr_in to;
+ struct hostent *host, *hostlist;
+ char *cp;
+ char krbhst[MAX_HSTNM];
+ char lrealm[REALM_SZ];
+
+ /*
+ * If "realm" is non-null, use that, otherwise get the
+ * local realm.
+ */
+ if (realm)
+ (void) strcpy(lrealm, realm);
+ else
+ if (krb_get_lrealm(lrealm,1)) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't get local realm\n", prog);
+ return(SKDC_CANT);
+ }
+ if (krb_debug)
+ printf("lrealm is %s\n", lrealm);
+ if (krb_udp_port == 0) {
+ register struct servent *sp;
+ if ((sp = getservbyname("kerberos","udp")) == 0) {
+ if (krb_debug)
+ fprintf(stderr, "%s: Can't get kerberos/udp service\n",
+ prog);
+ return(SKDC_CANT);
+ }
+ krb_udp_port = sp->s_port;
+ if (krb_debug)
+ printf("krb_udp_port is %d\n", krb_udp_port);
+ }
+ bzero((char *)&to, S_AD_SZ);
+ hostlist = (struct hostent *) malloc(sizeof(struct hostent));
+ if (!hostlist)
+ return (/*errno */SKDC_CANT);
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"%s: Can't open socket\n", prog);
+ return(SKDC_CANT);
+ }
+ /* from now on, exit through rtn label for cleanup */
+
+ no_host = 1;
+ /* get an initial allocation */
+ n_hosts = 0;
+ for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
+ if (krb_debug) {
+ printf("Getting host entry for %s...",krbhst);
+ (void) fflush(stdout);
+ }
+ host = gethostbyname(krbhst);
+ if (krb_debug) {
+ printf("%s.\n",
+ host ? "Got it" : "Didn't get it");
+ (void) fflush(stdout);
+ }
+ if (!host)
+ continue;
+ no_host = 0; /* found at least one */
+ n_hosts++;
+ /* preserve host network address to check later
+ * (would be better to preserve *all* addresses,
+ * take care of that later)
+ */
+ hostlist = (struct hostent *)
+ realloc((char *)hostlist,
+ (unsigned)
+ sizeof(struct hostent)*(n_hosts+1));
+ if (!hostlist)
+ return /*errno */SKDC_CANT;
+ bcopy((char *)host, (char *)&hostlist[n_hosts-1],
+ sizeof(struct hostent));
+ host = &hostlist[n_hosts-1];
+ cp = malloc((unsigned)host->h_length);
+ if (!cp) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+ bcopy((char *)host->h_addr, cp, host->h_length);
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+ (or worse) only return one name ... */
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ host->h_addr_list = (char **)malloc(sizeof(char *));
+ if (!host->h_addr_list) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+#endif /* ULTRIX022 || SunOS */
+ host->h_addr = cp;
+ bzero((char *)&hostlist[n_hosts],
+ sizeof(struct hostent));
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ to.sin_port = krb_udp_port;
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ if (krb_debug) {
+ printf("Timeout, error, or wrong descriptor\n");
+ (void) fflush(stdout);
+ }
+ }
+ if (no_host) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't find any Kerberos host.\n",
+ prog);
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ /* retry each host in sequence */
+ for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
+ for (host = hostlist; host->h_name != (char *)NULL; host++) {
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ }
+ }
+ retval = SKDC_RETRY;
+rtn:
+ (void) close(f);
+ if (hostlist) {
+ register struct hostent *hp;
+ for (hp = hostlist; hp->h_name; hp++)
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ if (hp->h_addr_list) {
+#endif /* ULTRIX022 || SunOS */
+ if (hp->h_addr)
+ free(hp->h_addr);
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ free((char *)hp->h_addr_list);
+ }
+#endif /* ULTRIX022 || SunOS */
+ free((char *)hostlist);
+ }
+ return(retval);
+}
+
+/*
+ * try to send out and receive message.
+ * return 1 on success, 0 on failure
+ */
+
+static send_recv(pkt,rpkt,f,_to,addrs)
+ KTEXT pkt;
+ KTEXT rpkt;
+ int f;
+ struct sockaddr_in *_to;
+ struct hostent *addrs;
+{
+ fd_set readfds;
+ register struct hostent *hp;
+ struct sockaddr_in from;
+ int sin_size;
+ int numsent;
+
+ if (krb_debug) {
+ if (_to->sin_family == AF_INET)
+ printf("Sending message to %s...",
+ inet_ntoa(_to->sin_addr));
+ else
+ printf("Sending message...");
+ (void) fflush(stdout);
+ }
+ if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0,
+ (struct sockaddr *)_to,
+ S_AD_SZ)) != pkt->length) {
+ if (krb_debug)
+ printf("sent only %d/%d\n",numsent, pkt->length);
+ return 0;
+ }
+ if (krb_debug) {
+ printf("Sent\nWaiting for reply...");
+ (void) fflush(stdout);
+ }
+ FD_ZERO(&readfds);
+ FD_SET(f, &readfds);
+ errno = 0;
+ /* select - either recv is ready, or timeout */
+ /* see if timeout or error or wrong descriptor */
+ if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1
+ || !FD_ISSET(f, &readfds)) {
+ if (krb_debug) {
+ fprintf(stderr, "select failed: readfds=%x",
+ readfds);
+ perror("");
+ }
+ return 0;
+ }
+ sin_size = sizeof(from);
+ if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0,
+ (struct sockaddr *)&from, &sin_size)
+ < 0) {
+ if (krb_debug)
+ perror("recvfrom");
+ return 0;
+ }
+ if (krb_debug) {
+ printf("received packet from %s\n", inet_ntoa(from.sin_addr));
+ fflush(stdout);
+ }
+ for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+ if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr,
+ hp->h_length)) {
+ if (krb_debug) {
+ printf("Received it\n");
+ (void) fflush(stdout);
+ }
+ return 1;
+ }
+ if (krb_debug)
+ fprintf(stderr,
+ "packet not from %x\n",
+ hp->h_addr);
+ }
+ if (krb_debug)
+ fprintf(stderr, "%s: received packet from wrong host! (%x)\n",
+ "send_to_kdc(send_rcv)", from.sin_addr.s_addr);
+ return 0;
+}
diff --git a/eBones/krb/sendauth.c b/eBones/krb/sendauth.c
new file mode 100644
index 0000000..7d798bb
--- /dev/null
+++ b/eBones/krb/sendauth.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $
+ * $Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_recvauth.c
+ */
+
+extern int errno;
+
+extern char *krb_get_phost();
+
+/*
+ * This file contains two routines: krb_sendauth() and krb_sendsrv().
+ *
+ * krb_sendauth() transmits a ticket over a file descriptor for a
+ * desired service, instance, and realm, doing mutual authentication
+ * with the server if desired.
+ *
+ * krb_sendsvc() sends a service name to a remote knetd server.
+ */
+
+/*
+ * The first argument to krb_sendauth() contains a bitfield of
+ * options (the options are defined in "krb.h"):
+ *
+ * KOPT_DONT_CANON Don't canonicalize instance as a hostname.
+ * (If this option is not chosen, krb_get_phost()
+ * is called to canonicalize it.)
+ *
+ * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos.
+ * A ticket must be supplied in the "ticket"
+ * argument.
+ * (If this option is not chosen, and there
+ * is no ticket for the given server in the
+ * ticket cache, one will be fetched using
+ * krb_mk_req() and returned in "ticket".)
+ *
+ * KOPT_DO_MUTUAL Do mutual authentication, requiring that the
+ * receiving server return the checksum+1 encrypted
+ * in the session key. The mutual authentication
+ * is done using krb_mk_priv() on the other side
+ * (see "recvauth.c") and krb_rd_priv() on this
+ * side.
+ *
+ * The "fd" argument is a file descriptor to write to the remote
+ * server on. The "ticket" argument is used to store the new ticket
+ * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
+ * chosen, the ticket must be supplied in the "ticket" argument.
+ * The "service", "inst", and "realm" arguments identify the ticket.
+ * If "realm" is null, the local realm is used.
+ *
+ * The following arguments are only needed if the KOPT_DO_MUTUAL option
+ * is chosen:
+ *
+ * The "checksum" argument is a number that the server will add 1 to
+ * to authenticate itself back to the client; the "msg_data" argument
+ * holds the returned mutual-authentication message from the server
+ * (i.e., the checksum+1); the "cred" structure is used to hold the
+ * session key of the server, extracted from the ticket file, for use
+ * in decrypting the mutual authentication message from the server;
+ * and "schedule" holds the key schedule for that decryption. The
+ * the local and server addresses are given in "laddr" and "faddr".
+ *
+ * The application protocol version number (of up to KRB_SENDAUTH_VLEN
+ * characters) is passed in "version".
+ *
+ * If all goes well, KSUCCESS is returned, otherwise some error code.
+ *
+ * The format of the message sent to the server is:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol
+ * bytes version number
+ *
+ * KRB_SENDAUTH_VLEN version application protocol
+ * bytes version number
+ *
+ * 4 bytes ticket->length length of ticket
+ *
+ * ticket->length ticket->dat ticket itself
+ */
+
+/*
+ * XXX: Note that krb_rd_priv() is coded in such a way that
+ * "msg_data->app_data" will be pointing into "priv_buf", which
+ * will disappear when krb_sendauth() returns.
+ */
+
+int
+krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
+ msg_data, cred, schedule, laddr, faddr, version)
+long options; /* bit-pattern of options */
+int fd; /* file descriptor to write onto */
+KTEXT ticket; /* where to put ticket (return); or
+ * supplied in case of KOPT_DONT_MK_REQ */
+char *service, *inst, *realm; /* service name, instance, realm */
+u_long checksum; /* checksum to include in request */
+MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */
+CREDENTIALS *cred; /* credentials (return) */
+Key_schedule schedule; /* key schedule (return) */
+struct sockaddr_in *laddr; /* local address */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+char *version; /* version string */
+{
+ int rem, i, cc;
+ char srv_inst[INST_SZ];
+ char krb_realm[REALM_SZ];
+ char buf[BUFSIZ];
+ long tkt_len;
+ u_char priv_buf[1024];
+ u_long cksum;
+
+ rem=KSUCCESS;
+
+ /* get current realm if not passed in */
+ if (!realm) {
+ rem = krb_get_lrealm(krb_realm,1);
+ if (rem != KSUCCESS)
+ return(rem);
+ realm = krb_realm;
+ }
+
+ /* copy instance into local storage, canonicalizing if desired */
+ if (options & KOPT_DONT_CANON)
+ (void) strncpy(srv_inst, inst, INST_SZ);
+ else
+ (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
+
+ /* get the ticket if desired */
+ if (!(options & KOPT_DONT_MK_REQ)) {
+ rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
+ if (rem != KSUCCESS)
+ return(rem);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* this is only for compatibility with old servers */
+ if (options & KOPT_DO_OLDSTYLE) {
+ (void) sprintf(buf,"%d ",ticket->length);
+ (void) write(fd, buf, strlen(buf));
+ (void) write(fd, (char *) ticket->dat, ticket->length);
+ return(rem);
+ }
+#endif ATHENA_COMPAT
+ /* if mutual auth, get credentials so we have service session
+ keys for decryption below */
+ if (options & KOPT_DO_MUTUAL)
+ if (cc = krb_get_cred(service, srv_inst, realm, cred))
+ return(cc);
+
+ /* zero the buffer */
+ (void) bzero(buf, BUFSIZ);
+
+ /* insert version strings */
+ (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+ (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
+
+ /* increment past vers strings */
+ i = 2*KRB_SENDAUTH_VLEN;
+
+ /* put ticket length into buffer */
+ tkt_len = htonl((unsigned long) ticket->length);
+ (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
+ i += sizeof(tkt_len);
+
+ /* put ticket into buffer */
+ (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
+ i += ticket->length;
+
+ /* write the request to the server */
+ if ((cc = krb_net_write(fd, buf, i)) != i)
+ return(cc);
+
+ /* mutual authentication, if desired */
+ if (options & KOPT_DO_MUTUAL) {
+ /* get the length of the reply */
+ if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+ tkt_len = ntohl((unsigned long)tkt_len);
+
+ /* if the length is negative, the server failed to recognize us. */
+ if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf)))
+ return(KFAILURE); /* XXX */
+ /* read the reply... */
+ if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
+ return(errno);
+
+ /* ...and decrypt it */
+#ifndef NOENCRYPTION
+ key_sched(cred->session,schedule);
+#endif
+ if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule,
+ cred->session, faddr, laddr, msg_data))
+ return(cc);
+
+ /* fetch the (modified) checksum */
+ (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
+ sizeof(cksum));
+ cksum = ntohl(cksum);
+
+ /* if it doesn't match, fail */
+ if (cksum != checksum + 1)
+ return(KFAILURE); /* XXX */
+ }
+ return(KSUCCESS);
+}
+
+#ifdef ATHENA_COMPAT
+/*
+ * krb_sendsvc
+ */
+
+int
+krb_sendsvc(fd, service)
+int fd;
+char *service;
+{
+ /* write the service name length and then the service name to
+ the fd */
+ long serv_length;
+ int cc;
+
+ serv_length = htonl((unsigned long)strlen(service));
+ if ((cc = krb_net_write(fd, (char *) &serv_length,
+ sizeof(serv_length)))
+ != sizeof(serv_length))
+ return(cc);
+ if ((cc = krb_net_write(fd, service, strlen(service)))
+ != strlen(service))
+ return(cc);
+ return(KSUCCESS);
+}
+#endif ATHENA_COMPAT
diff --git a/eBones/krb/stime.c b/eBones/krb/stime.c
new file mode 100644
index 0000000..c040374
--- /dev/null
+++ b/eBones/krb/stime.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $
+ * $Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h> /* for sprintf() */
+
+/*
+ * Given a pointer to a long containing the number of seconds
+ * since the beginning of time (midnight 1 Jan 1970 GMT), return
+ * a string containing the local time in the form:
+ *
+ * "25-Jan-88 10:17:56"
+ */
+
+char *stime(t)
+ long *t;
+{
+ static char st_data[40];
+ static char *st = st_data;
+ struct tm *tm;
+ char *month_sname();
+
+ tm = localtime(t);
+ (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return st;
+}
diff --git a/eBones/krb/tf_shm.c b/eBones/krb/tf_shm.c
new file mode 100644
index 0000000..5548f0d
--- /dev/null
+++ b/eBones/krb/tf_shm.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Shared memory segment functions for session keys. Derived from code
+ * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
+ *
+ * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $
+ * $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <krb.h>
+#include <des.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */
+
+extern int errno;
+extern int krb_debug;
+
+/*
+ * krb_create_shmtkt:
+ *
+ * create a shared memory segment for session keys, leaving its id
+ * in the specified filename.
+ */
+
+int
+krb_shm_create(file_name)
+char *file_name;
+{
+ int retval;
+ int shmid;
+ struct shmid_ds shm_buf;
+ FILE *sfile;
+ uid_t me, metoo, getuid(), geteuid();
+
+ (void) krb_shm_dest(file_name); /* nuke it if it exists...
+ this cleans up to make sure we
+ don't slowly lose memory. */
+
+ shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT);
+ if (shmid == -1) {
+ if (krb_debug)
+ perror("krb_shm_create shmget");
+ return(KFAILURE); /* XXX */
+ }
+ me = getuid();
+ metoo = geteuid();
+ /*
+ * now set up the buffer so that we can modify it
+ */
+ shm_buf.shm_perm.uid = me;
+ shm_buf.shm_perm.gid = getgid();
+ shm_buf.shm_perm.mode = 0600;
+ if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */
+ if (krb_debug)
+ perror("krb_shm_create shmctl");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary). */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((sfile = fopen(file_name,"w")) == 0) {
+ if (krb_debug)
+ perror("krb_shm_create file");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (fchmod(fileno(sfile),0600) < 0) {
+ if (krb_debug)
+ perror("krb_shm_create fchmod");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid2");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+
+ (void) fprintf(sfile,"%d",shmid);
+ (void) fflush(sfile);
+ (void) fclose(sfile);
+ return(KSUCCESS);
+}
+
+
+/*
+ * krb_is_diskless:
+ *
+ * check / to see if file .diskless exists. If so it is diskless.
+ * Do it this way now to avoid dependencies on a particular routine.
+ * Choose root file system since that will be private to the client.
+ */
+
+int krb_is_diskless()
+{
+ struct stat buf;
+ if (stat("/.diskless",&buf) < 0)
+ return(0);
+ else return(1);
+}
+
+/*
+ * krb_shm_dest: destroy shared memory segment with session keys, and remove
+ * file pointing to it.
+ */
+
+int krb_shm_dest(file)
+char *file;
+{
+ int shmid;
+ FILE *sfile;
+ struct stat st_buf;
+
+ if (stat(file,&st_buf) == 0) {
+ /* successful stat */
+ if ((sfile = fopen(file,"r")) == 0) {
+ if (krb_debug)
+ perror("cannot open shared memory file");
+ return(KFAILURE); /* XXX */
+ }
+ if (fscanf(sfile,"%d",&shmid) == 1) {
+ if (shmctl(shmid,IPC_RMID,0) != 0) {
+ if (krb_debug)
+ perror("krb_shm_dest: cannot delete shm segment");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ } else {
+ if (krb_debug)
+ fprintf(stderr, "bad format in shmid file\n");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ (void) fclose(sfile);
+ (void) unlink(file);
+ return(KSUCCESS);
+ } else
+ return(RET_TKFIL); /* XXX */
+}
+
+
+
diff --git a/eBones/krb/tf_util.3 b/eBones/krb/tf_util.3
new file mode 100644
index 0000000..3a9bc94
--- /dev/null
+++ b/eBones/krb/tf_util.3
@@ -0,0 +1,151 @@
+.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $
+.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \
+\- Routines for manipulating a Kerberos ticket file
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+tf_init(tf_name, rw)
+char *tf_name;
+int rw;
+.PP
+.ft B
+tf_get_pname(pname)
+char *pname;
+.PP
+.ft B
+tf_get_pinst(pinst)
+char *pinst;
+.PP
+.ft B
+tf_get_cred(c)
+CREDENTIALS *c;
+.PP
+.ft B
+tf_close()
+.PP
+.fi
+.SH DESCRIPTION
+This group of routines are provided to manipulate the Kerberos tickets
+file. A ticket file has the following format:
+.nf
+.in +4
+.sp
+principal's name (null-terminated string)
+principal's instance (null-terminated string)
+CREDENTIAL_1
+CREDENTIAL_2
+ ...
+CREDENTIAL_n
+EOF
+.sp
+.in -4
+.LP
+Where "CREDENTIAL_x" consists of the following fixed-length
+fields from the CREDENTIALS structure (defined in <krb.h>):
+.nf
+.sp
+.in +4
+ char service[ANAME_SZ]
+ char instance[INST_SZ]
+ char realm[REALM_SZ]
+ des_cblock session
+ int lifetime
+ int kvno
+ KTEXT_ST ticket_st
+ long issue_date
+.in -4
+.sp
+.fi
+.PP
+.I tf_init
+must be called before the other ticket file
+routines.
+It takes the name of the ticket file to use,
+and a read/write flag as arguments.
+It tries to open the ticket file, checks the mode and if
+everything is okay, locks the file. If it's opened for
+reading, the lock is shared. If it's opened for writing,
+the lock is exclusive.
+KSUCCESS is returned if all went well, otherwise one of the
+following:
+.nf
+.sp
+NO_TKT_FIL - file wasn't there
+TKT_FIL_ACC - file was in wrong mode, etc.
+TKT_FIL_LCK - couldn't lock the file, even after a retry
+.sp
+.fi
+.PP
+The
+.I tf_get_pname
+reads the principal's name from a ticket file.
+It should only be called after tf_init has been called. The
+principal's name is filled into the
+.I pname
+parameter. If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If the principal's name was null, or EOF was encountered, or the
+name was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+.PP
+The
+.I tf_get_pinst
+reads the principal's instance from a ticket file.
+It should only be called after tf_init and tf_get_pname
+have been called.
+The principal's instance is filled into the
+.I pinst
+parameter.
+If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If EOF was encountered, or the
+name was longer than INST_SZ, TKT_FIL_FMT is returned.
+Note that, unlike the principal name, the instance name may be null.
+.PP
+The
+.I tf_get_cred
+routine reads a CREDENTIALS record from a ticket file and
+fills in the given structure.
+It should only be called after
+tf_init, tf_get_pname, and tf_get_pinst have been called.
+If all goes well, KSUCCESS is returned. Possible error codes
+are:
+.nf
+.sp
+TKT_FIL_INI - tf_init wasn't called first
+TKT_FIL_FMT - bad format
+EOF - end of file encountered
+.sp
+.fi
+.PP
+.I tf_close
+closes the ticket file and releases the lock on it.
+.SH "SEE ALSO"
+krb(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The ticket file routines have to be called in a certain order.
+.SH AUTHORS
+Jennifer Steiner, MIT Project Athena
+.br
+Bill Bryant, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1987 Massachusetts Institute of Technology
diff --git a/eBones/krb/tf_util.c b/eBones/krb/tf_util.c
new file mode 100644
index 0000000..a9e8551
--- /dev/null
+++ b/eBones/krb/tf_util.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $
+ * $Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <krb.h>
+
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* TKT_SHMEM */
+
+#define TOO_BIG -1
+#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before
+ * retry if ticket file is
+ * locked */
+extern errno;
+extern int krb_debug;
+
+#ifdef TKT_SHMEM
+char *krb_shm_addr = 0;
+static char *tmp_shm_addr = 0;
+static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};
+
+char *shmat();
+#endif /* TKT_SHMEM */
+
+/*
+ * fd must be initialized to something that won't ever occur as a real
+ * file descriptor. Since open(2) returns only non-negative numbers as
+ * valid file descriptors, and tf_init always stuffs the return value
+ * from open in here even if it is an error flag, we must
+ * a. Initialize fd to a negative number, to indicate that it is
+ * not initially valid.
+ * b. When checking for a valid fd, assume that negative values
+ * are invalid (ie. when deciding whether tf_init has been
+ * called.)
+ * c. In tf_close, be sure it gets reinitialized to a negative
+ * number.
+ */
+static fd = -1;
+static curpos; /* Position in tfbfr */
+static lastpos; /* End of tfbfr */
+static char tfbfr[BUFSIZ]; /* Buffer for ticket data */
+
+static tf_gets(), tf_read();
+
+/*
+ * This file contains routines for manipulating the ticket cache file.
+ *
+ * The ticket file is in the following format:
+ *
+ * principal's name (null-terminated string)
+ * principal's instance (null-terminated string)
+ * CREDENTIAL_1
+ * CREDENTIAL_2
+ * ...
+ * CREDENTIAL_n
+ * EOF
+ *
+ * Where "CREDENTIAL_x" consists of the following fixed-length
+ * fields from the CREDENTIALS structure (see "krb.h"):
+ *
+ * char service[ANAME_SZ]
+ * char instance[INST_SZ]
+ * char realm[REALM_SZ]
+ * C_Block session
+ * int lifetime
+ * int kvno
+ * KTEXT_ST ticket_st
+ * long issue_date
+ *
+ * Short description of routines:
+ *
+ * tf_init() opens the ticket file and locks it.
+ *
+ * tf_get_pname() returns the principal's name.
+ *
+ * tf_get_pinst() returns the principal's instance (may be null).
+ *
+ * tf_get_cred() returns the next CREDENTIALS record.
+ *
+ * tf_save_cred() appends a new CREDENTIAL record to the ticket file.
+ *
+ * tf_close() closes the ticket file and releases the lock.
+ *
+ * tf_gets() returns the next null-terminated string. It's an internal
+ * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred().
+ *
+ * tf_read() reads a given number of bytes. It's an internal routine
+ * used by tf_get_cred().
+ */
+
+/*
+ * tf_init() should be called before the other ticket file routines.
+ * It takes the name of the ticket file to use, "tf_name", and a
+ * read/write flag "rw" as arguments.
+ *
+ * It tries to open the ticket file, checks the mode, and if everything
+ * is okay, locks the file. If it's opened for reading, the lock is
+ * shared. If it's opened for writing, the lock is exclusive.
+ *
+ * Returns KSUCCESS if all went well, otherwise one of the following:
+ *
+ * NO_TKT_FIL - file wasn't there
+ * TKT_FIL_ACC - file was in wrong mode, etc.
+ * TKT_FIL_LCK - couldn't lock the file, even after a retry
+ */
+
+tf_init(tf_name, rw)
+ char *tf_name;
+{
+ int wflag;
+ uid_t me, getuid();
+ struct stat stat_buf;
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+ FILE *sfp;
+ int shmid;
+#endif
+
+ switch (rw) {
+ case R_TKT_FIL:
+ wflag = 0;
+ break;
+ case W_TKT_FIL:
+ wflag = 1;
+ break;
+ default:
+ if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");
+ return TKT_FIL_ACC;
+ }
+ if (lstat(tf_name, &stat_buf) < 0)
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ me = getuid();
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, tf_name);
+ (void) strcat(shmidname, ".shm");
+ if (stat(shmidname,&stat_buf) < 0)
+ return(TKT_FIL_ACC);
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#endif /* TKT_SHMEM */
+
+ /*
+ * If "wflag" is set, open the ticket file in append-writeonly mode
+ * and lock the ticket file in exclusive mode. If unable to lock
+ * the file, sleep and try again. If we fail again, return with the
+ * proper error message.
+ */
+
+ curpos = sizeof(tfbfr);
+
+#ifdef TKT_SHMEM
+ sfp = fopen(shmidname, "r"); /* only need read/write on the
+ actual tickets */
+ if (sfp == 0)
+ return TKT_FIL_ACC;
+ shmid = -1;
+ {
+ char buf[BUFSIZ];
+ int val; /* useful for debugging fscanf */
+ /* We provide our own buffer here since some STDIO libraries
+ barf on unbuffered input with fscanf() */
+
+ setbuf(sfp, buf);
+ if ((val = fscanf(sfp,"%d",&shmid)) != 1) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ if (shmid < 0) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ (void) fclose(sfp);
+ }
+ /*
+ * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and
+ * attach the same segment twice so we need this check.
+ */
+ if (!krb_shm_addr) {
+ if ((krb_shm_addr = shmat(shmid,0,0)) == -1){
+ if (krb_debug)
+ fprintf(stderr,
+ "cannot attach shared memory for segment %d\n",
+ shmid);
+ krb_shm_addr = 0; /* reset so we catch further errors */
+ return TKT_FIL_ACC;
+ }
+ }
+ tmp_shm_addr = krb_shm_addr;
+#endif /* TKT_SHMEM */
+
+ if (wflag) {
+ fd = open(tf_name, O_RDWR, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+ }
+ /*
+ * Otherwise "wflag" is not set and the ticket file should be opened
+ * for read-only operations and locked for shared access.
+ */
+
+ fd = open(tf_name, O_RDONLY, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pname() reads the principal's name from the ticket file. It
+ * should only be called after tf_init() has been called. The
+ * principal's name is filled into the "p" parameter. If all goes well,
+ * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is
+ * returned. If the name was null, or EOF was encountered, or the name
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+ */
+
+tf_get_pname(p)
+ char *p;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pname called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pinst() reads the principal's instance from a ticket file.
+ * It should only be called after tf_init() and tf_get_pname() have been
+ * called. The instance is filled into the "inst" parameter. If all
+ * goes well, KSUCCESS is returned. If tf_init() wasn't called,
+ * TKT_FIL_INI is returned. If EOF was encountered, or the instance
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the
+ * instance may be null.
+ */
+
+tf_get_pinst(inst)
+ char *inst;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pinst called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(inst, INST_SZ) < 1)
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills
+ * in the given structure "c". It should only be called after tf_init(),
+ * tf_get_pname(), and tf_get_pinst() have been called. If all goes well,
+ * KSUCCESS is returned. Possible error codes are:
+ *
+ * TKT_FIL_INI - tf_init wasn't called first
+ * TKT_FIL_FMT - bad format
+ * EOF - end of file encountered
+ */
+
+tf_get_cred(c)
+ CREDENTIALS *c;
+{
+ KTEXT ticket = &c->ticket_st; /* pointer to ticket */
+ int k_errno;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
+ switch (k_errno) {
+ case TOO_BIG:
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if (
+ tf_read((char *) (c->session), KEY_SZ) < 1 ||
+ tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
+ tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 ||
+ tf_read((char *) &(ticket->length), sizeof(ticket->length))
+ < 1 ||
+ /* don't try to read a silly amount into ticket->dat */
+ ticket->length > MAX_KTXT_LEN ||
+ tf_read((char *) (ticket->dat), ticket->length) < 1 ||
+ tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
+ ) {
+ tf_close();
+ return TKT_FIL_FMT;
+ }
+#ifdef TKT_SHMEM
+ bcopy(tmp_shm_addr,c->session,KEY_SZ);
+ tmp_shm_addr += KEY_SZ;
+#endif /* TKT_SHMEM */
+ return KSUCCESS;
+}
+
+/*
+ * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is
+ * not a valid file descriptor, it just returns. It also clears the
+ * buffer used to read tickets.
+ *
+ * The return value is not defined.
+ */
+
+tf_close()
+{
+ if (!(fd < 0)) {
+#ifdef TKT_SHMEM
+ if (shmdt(krb_shm_addr)) {
+ /* what kind of error? */
+ if (krb_debug)
+ fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno);
+ } else {
+ krb_shm_addr = 0;
+ }
+#endif TKT_SHMEM
+ (void) flock(fd, LOCK_UN);
+ (void) close(fd);
+ fd = -1; /* see declaration of fd above */
+ }
+ bzero(tfbfr, sizeof(tfbfr));
+}
+
+/*
+ * tf_gets() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until either it has read "n" characters,
+ * or until it reads a null byte. When finished, what has been read exists
+ * in "s". If it encounters EOF or an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read (including null terminator)
+ * when all goes well
+ *
+ * 0 end of file or read error
+ *
+ * TOO_BIG if "count" characters are read and no null is
+ * encountered. This is an indication that the ticket
+ * file is seriously ill.
+ */
+
+static
+tf_gets(s, n)
+ register char *s;
+{
+ register count;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_gets called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ for (count = n - 1; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s = tfbfr[curpos++];
+ if (*s++ == '\0')
+ return (n - count);
+ }
+ tf_close();
+ return TOO_BIG;
+}
+
+/*
+ * tf_read() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until "n" bytes have been read. When
+ * finished, what has been read exists in "s". If it encounters EOF or
+ * an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read when all goes well
+ *
+ * 0 on end of file or read error
+ */
+
+static
+tf_read(s, n)
+ register char *s;
+ register n;
+{
+ register count;
+
+ for (count = n; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s++ = tfbfr[curpos++];
+ }
+ return n;
+}
+
+char *tkt_string();
+
+/*
+ * tf_save_cred() appends an incoming ticket to the end of the ticket
+ * file. You must call tf_init() before calling tf_save_cred().
+ *
+ * The "service", "instance", and "realm" arguments specify the
+ * server's name; "session" contains the session key to be used with
+ * the ticket; "kvno" is the server key version number in which the
+ * ticket is encrypted, "ticket" contains the actual ticket, and
+ * "issue_date" is the time the ticket was requested (local host's time).
+ *
+ * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't
+ * called previously, and KFAILURE for anything else that went wrong.
+ */
+
+tf_save_cred(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+
+ off_t lseek();
+ int count; /* count for write */
+#ifdef TKT_SHMEM
+ int *skey_check;
+#endif /* TKT_SHMEM */
+
+ if (fd < 0) { /* fd is ticket file as set by tf_init */
+ if (krb_debug)
+ fprintf(stderr, "tf_save_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ /* Find the end of the ticket file */
+ (void) lseek(fd, 0L, 2);
+#ifdef TKT_SHMEM
+ /* scan to end of existing keys: pick first 'empty' slot.
+ we assume that no real keys will be completely zero (it's a weak
+ key under DES) */
+
+ skey_check = (int *) krb_shm_addr;
+
+ while (*skey_check && *(skey_check+1))
+ skey_check += 2;
+ tmp_shm_addr = (char *)skey_check;
+#endif /* TKT_SHMEM */
+
+ /* Write the ticket and associated data */
+ /* Service */
+ count = strlen(service) + 1;
+ if (write(fd, service, count) != count)
+ goto bad;
+ /* Instance */
+ count = strlen(instance) + 1;
+ if (write(fd, instance, count) != count)
+ goto bad;
+ /* Realm */
+ count = strlen(realm) + 1;
+ if (write(fd, realm, count) != count)
+ goto bad;
+ /* Session key */
+#ifdef TKT_SHMEM
+ bcopy(session,tmp_shm_addr,8);
+ tmp_shm_addr+=8;
+ if (write(fd,krb_dummy_skey,8) != 8)
+ goto bad;
+#else /* ! TKT_SHMEM */
+ if (write(fd, (char *) session, 8) != 8)
+ goto bad;
+#endif /* TKT_SHMEM */
+ /* Lifetime */
+ if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Key vno */
+ if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Tkt length */
+ if (write(fd, (char *) &(ticket->length), sizeof(int)) !=
+ sizeof(int))
+ goto bad;
+ /* Ticket */
+ count = ticket->length;
+ if (write(fd, (char *) (ticket->dat), count) != count)
+ goto bad;
+ /* Issue date */
+ if (write(fd, (char *) &issue_date, sizeof(long))
+ != sizeof(long))
+ goto bad;
+
+ /* Actually, we should check each write for success */
+ return (KSUCCESS);
+bad:
+ return (KFAILURE);
+}
diff --git a/eBones/krb/tkt_string.c b/eBones/krb/tkt_string.c
new file mode 100644
index 0000000..ba22db8
--- /dev/null
+++ b/eBones/krb/tkt_string.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $
+ * $Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <krb.h>
+#include <string.h>
+#include <sys/param.h>
+
+char *getenv();
+
+/*
+ * This routine is used to generate the name of the file that holds
+ * the user's cache of server tickets and associated session keys.
+ *
+ * If it is set, krb_ticket_string contains the ticket file name.
+ * Otherwise, the filename is constructed as follows:
+ *
+ * If it is set, the environment variable "KRBTKFILE" will be used as
+ * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and
+ * the user's uid are concatenated to produce the ticket file name
+ * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket
+ * file name is returned.
+ */
+
+static char krb_ticket_string[MAXPATHLEN] = "";
+
+char *tkt_string()
+{
+ char *env;
+ uid_t getuid();
+
+ if (!*krb_ticket_string) {
+ if (env = getenv("KRBTKFILE")) {
+ (void) strncpy(krb_ticket_string, env,
+ sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+ } else {
+ /* 32 bits of signed integer will always fit in 11 characters
+ (including the sign), so no need to worry about overflow */
+ (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,getuid());
+ }
+ }
+ return krb_ticket_string;
+}
+
+/*
+ * This routine is used to set the name of the file that holds the user's
+ * cache of server tickets and associated session keys.
+ *
+ * The value passed in is copied into local storage.
+ *
+ * NOTE: This routine should be called during initialization, before other
+ * Kerberos routines are called; otherwise tkt_string() above may be called
+ * and return an undesired ticket file name until this routine is called.
+ */
+
+void
+krb_set_tkt_string(val)
+char *val;
+{
+
+ (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+
+ return;
+}
diff --git a/eBones/krb/util.c b/eBones/krb/util.c
new file mode 100644
index 0000000..8e48557
--- /dev/null
+++ b/eBones/krb/util.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Miscellaneous debug printing utilities
+ *
+ * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $
+ * $Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <des.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Print some of the contents of the given authenticator structure
+ * (AUTH_DAT defined in "krb.h"). Fields printed are:
+ *
+ * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session
+ */
+
+ad_print(x)
+AUTH_DAT *x;
+{
+ struct in_addr in;
+
+ /* Print the contents of an auth_dat struct. */
+ in.s_addr = x->address;
+ printf("\n%s %s %s %s flags %u cksum 0x%X\n\ttkt_tm 0x%X sess_key",
+ x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags,
+ x->checksum, x->time_sec);
+
+ printf("[8] =");
+#ifdef NOENCRYPTION
+ placebo_cblock_print(x->session);
+#else
+ des_cblock_print_file(x->session,stdout);
+#endif
+ /* skip reply for now */
+}
+
+/*
+ * Print in hex the 8 bytes of the given session key.
+ *
+ * Printed format is: " 0x { x, x, x, x, x, x, x, x }"
+ */
+
+#ifdef NOENCRYPTION
+placebo_cblock_print(x)
+ des_cblock x;
+{
+ unsigned char *y = (unsigned char *) x;
+ register int i = 0;
+
+ printf(" 0x { ");
+
+ while (i++ <8) {
+ printf("%x",*y++);
+ if (i<8) printf(", ");
+ }
+ printf(" }");
+}
+#endif
OpenPOWER on IntegriCloud