diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1995-12-14 06:52:55 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1995-12-14 06:52:55 +0000 |
commit | 8cf1f2a33575f93a2a1411591dea02dadfff25a0 (patch) | |
tree | 546551ebd40f0dfbbb6016a6028d467641b4ed8b /kerberosIV/krb | |
parent | 02a248da23b192dd04bdb0fe2d61202086e9ceb3 (diff) |
Kerberos IV code, based on a merge of fixed code from KTH and original
4.4BSD Lite code (international edition). Provides all functionality
from the original 4.4BSD code plus standard Kerberos elements that were
omitted in the 4.4BSD code.
Diffstat (limited to 'kerberosIV/krb')
69 files changed, 10636 insertions, 0 deletions
diff --git a/kerberosIV/krb/Makefile b/kerberosIV/krb/Makefile new file mode 100644 index 00000000000..80fc074bfae --- /dev/null +++ b/kerberosIV/krb/Makefile @@ -0,0 +1,42 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 + +LIB= krb +CFLAGS+=-I${.CURDIR} +SRCS= cr_err_reply.c create_auth_reply.c create_ciph.c \ + create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.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_localtime.c klog.c \ + kname_parse.c kntoln.c kparse.c krb_equiv.c krb_err.c krb_err_txt.c \ + krb_get_in_tkt.c kuserok.c lifetime.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 str2key.c tf_util.c tkt_string.c +MAN= kerberos.3 krb_realmofhost.3 krb_sendauth.3 krb_set_tkt_string.3 \ + kuserok.3 tf_util.3 +MLINKS+=kerberos.3 krb_mk_req.3 kerberos.3 krb_rd_req.3 kerberos.3 krb_kntoln.3 \ + kerberos.3 krb_set_key.3 kerberos.3 krb_get_cred.3 kerberos.3 krb_mk_priv.3 \ + kerberos.3 krb_rd_priv.3 kerberos.3 krb_mk_safe.3 kerberos.3 krb_rd_safe.3 \ + kerberos.3 krb_mk_err.3 kerberos.3 krb_rd_err.3 kerberos.3 krb_ck_repl.3 +MLINKS+=krb_realmofhost.3 krb_get_phost.3 krb_realmofhost.3 krb_get_krbhst.3 \ + krb_realmofhost.3 krb_get_admhst.3 krb_realmofhost.3 krb_get_lrealm.3 +MLINKS+=krb_sendauth.3 krb_recvauth.3 krb_sendauth.3 krb_net_write.3 \ + krb_sendauth.3 krb_net_read.3 +MLINKS+=tf_util.3 tf_init.3 tf_util.3 tf_get_pname.3 tf_util.3 tf_get_pinst.3 \ + tf_util.3 tf_get_cred.3 tf_util.3 tf_close.3 + +LDADD+= ${COM_ERR} +CLEANFILES+= krb_err.c krb_err.h + +krb_err.c krb_err.h: krb_err.et + test -e krb_err.et || ln -s ${.CURDIR}/krb_err.et . + ${COMPILE_ET} krb_err.et + -test -h krb_err.et && rm krb_err.et + +beforeinstall: + -cd ${.OBJDIR}; cmp -s krb_err.h ${DESTDIR}/usr/include/kerberosIV/krb_err.h || \ + install -c -o ${BINOWN} -g ${BINGRP} -m 444 krb_err.h ${DESTDIR}/usr/include/kerberosIV + +.include <bsd.lib.mk> diff --git a/kerberosIV/krb/cr_err_reply.c b/kerberosIV/krb/cr_err_reply.c new file mode 100644 index 00000000000..8feaa6544e2 --- /dev/null +++ b/kerberosIV/krb/cr_err_reply.c @@ -0,0 +1,117 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/cr_err_reply.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * req_act_vno used to be defined as an extern ("defined in server"). + * However, that does noone anything good, so we define our own so + * that the shared libraries do not turn up with an undefined variable! + */ +static int my_req_act_vno = KRB_PROT_VERSION; + +/* + * This routine is used by the Kerberos authentication server to + * create an error reply packet to send back to its client. + * + * It takes a pointer to the packet to be built, the name, instance, + * and realm of the principal, the client's timestamp, an error code + * and an error string as arguments. Its return value is undefined. + * + * The packet is built in the following format: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char req_ack_vno protocol version number + * + * unsigned char AUTH_MSG_ERR_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned long e error code + * + * string e_string error text + */ + +void +cr_err_reply(pkt, pname, pinst, prealm, time_ws, e, e_string) + KTEXT pkt; + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + u_int32_t time_ws; /* Workstation time */ + u_int32_t e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *v = (u_char *) pkt->dat; /* Prot vers number */ + u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */ + + /* Create fixed part of packet */ + *v = (unsigned char) my_req_act_vno; /* KRB_PROT_VERSION; */ + *t = (unsigned char) AUTH_MSG_ERR_REPLY; + *t |= HOST_BYTE_ORDER; + + if (pname == 0) + pname = ""; + if (pinst == 0) + pinst = ""; + if (prealm == 0) + prealm = ""; + + /* 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); + /* ws timestamp */ + bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err code */ + bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err text */ + (void) strcpy((char *)(pkt->dat+pkt->length),e_string); + pkt->length += 1 + strlen(e_string); + + /* And return */ + return; +} diff --git a/kerberosIV/krb/create_auth_reply.c b/kerberosIV/krb/create_auth_reply.c new file mode 100644 index 00000000000..80169848cfe --- /dev/null +++ b/kerberosIV/krb/create_auth_reply.c @@ -0,0 +1,128 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/create_auth_reply.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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 */ + int32_t time_ws; /* Workstation time */ + int n; /* Number of tickets */ + u_int32_t 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/kerberosIV/krb/create_ciph.c b/kerberosIV/krb/create_ciph.c new file mode 100644 index 00000000000..4bf44f953d9 --- /dev/null +++ b/kerberosIV/krb/create_ciph.c @@ -0,0 +1,122 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/create_ciph.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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 + * + */ + +int +create_ciph(c, session, service, instance, realm, + life, kvno, tkt, kdc_time, key) + KTEXT c; /* Text block to hold ciphertext */ + unsigned char *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 */ + u_int32_t life; /* Lifetime of the ticket */ + int kvno; /* Key version number for service */ + KTEXT tkt; /* The ticket for the service */ + u_int32_t kdc_time; /* KDC time */ + des_cblock *key; /* Key to encrypt ciphertext with */ +{ + char *ptr; + des_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 + des_key_sched(key,key_s); + des_pcbc_encrypt((des_cblock *)c->dat,(des_cblock *)c->dat,(long) c->length,key_s, + key, DES_ENCRYPT); +#endif /* NOENCRYPTION */ + + return(KSUCCESS); +} diff --git a/kerberosIV/krb/create_death_packet.c b/kerberosIV/krb/create_death_packet.c new file mode 100644 index 00000000000..f7333097513 --- /dev/null +++ b/kerberosIV/krb/create_death_packet.c @@ -0,0 +1,75 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/create_death_packet.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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/kerberosIV/krb/create_ticket.c b/kerberosIV/krb/create_ticket.c new file mode 100644 index 00000000000..944007c9e7a --- /dev/null +++ b/kerberosIV/krb/create_ticket.c @@ -0,0 +1,141 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/create_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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 */ + int32_t paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + int16_t life; /* Lifetime of the ticket */ + int32_t time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + des_cblock *key; /* Service's secret key */ +{ + des_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 + des_key_sched(key,key_s); + des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length, + key_s,key, DES_ENCRYPT); +#endif + return 0; +} diff --git a/kerberosIV/krb/debug_decl.c b/kerberosIV/krb/debug_decl.c new file mode 100644 index 00000000000..5489acd99cb --- /dev/null +++ b/kerberosIV/krb/debug_decl.c @@ -0,0 +1,33 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/debug_decl.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* Declare global debugging variables. */ + +int krb_ap_req_debug = 0; +int krb_debug = 0; diff --git a/kerberosIV/krb/decomp_ticket.c b/kerberosIV/krb/decomp_ticket.c new file mode 100644 index 00000000000..00b95910230 --- /dev/null +++ b/kerberosIV/krb/decomp_ticket.c @@ -0,0 +1,134 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/decomp_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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 */ + u_int32_t *paddress; /* Net address of entity + * requesting ticket */ + unsigned char *session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + u_int32_t *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + des_cblock *key; /* Service's secret key + * (to decrypt the ticket) */ + struct des_ks_struct *key_s; /* The precomputed key schedule */ +{ + static int tkt_swap_bytes; + unsigned char *uptr; + char *ptr = (char *)tkt->dat; + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length, + key_s,key, DES_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/kerberosIV/krb/dest_tkt.c b/kerberosIV/krb/dest_tkt.c new file mode 100644 index 00000000000..2386a5afdc9 --- /dev/null +++ b/kerberosIV/krb/dest_tkt.c @@ -0,0 +1,100 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/dest_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif + +/* + * 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". + */ + +int +dest_tkt() +{ + char *file = TKT_FILE; + int i,fd; + 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/kerberosIV/krb/extract_ticket.c b/kerberosIV/krb/extract_ticket.c new file mode 100644 index 00000000000..7a32e712edf --- /dev/null +++ b/kerberosIV/krb/extract_ticket.c @@ -0,0 +1,71 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/extract_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +void +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 = (unsigned char) *(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/kerberosIV/krb/fgetst.c b/kerberosIV/krb/fgetst.c new file mode 100644 index 00000000000..dfc268fb3f2 --- /dev/null +++ b/kerberosIV/krb/fgetst.c @@ -0,0 +1,55 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/fgetst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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/kerberosIV/krb/get_ad_tkt.c b/kerberosIV/krb/get_ad_tkt.c new file mode 100644 index 00000000000..7250b443fd1 --- /dev/null +++ b/kerberosIV/krb/get_ad_tkt.c @@ -0,0 +1,278 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_ad_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +static 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. + */ + +static int +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); +} + +/* use the bsd time.h struct defs for PC too! */ +#include <sys/time.h> +#include <sys/types.h> + +static struct timeval tt_local = { 0, 0 }; +static 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. + */ + +int +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 */ + des_cblock ses; /* Session key for tkt */ + CREDENTIALS cr; + int kvno; /* Kvno for session key */ + char lrealm[REALM_SZ]; + des_cblock key; /* Key for decrypting cipher */ + des_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 + /* Attempt to decrypt it */ + + des_key_sched(&cr.session,key_s); + if (krb_debug) printf("About to do decryption ..."); + des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)cip->dat, + (long) cip->length,key_s,&cr.session,0); +#endif /* !NOENCRYPTION */ + /* 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 char) 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/kerberosIV/krb/get_admhst.c b/kerberosIV/krb/get_admhst.c new file mode 100644 index 00000000000..cda70787a75 --- /dev/null +++ b/kerberosIV/krb/get_admhst.c @@ -0,0 +1,98 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_admhst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"r")) == NULL) + return(KFAILURE); + } + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + /* error reading */ + (void) fclose(cnffile); + return(KFAILURE); + } + if (!strchr(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/kerberosIV/krb/get_cred.c b/kerberosIV/krb/get_cred.c new file mode 100644 index 00000000000..2882de597ad --- /dev/null +++ b/kerberosIV/krb/get_cred.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_cred.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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/kerberosIV/krb/get_in_tkt.c b/kerberosIV/krb/get_in_tkt.c new file mode 100644 index 00000000000..9b3741efd6b --- /dev/null +++ b/kerberosIV/krb/get_in_tkt.c @@ -0,0 +1,319 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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; + char *instance; + char *realm; + char *passwd; + des_cblock *key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else + if (passwd) + des_string_to_key(passwd,key); + else + des_read_password(key,"Password: ",0); +#endif + return (0); +} + +/*ARGSUSED */ +static int +afs_passwd_to_key(user, instance, realm, passwd, key) + char *user; + char *instance; + char *realm; + char *passwd; + des_cblock *key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else /* Do encyryption */ + if (passwd) + afs_string_to_key(passwd, realm, key); + else { + des_read_password(key, "Password: ", 0); + } +#endif /* NOENCRYPTION */ + 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. + */ + +int +krb_get_pw_in_tkt(user, instance, realm, service, sinstance, life, password) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + char *password; +{ + char pword[100]; /* storage for the password */ + int code; + + /* Only request password once! */ + if (!password) { + if (des_read_pw_string(pword, sizeof(pword)-1, "Password: ", 0)) + pword[0] = '\0'; /* something wrong */ + password = pword; + } + + code = krb_get_in_tkt(user,instance,realm,service,sinstance,life, + passwd_to_key, NULL, password); + if (code != INTK_BADPW) + goto done; + + code = krb_get_in_tkt(user,instance,realm,service,sinstance,life, + afs_passwd_to_key, NULL, password); + if (code != INTK_BADPW) + goto done; + + done: + if (password == pword) + bzero(pword, sizeof(pword)); + return(code); +} + +#ifdef NOENCRYPTION +/* + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_in_tkt.c,v $ + * $Author: tholo $ + * + * 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: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_in_tkt.c,v 1.1 1995/12/14 06:52:39 tholo Exp $"; +#endif /* lint */ + +#include <des.h> +#include "conf.h" + +#include <stdio.h> +#include <strings.h> +#include <sys/ioctl.h> +#include <signal.h> +#include <setjmp.h> + +static jmp_buf env; + +static void sig_restore(); +static push_signals(), pop_signals(); +int placebo_read_pw_string(); + +/*** Routines ****************************************************** */ +int +placebo_read_password(k,prompt,verify) + des_cblock *k; + char *prompt; + int verify; +{ + int ok; + char key_string[BUFSIZ]; + + if (setjmp(env)) { + ok = -1; + goto lose; + } + + 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; + + jmp_buf old_env; + struct sgttyb tty_state; + char key_string[BUFSIZ]; + + if (max > BUFSIZ) { + return -1; + } + + 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; + while (!ok) { + printf(prompt); + fflush(stdout); + if (!fgets(s, max, stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(s, '\n'))) + *ptr = '\0'; + if (verify) { + printf("\nVerifying, please re-enter %s",prompt); + fflush(stdout); + if (!fgets(key_string, sizeof(key_string), stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(key_string, '\n'))) + *ptr = '\0'; + if (strcmp(s,key_string)) { + printf("\n\07\07Mismatch - try again\n"); + fflush(stdout); + continue; + } + } + ok = 1; + } + +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)); + if (verify) + bzero(key_string, sizeof (key_string)); + s[max-1] = 0; /* force termination */ + return !ok; /* return nonzero if not okay */ +} + +/* + * this can be static since we should never have more than + * one set saved.... + */ +static RETSIGTYPE (*old_sigfunc[NSIG])(); + +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 /* NOENCRYPTION */ diff --git a/kerberosIV/krb/get_krbhst.c b/kerberosIV/krb/get_krbhst.c new file mode 100644 index 00000000000..9d396af4815 --- /dev/null +++ b/kerberosIV/krb/get_krbhst.c @@ -0,0 +1,103 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_krbhst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"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/kerberosIV/krb/get_krbrlm.c b/kerberosIV/krb/get_krbrlm.c new file mode 100644 index 00000000000..a3a9a625833 --- /dev/null +++ b/kerberosIV/krb/get_krbrlm.c @@ -0,0 +1,78 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_krbrlm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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(). + */ + +int +krb_get_lrealm(r, n) + char *r; + int n; +{ + FILE *cnffile; + + if (n > 1) + return(KFAILURE); /* Temporary restriction */ + + if ((cnffile = fopen(KRB_CONF, "r")) == NULL) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"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/kerberosIV/krb/get_phost.c b/kerberosIV/krb/get_phost.c new file mode 100644 index 00000000000..8c6c6caef9a --- /dev/null +++ b/kerberosIV/krb/get_phost.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_phost.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define USE_FULL_HOST_NAME 0 + +#include <ctype.h> +#include <netdb.h> + +/* + * 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 ) { +#if USE_FULL_HOST_NAME + char *p; +#else /* USE_FULL_HOST_NAME */ + char *p = strchr( h->h_name, '.' ); + if (p) + *p = 0; +#endif /* USE_FULL_HOST_NAME */ + p = phost = h->h_name; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/kerberosIV/krb/get_pw_tkt.c b/kerberosIV/krb/get_pw_tkt.c new file mode 100644 index 00000000000..0e459a3c6d7 --- /dev/null +++ b/kerberosIV/krb/get_pw_tkt.c @@ -0,0 +1,86 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_pw_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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/kerberosIV/krb/get_request.c b/kerberosIV/krb/get_request.c new file mode 100644 index 00000000000..ba0e0daaa67 --- /dev/null +++ b/kerberosIV/krb/get_request.c @@ -0,0 +1,66 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_request.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +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/kerberosIV/krb/get_svc_in_tkt.c b/kerberosIV/krb/get_svc_in_tkt.c new file mode 100644 index 00000000000..57f1942cbb9 --- /dev/null +++ b/kerberosIV/krb/get_svc_in_tkt.c @@ -0,0 +1,92 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_svc_in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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; + char *instance; + char *realm; + char *srvtab; + unsigned char *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. + */ + +int +krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + char *srvtab; +{ + return(krb_get_in_tkt(user, instance, realm, service, sinstance, + life, srvtab_to_key, NULL, srvtab)); +} diff --git a/kerberosIV/krb/get_tf_fullname.c b/kerberosIV/krb/get_tf_fullname.c new file mode 100644 index 00000000000..25750e9e982 --- /dev/null +++ b/kerberosIV/krb/get_tf_fullname.c @@ -0,0 +1,80 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_tf_fullname.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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(). + */ + +int +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/kerberosIV/krb/get_tf_realm.c b/kerberosIV/krb/get_tf_realm.c new file mode 100644 index 00000000000..04b19894ac2 --- /dev/null +++ b/kerberosIV/krb/get_tf_realm.c @@ -0,0 +1,49 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/get_tf_realm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + * + */ + +int +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/kerberosIV/krb/getrealm.c b/kerberosIV/krb/getrealm.c new file mode 100644 index 00000000000..45f6e260b11 --- /dev/null +++ b/kerberosIV/krb/getrealm.c @@ -0,0 +1,132 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/getrealm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define MATCH_SUBDOMAINS 0 + +/* 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 = strchr(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) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.realms", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((trans_file = fopen(tbuf,"r")) == NULL) + return(ret_realm); /* krb_errno = KRB_NO_TRANS */ + } + 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) { +#if MATCH_SUBDOMAINS + char *cp; + for (cp = domain; cp != NULL; cp = strchr(cp+1, '.')) { + /* this is a domain match */ + if (!strcasecmp(trans_host, cp)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } + } +#else /* MATCH_SUBDOMAINS */ + /* this is a domain match */ + if (!strcasecmp(trans_host, domain)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } +#endif /* MATCH_SUBDOMAINS */ + } + } +} diff --git a/kerberosIV/krb/getst.c b/kerberosIV/krb/getst.c new file mode 100644 index 00000000000..a7b73af0947 --- /dev/null +++ b/kerberosIV/krb/getst.c @@ -0,0 +1,54 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/getst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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. + */ + +int +getst(fd, s, n) + int fd; + register char *s; + int n; +{ + register count = n; + while (read(fd, s, 1) > 0 && --count) + if (*s++ == '\0') + return (n - count); + *s = '\0'; + return (n - count); +} diff --git a/kerberosIV/krb/in_tkt.c b/kerberosIV/krb/in_tkt.c new file mode 100644 index 00000000000..0fda5ab7c2e --- /dev/null +++ b/kerberosIV/krb/in_tkt.c @@ -0,0 +1,149 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif + +/* + * 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. + */ + +int +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 || !(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",(int)metoo,(int)me); + } + if ((tktfile = creat(file,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",(int)me,(int)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/kerberosIV/krb/k_localtime.c b/kerberosIV/krb/k_localtime.c new file mode 100644 index 00000000000..db54f81f681 --- /dev/null +++ b/kerberosIV/krb/k_localtime.c @@ -0,0 +1,35 @@ +/* + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/k_localtime.c,v $ + * + * $Locker: $ + */ + +/* + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include <kerberosIV/krb.h> + +#include <time.h> + +struct tm * +k_localtime(tp) + u_int32_t *tp; +{ + time_t t; + t = *tp; + return localtime(&t); +} diff --git a/kerberosIV/krb/kerberos.3 b/kerberosIV/krb/kerberos.3 new file mode 100644 index 00000000000..4434508dc59 --- /dev/null +++ b/kerberosIV/krb/kerberos.3 @@ -0,0 +1,462 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kerberos.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kerberos.3,v 1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred, +krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err, +krb_rd_err, krb_ck_repl \- Kerberos authentication library +.SH SYNOPSIS +.nf +.nj +.ft B +#include <des.h> +#include <krb.h> +.PP +.ft B +extern char *krb_err_txt[]; +.PP +.ft B +int krb_mk_req(authent,service,instance,realm,checksum) +KTEXT authent; +char *service; +char *instance; +char *realm; +u_long checksum; +.PP +.ft B +int krb_rd_req(authent,service,instance,from_addr,ad,fn) +KTEXT authent; +char *service; +char *instance; +u_long from_addr; +AUTH_DAT *ad; +char *fn; +.PP +.ft B +int krb_kntoln(ad,lname) +AUTH_DAT *ad; +char *lname; +.PP +.ft B +int krb_set_key(key,cvt) +char *key; +int cvt; +.PP +.ft B +int krb_get_cred(service,instance,realm,c) +char *service; +char *instance; +char *realm; +CREDENTIALS *c; +.PP +.ft B +long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver) +u_char *in; +u_char *out; +u_long in_length; +des_cblock key; +des_key_schedule schedule; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +.PP +.ft B +long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data) +u_char *in; +u_long in_length; +Key_schedule schedule; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg_data; +.PP +.ft B +long krb_mk_safe(in,out,in_length,key,sender,receiver) +u_char *in; +u_char *out; +u_long in_length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +.PP +.ft B +long krb_rd_safe(in,length,key,sender,receiver,msg_data) +u_char *in; +u_long length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg_data; +.PP +.ft B +long krb_mk_err(out,code,string) +u_char *out; +long code; +char *string; +.PP +.ft B +long krb_rd_err(in,length,code,msg_data) +u_char *in; +u_long length; +long code; +MSG_DAT *msg_data; +.fi +.ft R +.SH DESCRIPTION +This library supports network authentication and various related +operations. The library contains many routines beyond those described +in this man page, but they are not intended to be used directly. +Instead, they are called by the routines that are described, the +authentication server and the login program. +.PP +.I krb_err_txt[] +contains text string descriptions of various Kerberos error codes returned +by some of the routines below. +.PP +.I krb_mk_req +takes a pointer to a text structure in which an authenticator is to be +built. It also takes the name, instance, and realm of the service to be +used and an optional checksum. It is up to the application to decide +how to generate the checksum. +.I krb_mk_req +then retrieves a ticket for the desired service and creates an +authenticator. The authenticator is built in +.I authent +and is accessible +to the calling procedure. +.PP +It is up to the application to get the authenticator to the service +where it will be read by +.I krb_rd_req. +Unless an attacker posesses the session key contained in the ticket, it +will be unable to modify the authenticator. Thus, the checksum can be +used to verify the authenticity of the other data that will pass through +a connection. +.PP +.I krb_rd_req +takes an authenticator of type +.B KTEXT, +a service name, an instance, the address of the +host originating the request, and a pointer to a structure of type +.B AUTH_DAT +which is filled in with information obtained from the authenticator. +It also optionally takes the name of the file in which it will find the +secret key(s) for the service. +If the supplied +.I instance +contains "*", then the first service key with the same service name +found in the service key file will be used, and the +.I instance +argument will be filled in with the chosen instance. This means that +the caller must provide space for such an instance name. +.PP +It is used to find out information about the principal when a request +has been made to a service. It is up to the application protocol to get +the authenticator from the client to the service. The authenticator is +then passed to +.I krb_rd_req +to extract the desired information. +.PP +.I krb_rd_req +returns zero (RD_AP_OK) upon successful authentication. If a packet was +forged, modified, or replayed, authentication will fail. If the +authentication fails, a non-zero value is returned indicating the +particular problem encountered. See +.I krb.h +for the list of error codes. +.PP +If the last argument is the null string (""), krb_rd_req will use the +file /etc/srvtab to find its keys. If the last argument is NULL, it +will assume that the key has been set by +.I krb_set_key +and will not bother looking further. +.PP +.I krb_kntoln +converts a Kerberos name to a local name. It takes a structure +of type AUTH_DAT and uses the name and instance to look in the database +/etc/aname to find the corresponding local name. The local name is +returned and can be used by an application to change uids, directories, +or other parameters. It is not an integral part of Kerberos, but is +instead provided to support the use of Kerberos in existing utilities. +.PP +.I krb_set_key +takes as an argument a des key. It then creates +a key schedule from it and saves the original key to be used as an +initialization vector. +It is used to set the server's key which +must be used to decrypt tickets. +.PP +If called with a non-zero second argument, +.I krb_set_key +will first convert the input from a string of arbitrary length to a DES +key by encrypting it with a one-way function. +.PP +In most cases it should not be necessary to call +.I krb_set_key. +The necessary keys will usually be obtained and set inside +.I krb_rd_req. krb_set_key +is provided for those applications that do not wish to place the +application keys on disk. +.PP +.I krb_get_cred +searches the caller's ticket file for a ticket for the given service, instance, +and realm; and, if a ticket is found, fills in the given CREDENTIALS structure +with the ticket information. +.PP +If the ticket was found, +.I krb_get_cred +returns GC_OK. +If the ticket file can't be found, can't be read, doesn't belong to +the user (other than root), isn't a regular file, or is in the wrong +mode, the error GC_TKFIL is returned. +.PP +.I krb_mk_priv +creates an encrypted, authenticated +message from any arbitrary application data, pointed to by +.I in +and +.I in_length +bytes long. +The private session key, pointed to by +.I key +and the key schedule, +.I schedule, +are used to encrypt the data and some header information using +.I pcbc_encrypt. +.I sender +and +.I receiver +point to the Internet address of the two parties. +In addition to providing privacy, this protocol message protects +against modifications, insertions or replays. The encapsulated message and +header are placed in the area pointed to by +.I out +and the routine returns the length of the output, or -1 indicating +an error. +.PP +.I krb_rd_priv +decrypts and authenticates a received +.I krb_mk_priv +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +The private session key, pointed to by +.I key, +and the key schedule, +.I schedule, +are used to decrypt and verify the received message. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h. +The routine fills in the +.I app_data +field with a pointer to the decrypted application data, +.I app_length +with the length of the +.I app_data +field, +.I time_sec +and +.I time_5ms +with the timestamps in the message, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. (The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). The +.I hash +field returns a value useful as input to the +.I krb_ck_repl +routine. + +The routine returns zero if ok, or a Kerberos error code. Modified messages +and old messages cause errors, but it is up to the caller to +check the time sequence of messages, and to check against recently replayed +messages using +.I krb_ck_repl +if so desired. +.PP +.I krb_mk_safe +creates an authenticated, but unencrypted message from any arbitrary +application data, +pointed to by +.I in +and +.I in_length +bytes long. +The private session key, pointed to by +.I key, +is used to seed the +.I quad_cksum() +checksum algorithm used as part of the authentication. +.I sender +and +.I receiver +point to the Internet address of the two parties. +This message does not provide privacy, but does protect (via detection) +against modifications, insertions or replays. The encapsulated message and +header are placed in the area pointed to by +.I out +and the routine returns the length of the output, or -1 indicating +an error. +The authentication provided by this routine is not as strong as that +provided by +.I krb_mk_priv +or by computing the checksum using +.I cbc_cksum +instead, both of which authenticate via DES. +.PP + +.I krb_rd_safe +authenticates a received +.I krb_mk_safe +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +The private session key, pointed to by +.I key, +is used to seed the quad_cksum() routine as part of the authentication. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h . +The routine fills in these +.I MSG_DAT +fields: +the +.I app_data +field with a pointer to the application data, +.I app_length +with the length of the +.I app_data +field, +.I time_sec +and +.I time_5ms +with the timestamps in the message, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. +(The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). The +.I hash +field returns a value useful as input to the +.I krb_ck_repl +routine. + +The routine returns zero if ok, or a Kerberos error code. Modified messages +and old messages cause errors, but it is up to the caller to +check the time sequence of messages, and to check against recently replayed +messages using +.I krb_ck_repl +if so desired. +.PP +.I krb_mk_err +constructs an application level error message that may be used along +with +.I krb_mk_priv +or +.I krb_mk_safe. +.I out +is a pointer to the output buffer, +.I code +is an application specific error code, and +.I string +is an application specific error string. + +.PP +.I krb_rd_err +unpacks a received +.I krb_mk_err +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +.I code +is a pointer to a value to be filled in with the error +value provided by the application. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h . +The routine fills in these +.I MSG_DAT +fields: the +.I app_data +field with a pointer to the application error text, +.I app_length +with the length of the +.I app_data +field, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. (The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). + +The routine returns zero if the error message has been successfully received, +or a Kerberos error code. +.PP +The +.I KTEXT +structure is used to pass around text of varying lengths. It consists +of a buffer for the data, and a length. krb_rd_req takes an argument of this +type containing the authenticator, and krb_mk_req returns the +authenticator in a structure of this type. KTEXT itself is really a +pointer to the structure. The actual structure is of type KTEXT_ST. +.PP +The +.I AUTH_DAT +structure is filled in by krb_rd_req. It must be allocated before +calling krb_rd_req, and a pointer to it is passed. The structure is +filled in with data obtained from Kerberos. +.I MSG_DAT +structure is filled in by either krb_rd_priv, krb_rd_safe, or +krb_rd_err. It must be allocated before the call and a pointer to it +is passed. The structure is +filled in with data obtained from Kerberos. +.PP +.SH FILES +/usr/include/krb.h +.br +/usr/lib/libkrb.a +.br +/usr/include/des.h +.br +/usr/lib/libdes.a +.br +/etc/aname +.br +/etc/srvtab +.br +/tmp/tkt[uid] +.SH "SEE ALSO" +kerberos(1), des_crypt(3) +.SH DIAGNOSTICS +.SH BUGS +The caller of +.I krb_rd_req, krb_rd_priv, and krb_rd_safe +must check time order and for replay attempts. +.I krb_ck_repl +is not implemented yet. +.SH AUTHORS +Clifford Neuman, MIT Project Athena +.br +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.SH RESTRICTIONS +COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology diff --git a/kerberosIV/krb/klog.c b/kerberosIV/krb/klog.c new file mode 100644 index 00000000000..7cbd7654fae --- /dev/null +++ b/kerberosIV/krb/klog.c @@ -0,0 +1,124 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/klog.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.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; + time_t now; + char *month_sname(int n); + 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". + */ + +void +kset_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} diff --git a/kerberosIV/krb/kname_parse.c b/kerberosIV/krb/kname_parse.c new file mode 100644 index 00000000000..3acdcce0a24 --- /dev/null +++ b/kerberosIV/krb/kname_parse.c @@ -0,0 +1,262 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kname_parse.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define INSTANCE_DOTS_OK 0 + +/* 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 + +/* + * 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. + */ + +int +kname_parse(np, ip, rp, fullname) + char *np; + char *ip; + char *rp; + char *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: +#if INSTANCE_DOTS_OK + *wnext++ = c; + break; +#else /* INSTANCE_DOTS_OK */ + return KNAME_FMT; +#endif /* INSTANCE_DOTS_OK */ + /* 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. + */ + +int +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. + */ + +int +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 '.': +#if INSTANCE_DOTS_OK + break; +#else /* INSTANCE_DOTS_OK */ + return 0; +#endif /* INSTANCE_DOTS_OK */ + /* 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. + */ + +int +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/kerberosIV/krb/kntoln.c b/kerberosIV/krb/kntoln.c new file mode 100644 index 00000000000..3f4239e2703 --- /dev/null +++ b/kerberosIV/krb/kntoln.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kntoln.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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. + */ + +#include "krb_locl.h" + +int +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/kerberosIV/krb/kparse.c b/kerberosIV/krb/kparse.c new file mode 100644 index 00000000000..2a3a62e8c6d --- /dev/null +++ b/kerberosIV/krb/kparse.c @@ -0,0 +1,789 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kparse.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + * + * " <- emacs fix + */ + +#include "krb_locl.h" + +#include <kerberosIV/kparse.h> + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define MAXKEY 80 +#define MAXVALUE 80 + +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*/ + return(KV_SYNTAX); +} + +/* + * 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). + * + * " <- emacs fix + */ + +int +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. + */ +int +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. + */ +int +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/kerberosIV/krb/krb_equiv.c b/kerberosIV/krb/krb_equiv.c new file mode 100644 index 00000000000..0cc13a61a84 --- /dev/null +++ b/kerberosIV/krb/krb_equiv.c @@ -0,0 +1,80 @@ +/* + * int krb_equiv(u_int32_t ipaddr_a, u_int32_t ipaddr_b); + * + * Given two IP adresses return true if they match + * or are considered to belong to the same host. + * + * For example if /etc/krb.equiv looks like + * + * 130.237.223.3 192.16.126.3 # alv alv1 + * 130.237.223.4 192.16.126.4 # byse byse1 + * 130.237.228.152 192.16.126.9 # topsy topsy1 + * + * krb_equiv(alv, alv1) would return true but + * krb_equiv(alv, byse1) would not. + * + * A comment starts with an '#' and ends with '\n'. + * + */ +#include "krb_locl.h" + +int +krb_equiv(a, b) + u_int32_t a; + u_int32_t b; +{ +#ifdef NO_IPADDR_CHECK + return 1; +#else + + FILE *fil; + int result = 0; + char line[256]; + + if (a == b) /* trivial match */ + return 1; + + fil = fopen(KRB_EQUIV, "r"); + if (fil == NULL) /* open failed */ + return 0; + + while (fgets(line, sizeof(line)-1, fil) != NULL) /* for each line */ + { + int hit_a = 0, hit_b = 0; + char *t = line; + + /* for each item on this line */ + while (*t != 0) /* more addresses on this line? */ + if (*t == '#') /* rest is comment */ + *t = 0; + else if (isspace(*t)) /* skip space */ + t++; + else if (isdigit(*t)) /* an address? */ + { + u_int32_t tmp = inet_addr(t); + if (tmp == -1) + ; /* not an address (or broadcast) */ + else if (tmp == a) + hit_a = 1; + else if (tmp == b) + hit_b = 1; + + while (*t == '.' || isdigit(*t)) /* done with this address */ + t++; + } + else + *t = 0; /* garbage on this line, skip it */ + + /* line is now parsed, if we found 2 matches were done */ + if (hit_a && hit_b) + { + result = 1; + goto done; + } + } + + done: + fclose(fil); + return result; +#endif /* !NO_IPADDR_CHECK */ +} diff --git a/kerberosIV/krb/krb_err.et b/kerberosIV/krb/krb_err.et new file mode 100644 index 00000000000..6c7d37df89e --- /dev/null +++ b/kerberosIV/krb/krb_err.et @@ -0,0 +1,259 @@ +# Copyright 1987,1988 Massachusetts Institute of Technology +# +# For copying and distribution information, see the file +# "mit-copyright.h". +# +# $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_err.et,v $ +# $Author: tholo $ +# $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_err.et,v 1.1 1995/12/14 06:52:37 tholo 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/kerberosIV/krb/krb_err_txt.c b/kerberosIV/krb/krb_err_txt.c new file mode 100644 index 00000000000..8423d20e81a --- /dev/null +++ b/kerberosIV/krb/krb_err_txt.c @@ -0,0 +1,295 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_err_txt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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. + */ + +const 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/kerberosIV/krb/krb_get_in_tkt.c b/kerberosIV/krb/krb_get_in_tkt.c new file mode 100644 index 00000000000..1ce8c9926b7 --- /dev/null +++ b/kerberosIV/krb/krb_get_in_tkt.c @@ -0,0 +1,331 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_get_in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.h> + +int swap_bytes; + +static int +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); +} + +/* + * 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; + des_cblock key; /* Key for decrypting cipher */ + des_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 + des_key_sched(&key,key_s); + des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)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 + */ + +int +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 */ + des_cblock 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/kerberosIV/krb/krb_locl.h b/kerberosIV/krb/krb_locl.h new file mode 100644 index 00000000000..45f46bbf991 --- /dev/null +++ b/kerberosIV/krb/krb_locl.h @@ -0,0 +1,40 @@ +/* $Id: krb_locl.h,v 1.1 1995/12/14 06:52:38 tholo Exp $ */ + +#ifndef __krb_locl_h +#define __krb_locl_h + +#include <sys/cdefs.h> +#include "kerberosIV/site.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <unistd.h> +#include <sys/types.h> +#include <time.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/file.h> +#include <errno.h> + +#include <kerberosIV/krb.h> +#include <prot.h> + +/* --- */ + +/* Globals! */ +extern int krb_debug; +extern int krb_ap_req_debug; + +/* Utils */ +char *pkt_cipher __P((KTEXT)); + +int new_log __P((time_t, char *)); +char *klog (); + +char *month_sname __P((int)); +int fgetst __P((FILE *, char *, int)); + +#endif /* __krb_locl_h */ diff --git a/kerberosIV/krb/krb_realmofhost.3 b/kerberosIV/krb/krb_realmofhost.3 new file mode 100644 index 00000000000..843cf868b7c --- /dev/null +++ b/kerberosIV/krb/krb_realmofhost.3 @@ -0,0 +1,162 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_realmofhost.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_realmofhost.3,v 1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.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/kerberosIV/krb/krb_sendauth.3 b/kerberosIV/krb/krb_sendauth.3 new file mode 100644 index 00000000000..6e0d0d7a577 --- /dev/null +++ b/kerberosIV/krb/krb_sendauth.3 @@ -0,0 +1,349 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_sendauth.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_sendauth.3,v 1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1988 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.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/kerberosIV/krb/krb_set_tkt_string.3 b/kerberosIV/krb/krb_set_tkt_string.3 new file mode 100644 index 00000000000..f29a55b307d --- /dev/null +++ b/kerberosIV/krb/krb_set_tkt_string.3 @@ -0,0 +1,44 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v 1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.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/kerberosIV/krb/kuserok.3 b/kerberosIV/krb/kuserok.3 new file mode 100644 index 00000000000..26da3e732fc --- /dev/null +++ b/kerberosIV/krb/kuserok.3 @@ -0,0 +1,64 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kuserok.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kuserok.3,v 1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.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/kerberosIV/krb/kuserok.c b/kerberosIV/krb/kuserok.c new file mode 100644 index 00000000000..4b1d412fe85 --- /dev/null +++ b/kerberosIV/krb/kuserok.c @@ -0,0 +1,212 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/kuserok.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * kuserok: check if a kerberos principal has + * access to a local account + */ + +#include "krb_locl.h" + +#include <pwd.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/file.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 */ + +int +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 = strchr(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/kerberosIV/krb/lifetime.c b/kerberosIV/krb/lifetime.c new file mode 100644 index 00000000000..e022f3215bc --- /dev/null +++ b/kerberosIV/krb/lifetime.c @@ -0,0 +1,234 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/lifetime.c,v $ + * + * $Locker: $ + */ + +/*************************************************************************** + * PRE-HISTORY + * + * Revision 2.1.2.2 91/11/08 00:35:25 mja + * Lower NEVERDATE to a positive value since time values are not + * handled properly by most of the rest of the system when + * negative; add krb_life_to_atime() and krb_atime_to_life(). + * [91/11/07 22:52:50 mja] + * + * Revision 2.1.2.1 91/07/09 22:50:42 mja + * Created. + * [91/01/30 jm36@ANDREW.CMU.EDU] + * + ***************************************************************************/ + +/* + * Ticket lifetime. This defines the table used to lookup lifetime + * for the fixed part of rande of the one byte lifetime field. Values + * less than 0x80 are intrpreted as the number of 5 minute intervals. + * Values from 0x80 to 0xBF should be looked up in this table. The + * value of 0x80 is the same using both methods: 10 and two-thirds + * hours . The lifetime of 0xBF is 30 days. The intervening values + * of have a fixed ratio of roughly 1.06914. The value 0xFF is + * defined to mean a ticket has no expiration time. This should be + * used advisedly since individual servers may impose defacto + * upperbounds on ticket lifetimes. + */ + +#include "krb_locl.h" + +#define TKTLIFENUMFIXED 64 +#define TKTLIFEMINFIXED 0x80 +#define TKTLIFEMAXFIXED 0xBF +#define TKTLIFENOEXPIRE 0xFF +#define MAXTKTLIFETIME (30*24*3600) /* 30 days */ +#ifndef NEVERDATE +#define NEVERDATE ((unsigned long)0x7fffffffL) +#endif + +static const int tkt_lifetimes[TKTLIFENUMFIXED] = { + 38400, /* 10.67 hours, 0.44 days */ + 41055, /* 11.40 hours, 0.48 days */ + 43894, /* 12.19 hours, 0.51 days */ + 46929, /* 13.04 hours, 0.54 days */ + 50174, /* 13.94 hours, 0.58 days */ + 53643, /* 14.90 hours, 0.62 days */ + 57352, /* 15.93 hours, 0.66 days */ + 61318, /* 17.03 hours, 0.71 days */ + 65558, /* 18.21 hours, 0.76 days */ + 70091, /* 19.47 hours, 0.81 days */ + 74937, /* 20.82 hours, 0.87 days */ + 80119, /* 22.26 hours, 0.93 days */ + 85658, /* 23.79 hours, 0.99 days */ + 91581, /* 25.44 hours, 1.06 days */ + 97914, /* 27.20 hours, 1.13 days */ + 104684, /* 29.08 hours, 1.21 days */ + 111922, /* 31.09 hours, 1.30 days */ + 119661, /* 33.24 hours, 1.38 days */ + 127935, /* 35.54 hours, 1.48 days */ + 136781, /* 37.99 hours, 1.58 days */ + 146239, /* 40.62 hours, 1.69 days */ + 156350, /* 43.43 hours, 1.81 days */ + 167161, /* 46.43 hours, 1.93 days */ + 178720, /* 49.64 hours, 2.07 days */ + 191077, /* 53.08 hours, 2.21 days */ + 204289, /* 56.75 hours, 2.36 days */ + 218415, /* 60.67 hours, 2.53 days */ + 233517, /* 64.87 hours, 2.70 days */ + 249664, /* 69.35 hours, 2.89 days */ + 266926, /* 74.15 hours, 3.09 days */ + 285383, /* 79.27 hours, 3.30 days */ + 305116, /* 84.75 hours, 3.53 days */ + 326213, /* 90.61 hours, 3.78 days */ + 348769, /* 96.88 hours, 4.04 days */ + 372885, /* 103.58 hours, 4.32 days */ + 398668, /* 110.74 hours, 4.61 days */ + 426234, /* 118.40 hours, 4.93 days */ + 455705, /* 126.58 hours, 5.27 days */ + 487215, /* 135.34 hours, 5.64 days */ + 520904, /* 144.70 hours, 6.03 days */ + 556921, /* 154.70 hours, 6.45 days */ + 595430, /* 165.40 hours, 6.89 days */ + 636601, /* 176.83 hours, 7.37 days */ + 680618, /* 189.06 hours, 7.88 days */ + 727680, /* 202.13 hours, 8.42 days */ + 777995, /* 216.11 hours, 9.00 days */ + 831789, /* 231.05 hours, 9.63 days */ + 889303, /* 247.03 hours, 10.29 days */ + 950794, /* 264.11 hours, 11.00 days */ + 1016537, /* 282.37 hours, 11.77 days */ + 1086825, /* 301.90 hours, 12.58 days */ + 1161973, /* 322.77 hours, 13.45 days */ + 1242318, /* 345.09 hours, 14.38 days */ + 1328218, /* 368.95 hours, 15.37 days */ + 1420057, /* 394.46 hours, 16.44 days */ + 1518247, /* 421.74 hours, 17.57 days */ + 1623226, /* 450.90 hours, 18.79 days */ + 1735464, /* 482.07 hours, 20.09 days */ + 1855462, /* 515.41 hours, 21.48 days */ + 1983758, /* 551.04 hours, 22.96 days */ + 2120925, /* 589.15 hours, 24.55 days */ + 2267576, /* 629.88 hours, 26.25 days */ + 2424367, /* 673.44 hours, 28.06 days */ + 2592000}; /* 720.00 hours, 30.00 days */ + +/* + * krb_life_to_time - takes a start time and a Kerberos standard + * lifetime char and returns the corresponding end time. There are + * four simple cases to be handled. The first is a life of 0xff, + * meaning no expiration, and results in an end time of 0xffffffff. + * The second is when life is less than the values covered by the + * table. In this case, the end time is the start time plus the + * number of 5 minute intervals specified by life. The third case + * returns start plus the MAXTKTLIFETIME if life is greater than + * TKTLIFEMAXFIXED. The last case, uses the life value (minus + * TKTLIFEMINFIXED) as an index into the table to extract the lifetime + * in seconds, which is added to start to produce the end time. + */ +u_int32_t +krb_life_to_time(start, life) + u_int32_t start; + int life; +{ + life = (unsigned char) life; + if (life == TKTLIFENOEXPIRE) return NEVERDATE; + if (life < TKTLIFEMINFIXED) return start + life*5*60; + if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME; + return start + tkt_lifetimes[life - TKTLIFEMINFIXED]; +} + +/* + * krb_time_to_life - takes start and end times for the ticket and + * returns a Kerberos standard lifetime char, possibily using the + * tkt_lifetimes table for lifetimes above 127*5 minutes. First, the + * special case of (end == NEVERDATE) is handled to mean no + * expiration. Then negative lifetimes and those greater than the + * maximum ticket lifetime are rejected. Then lifetimes less than the + * first table entry are handled by rounding the requested lifetime + * *up* to the next 5 minute interval. The final step is to search + * the table for the smallest entry *greater than or equal* to the + * requested entry. + */ +int +krb_time_to_life(start, end) + u_int32_t start; + u_int32_t end; +{ + long lifetime; + int i; + + if (end >= NEVERDATE) return TKTLIFENOEXPIRE; + lifetime = end - start; + if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0; + if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60); + for (i=0; i<TKTLIFENUMFIXED; i++) { + if (lifetime <= tkt_lifetimes[i]) { + return i+TKTLIFEMINFIXED; + } + } + return 0; +} + +char * +krb_life_to_atime(life) + int life; +{ + static char atime[11+1+2+1+2+1+2+1]; + unsigned long when; + int secs, mins, hours; + + if (life == TKTLIFENOEXPIRE) + return("Forever"); + when = krb_life_to_time(0, life); + secs = when%60; + when /= 60; + mins = when%60; + when /= 60; + hours = when%24; + when /= 24; + sprintf(atime, "%d+%02d:%02d:%02d", (int)when, hours, mins, secs); + return(atime); +} + +int +krb_atime_to_life(atime) + char *atime; +{ + unsigned long when = 0; + register char *cp; + int colon = 0, plus = 0; + int n = 0; + + if (strcasecmp(atime, "forever") == 0) + return(TKTLIFENOEXPIRE); + + for (cp=atime; *cp; cp++) { + switch(*cp) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = n*10 + *cp-'0'; + break; + case '+': + plus++; + when += n; + when *= 24; + n = 0; + break; + case ':': + colon++; + when += n; + when *= 60; + n = 0; + break; + default: + break; + } + } + when += n; + if (plus == 0 && colon == 0) + return((unsigned char)when); + while (colon < 2) { + when *= 60; + colon++; + } + return(krb_time_to_life(0,when)); +} diff --git a/kerberosIV/krb/log.c b/kerberosIV/krb/log.c new file mode 100644 index 00000000000..5cea8483276 --- /dev/null +++ b/kerberosIV/krb/log.c @@ -0,0 +1,133 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/log.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.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. + */ + +/*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; + time_t 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". + */ + +void +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. + */ + +int +new_log(t, string) + time_t t; + char *string; +{ + static FILE *logfile; + + 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/kerberosIV/krb/lsb_addr_comp.h b/kerberosIV/krb/lsb_addr_comp.h new file mode 100644 index 00000000000..75a517de9cb --- /dev/null +++ b/kerberosIV/krb/lsb_addr_comp.h @@ -0,0 +1,54 @@ +/* + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/lsb_addr_comp.h,v $ + */ + +/* + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Comparison macros to emulate LSBFIRST comparison results of network + * byte-order quantities + */ + +#ifndef LSB_ADDR_COMP_DEFS +#define LSB_ADDR_COMP_DEFS + +#if BYTE_ORDER == BIG_ENDIAN + +#define u_char_comp(x,y) \ + (((x)>(y))?(1):(((x)==(y))?(0):(-1))) +/* This is gross, but... */ +#define lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y) +#define lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y) + +#define long_less_than(x,y) \ + (u_char_comp((x)[3],(y)[3])?u_char_comp((x)[3],(y)[3]): \ + (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \ + (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \ + (u_char_comp((x)[0],(y)[0]))))) +#define short_less_than(x,y) \ + (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \ + (u_char_comp((x)[0],(y)[0]))) + +#else /* !WORDS_BIGENDIAN */ + +#define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0)) +#define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0)) + +#endif /* !WORDS_BIGENDIAN */ + +#endif /* LSB_ADDR_COMP_DEFS */ diff --git a/kerberosIV/krb/mk_err.c b/kerberosIV/krb/mk_err.c new file mode 100644 index 00000000000..4c37a83430a --- /dev/null +++ b/kerberosIV/krb/mk_err.c @@ -0,0 +1,77 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/mk_err.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/types.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 + */ + +int32_t +krb_mk_err(p, e, e_string) + u_char *p; /* Where to build error packet */ + int32_t 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/kerberosIV/krb/mk_priv.c b/kerberosIV/krb/mk_priv.c new file mode 100644 index 00000000000..968ae6bc860 --- /dev/null +++ b/kerberosIV/krb/mk_priv.c @@ -0,0 +1,209 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/mk_priv.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + */ + +#include "krb_locl.h" + +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t 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 + */ + +int32_t +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_int32_t length; /* of in data */ + struct des_ks_struct *schedule; /* precomputed key schedule */ + des_cblock *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; + + /* + * 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 = des_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(des_cblock) -1)/sizeof(des_cblock)) * + sizeof(des_cblock); + /* stuff the length */ + bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length)); + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)(p-q),schedule,key, DES_ENCRYPT); +#endif /* NOENCRYPTION */ + + return (q - out + c_length); /* resulting size */ +} diff --git a/kerberosIV/krb/mk_req.c b/kerberosIV/krb/mk_req.c new file mode 100644 index 00000000000..f8c4afe38fd --- /dev/null +++ b/kerberosIV/krb/mk_req.c @@ -0,0 +1,207 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/mk_req.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.h> + +static struct timeval tv_local = { 0, 0 }; +static int lifetime = 255; /* But no longer than TGT says. */ + +/* + * 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. + */ + +int +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 */ + int32_t 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 des_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 + des_key_sched(&cr.session,key_s); + des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat, + (long)req_id->length,key_s,&cr.session, DES_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/kerberosIV/krb/mk_safe.c b/kerberosIV/krb/mk_safe.c new file mode 100644 index 00000000000..e652d9ac0b4 --- /dev/null +++ b/kerberosIV/krb/mk_safe.c @@ -0,0 +1,177 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/mk_safe.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + */ + +#include "krb_locl.h" + +/* system include files */ +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t cksum; +static des_cblock 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" + */ + +int32_t +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_int32_t length; /* of in data */ + des_cblock *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 = des_quad_cksum((des_cblock *)q,big_cksum,p-q,2,key); +#endif + if (krb_debug) + printf("\ncksum = %u",(u_int) 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/kerberosIV/krb/month_sname.c b/kerberosIV/krb/month_sname.c new file mode 100644 index 00000000000..885809a6603 --- /dev/null +++ b/kerberosIV/krb/month_sname.c @@ -0,0 +1,47 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/month_sname.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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/kerberosIV/krb/netread.c b/kerberosIV/krb/netread.c new file mode 100644 index 00000000000..e223b7915ac --- /dev/null +++ b/kerberosIV/krb/netread.c @@ -0,0 +1,63 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/netread.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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/kerberosIV/krb/netwrite.c b/kerberosIV/krb/netwrite.c new file mode 100644 index 00000000000..c95033c0bf2 --- /dev/null +++ b/kerberosIV/krb/netwrite.c @@ -0,0 +1,59 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/netwrite.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * 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/kerberosIV/krb/one.c b/kerberosIV/krb/one.c new file mode 100644 index 00000000000..316d80465f7 --- /dev/null +++ b/kerberosIV/krb/one.c @@ -0,0 +1,35 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/one.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of M.I.T. not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior + permission. M.I.T. makes no representations about the suitability of + this software for any purpose. It is provided "as is" without express + or implied warranty. + + */ + +/* + * definition of variable set to 1. + * used in krb_conf.h to determine host byte order. + */ + +int krbONE = 1; diff --git a/kerberosIV/krb/pkt_cipher.c b/kerberosIV/krb/pkt_cipher.c new file mode 100644 index 00000000000..2beb0f6a53f --- /dev/null +++ b/kerberosIV/krb/pkt_cipher.c @@ -0,0 +1,50 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/pkt_cipher.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +char * +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((char*)ptr); +} diff --git a/kerberosIV/krb/pkt_clen.c b/kerberosIV/krb/pkt_clen.c new file mode 100644 index 00000000000..af9d2a12cfa --- /dev/null +++ b/kerberosIV/krb/pkt_clen.c @@ -0,0 +1,68 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/pkt_clen.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#if defined(horrible_function_using_global_variable_had_to_be_inlined) + +#include "krb_locl.h" + +/* + * 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. + */ + +int +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); +} + +#endif /* defined(horrible_function_using_global_variable_had_to_be_inlined) */ diff --git a/kerberosIV/krb/rd_err.c b/kerberosIV/krb/rd_err.c new file mode 100644 index 00000000000..8b3a26fe8d7 --- /dev/null +++ b/kerberosIV/krb/rd_err.c @@ -0,0 +1,91 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/rd_err.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + */ + +#include "krb_locl.h" + +/* system include files */ +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.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_int32_t in_length; /* of in msg */ + int32_t *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/kerberosIV/krb/rd_priv.c b/kerberosIV/krb/rd_priv.c new file mode 100644 index 00000000000..25906e567a6 --- /dev/null +++ b/kerberosIV/krb/rd_priv.c @@ -0,0 +1,215 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/rd_priv.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + */ + +#include "krb_locl.h" + +/* system include files */ +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t c_length; +static int swap_bytes; +static struct timeval local_time; +static long delta_t; + +/* Global! */ +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". + */ + +int32_t +krb_rd_priv(in, in_length, schedule, key, sender, receiver, m_data) + u_char *in; /* pointer to the msg received */ + u_int32_t in_length; /* length of "in" msg */ + struct des_ks_struct *schedule; /* precomputed key schedule */ + des_cblock *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_int32_t 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 + des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)c_length,schedule,key,DES_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 (!krb_equiv(src_addr, 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", (int) 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 = des_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/kerberosIV/krb/rd_req.c b/kerberosIV/krb/rd_req.c new file mode 100644 index 00000000000..c6128b11cf5 --- /dev/null +++ b/kerberosIV/krb/rd_req.c @@ -0,0 +1,344 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/rd_req.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.h> + +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 des_key_schedule serv_key; /* Key sched to decrypt ticket */ +static des_cblock 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 /* Encrypt */ + if (cvt) + des_string_to_key(key,&ky); + else + bcopy(key,(char *)ky,8); + return(des_key_sched(&ky,serv_key)); +#endif /* NOENCRYPTION */ +} + + +/* + * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or + * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), + * checks its integrity and returns a judgement as to the requestor's + * identity. + * + * The "authent" argument is a pointer to the received message. + * The "service" and "instance" arguments name the receiving server, + * and are used to get the service's ticket to decrypt the ticket + * in the message, and to compare against the server name inside the + * ticket. "from_addr" is the network address of the host from which + * the message was received; this is checked against the network + * address in the ticket. If "from_addr" is zero, the check is not + * performed. "ad" is an AUTH_DAT structure which is + * filled in with information about the sender's identity according + * to the authenticator and ticket sent in the message. Finally, + * "fn" contains the name of the file containing the server's key. + * (If "fn" is NULL, the server's key is assumed to have been set + * by krb_set_key(). If "fn" is the null string ("") the default + * file KEYFILE, defined in "krb.h", is used.) + * + * krb_rd_req() returns RD_AP_OK if the authentication information + * was genuine, or one of the following error codes (defined in + * "krb.h"): + * + * RD_AP_VERSION - wrong protocol version number + * RD_AP_MSG_TYPE - wrong message type + * RD_AP_UNDEC - couldn't decipher the message + * RD_AP_INCON - inconsistencies found + * RD_AP_BADD - wrong network address + * RD_AP_TIME - client time (in authenticator) + * too far off server time + * RD_AP_NYV - Kerberos time (in ticket) too + * far off server time + * RD_AP_EXP - ticket expired + * + * For the message format, see krb_mk_req(). + * + * Mutual authentication is not implemented. + */ + +int +krb_rd_req(authent, service, instance, from_addr, ad, fn) + register KTEXT authent; /* The received message */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int32_t 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 des_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,(int) s_kvno, + fn,(char *)skey)) + return(RD_AP_UNDEC); + if ((status = krb_set_key((char *)skey,0))) + return(status); +#endif /* !NOENCRYPTION */ + (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 + /* And decrypt it with the session key from the ticket */ + if (krb_ap_req_debug) log("About to decrypt authenticator"); + des_key_sched(&ad->session,seskey_sched); + des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat, + (long) req_id->length, seskey_sched,&ad->session,DES_DECRYPT); + if (krb_ap_req_debug) log("Done."); +#endif /* NOENCRYPTION */ + +#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); + + ptr = (char *) req_id->dat; + (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 && (!krb_equiv(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 > krb_life_to_time(ad->time_sec, ad->life)) + return(RD_AP_EXP); + + /* All seems OK */ + ad->reply.length = 0; + + return(RD_AP_OK); +} diff --git a/kerberosIV/krb/rd_safe.c b/kerberosIV/krb/rd_safe.c new file mode 100644 index 00000000000..a7ea1ff2043 --- /dev/null +++ b/kerberosIV/krb/rd_safe.c @@ -0,0 +1,189 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/rd_safe.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * 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 + */ + +#include "krb_locl.h" + +/* system include files */ +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static des_cblock calc_cksum[2]; +static des_cblock big_cksum[2]; +static int swap_bytes; +static struct timeval local_time; +static u_int32_t 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". + */ + +int32_t +krb_rd_safe(in, in_length, key, sender, receiver, m_data) + u_char *in; /* pointer to the msg received */ + u_int32_t in_length; /* length of "in" msg */ + des_cblock *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_int32_t src_addr; /* Can't send structs since no + * guarantees on size */ + /* Be very conservative */ + if (sizeof(src_addr) != sizeof(struct in_addr)) { + fprintf(stderr,"\n\ +krb_rd_safe protocol err sizeof(src_addr) != 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 (!krb_equiv(src_addr, 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 + des_quad_cksum((des_cblock *)q,calc_cksum,p-q,2,key); +#endif + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + (u_int) calc_cksum[0], (u_int) 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/kerberosIV/krb/read_service_key.c b/kerberosIV/krb/read_service_key.c new file mode 100644 index 00000000000..31ba2e84ee0 --- /dev/null +++ b/kerberosIV/krb/read_service_key.c @@ -0,0 +1,133 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/read_service_key.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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 */ +int +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(const char *, int, ...); + + if ((stab = open(file, 0, 0)) < 0) + 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/kerberosIV/krb/recvauth.c b/kerberosIV/krb/recvauth.c new file mode 100644 index 00000000000..d5706120d42 --- /dev/null +++ b/kerberosIV/krb/recvauth.c @@ -0,0 +1,295 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/recvauth.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> + +/* + * 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! + */ +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN + chars */ + +/* + * 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) + int32_t 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 */ + struct des_ks_struct *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_int32_t 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 + des_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/kerberosIV/krb/save_credentials.c b/kerberosIV/krb/save_credentials.c new file mode 100644 index 00000000000..b9b58d48704 --- /dev/null +++ b/kerberosIV/krb/save_credentials.c @@ -0,0 +1,67 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/save_credentials.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.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. + */ + +int +save_credentials(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + unsigned char *session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + int32_t 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/kerberosIV/krb/send_to_kdc.c b/kerberosIV/krb/send_to_kdc.c new file mode 100644 index 00000000000..7b6009008e1 --- /dev/null +++ b/kerberosIV/krb/send_to_kdc.c @@ -0,0 +1,324 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/send_to_kdc.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +#define S_AD_SZ sizeof(struct sockaddr_in) + +static 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(KTEXT pkt, KTEXT rpkt, int f, struct sockaddr_in *_to, struct hostent *addrs); + +/* + * 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 + */ + +int +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); + krb_udp_port = 750; /* Was return(SKDC_CANT); */ + } + else + 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; + bzero((char *)&hostlist[n_hosts], sizeof(struct hostent)); + 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(h_addr) + host->h_addr_list = (char **)malloc(2*sizeof(char *)); + if (!host->h_addr_list) { + retval = /*errno */SKDC_CANT; + goto rtn; + } + host->h_addr_list[1] = NULL; +#endif /* defined(h_addr) */ + 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(h_addr) + if (hp->h_addr_list) { +#endif /* defined(h_addr) */ + if (hp->h_addr) + free(hp->h_addr); +#if defined(h_addr) + free((char *)hp->h_addr_list); + } +#endif /* defined(h_addr) */ + free((char *)hostlist); + } + return(retval); +} + +/* + * try to send out and receive message. + * return 1 on success, 0 on failure + */ + +static int +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) { + long rfds; + bcopy(&readfds, &rfds, sizeof(rfds)); + fprintf(stderr, "select failed: readfds=%lx", + rfds); + 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 %lx\n", + (long)hp->h_addr); + } + if (krb_debug) + fprintf(stderr, "%s: received packet from wrong host! (%x)\n", + "send_to_kdc(send_rcv)", (int)from.sin_addr.s_addr); + return 0; +} diff --git a/kerberosIV/krb/sendauth.c b/kerberosIV/krb/sendauth.c new file mode 100644 index 00000000000..9111ab24d85 --- /dev/null +++ b/kerberosIV/krb/sendauth.c @@ -0,0 +1,269 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/sendauth.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_recvauth.c + */ +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */ + + +/* + * 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) + int32_t 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; /* service name, instance, realm */ + char *inst; /* checksum to include in request */ + char *realm; /* mutual auth MSG_DAT (return) */ + u_int32_t checksum; /* credentials (return) */ + MSG_DAT *msg_data; /* key schedule (return) */ + CREDENTIALS *cred; /* local address */ + struct des_ks_struct *schedule; + struct sockaddr_in *faddr; /* address of foreign host on fd */ + struct sockaddr_in *laddr; + char *version; /* version string */ +{ + int rem, i, cc; + char srv_inst[INST_SZ]; + char krb_realm[REALM_SZ]; + char buf[BUFSIZ]; + u_int32_t tkt_len; + u_char priv_buf[1024]; + u_int32_t 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(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(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 + des_key_sched(&cred->session,schedule); +#endif + if ((cc = krb_rd_priv(priv_buf, 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 */ + u_int32_t serv_length; + int cc; + + serv_length = htonl(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/kerberosIV/krb/shlib_version b/kerberosIV/krb/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/krb/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/krb/str2key.c b/kerberosIV/krb/str2key.c new file mode 100644 index 00000000000..cdc56583caf --- /dev/null +++ b/kerberosIV/krb/str2key.c @@ -0,0 +1,129 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/str2key.c,v $ + * + * $Locker: $ + */ + +/* + * This defines the Andrew string_to_key function. It accepts a password + * string as input and converts its via a one-way encryption algorithm to a DES + * encryption key. It is compatible with the original Andrew authentication + * service password database. + */ + +#include "krb_locl.h" + +/* +EXPORT void afs_string_to_key(char *passwd, char *cell, des_cblock *key); +*/ + +static void +mklower(s) + char *s; +{ + for (; *s; s++) + if ('A' <= *s && *s <= 'Z') + *s = *s - 'A' + 'a'; +} + +/* + * Short passwords, i.e 8 characters or less. + */ +static void +afs_cmu_StringToKey (str, cell, key) + char *str; + char *cell; + des_cblock *key; +{ + char password[8+1]; /* crypt is limited to 8 chars anyway */ + int i; + int passlen; + + bzero (key, sizeof(key)); + bzero(password, sizeof(password)); + + strncpy (password, cell, 8); + passlen = strlen (str); + if (passlen > 8) passlen = 8; + + for (i=0; i<passlen; i++) + password[i] = str[i] ^ cell[i]; /* make sure cell is zero padded */ + + for (i=0; i<8; i++) + if (password[i] == '\0') password[i] = 'X'; + + /* crypt only considers the first 8 characters of password but for some + reason returns eleven characters of result (plus the two salt chars). */ + strncpy((void *)key, (char *)crypt(password, "#~") + 2, sizeof(des_cblock)); + + /* parity is inserted into the LSB so leftshift each byte up one bit. This + allows ascii characters with a zero MSB to retain as much significance + as possible. */ + { char *keybytes = (char *)key; + unsigned int temp; + + for (i = 0; i < 8; i++) { + temp = (unsigned int) keybytes[i]; + keybytes[i] = (unsigned char) (temp << 1); + } + } + des_fixup_key_parity (key); +} + +#undef BUFSIZ +#define BUFSIZ 512 + +/* + * Long passwords, i.e 9 characters or more. +*/ +static void +afs_transarc_StringToKey (str, cell, key) + char *str; + char *cell; + des_cblock *key; +{ + des_key_schedule schedule; + des_cblock temp_key; + des_cblock ivec; + char password[BUFSIZ]; + int passlen; + + strncpy (password, str, sizeof(password)); + if ((passlen = strlen (password)) < sizeof(password)-1) + strncat (password, cell, sizeof(password)-passlen); + if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password); + + bcopy ("kerberos", &ivec, 8); + bcopy ("kerberos", &temp_key, 8); + des_fixup_key_parity (&temp_key); + des_key_sched (&temp_key, schedule); + des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec); + + bcopy (&ivec, &temp_key, 8); + des_fixup_key_parity (&temp_key); + des_key_sched (&temp_key, schedule); + des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec); + + des_fixup_key_parity (key); +} + +#undef REALM_SZ +#define REALM_SZ 41 + +void +afs_string_to_key(str, cell, key) + char *str; + char *cell; + des_cblock *key; +{ + char realm[REALM_SZ]; + (void)strcpy(realm, cell); + (void)mklower(realm); + + if (strlen(str) > 8) + afs_transarc_StringToKey (str, realm, key); + else + afs_cmu_StringToKey (str, realm, key); +} diff --git a/kerberosIV/krb/tf_util.3 b/kerberosIV/krb/tf_util.3 new file mode 100644 index 00000000000..7b21c50cfad --- /dev/null +++ b/kerberosIV/krb/tf_util.3 @@ -0,0 +1,152 @@ +.\" $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/tf_util.3,v $ +.\" $Author: tholo $ +.\" $Header: /cvs/OpenBSD/src/kerberosIV/krb/Attic/tf_util.3,v 1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <mit-copyright.h>. +.\" +.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/kerberosIV/krb/tf_util.c b/kerberosIV/krb/tf_util.c new file mode 100644 index 00000000000..37254df1cc1 --- /dev/null +++ b/kerberosIV/krb/tf_util.c @@ -0,0 +1,590 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/tf_util.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.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 */ + +#ifdef TKT_SHMEM +static 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}; +#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(register char *s, int n), tf_read(register char *s, register int n); + +/* + * 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 + * u_int32_t 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 + */ + +int +tf_init(tf_name, rw) + char *tf_name; + int rw; +{ + int wflag; + uid_t me, getuid(void); + 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. + */ + +int +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. + */ + +int +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 + */ + +int +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), DES_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. + */ + +void +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 int +tf_gets(s, n) + register char *s; + int n; +{ + 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 int +tf_read(s, n) + register char *s; + register int 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(void); + +/* + * 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. + */ + +int +tf_save_cred(service, instance, realm, session, + lifetime, kvno, ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + unsigned char *session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + u_int32_t issue_date; /* The issue time */ +{ + + off_t lseek(int, off_t, int); + 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(issue_date)) + != sizeof(issue_date)) + goto bad; + + /* Actually, we should check each write for success */ + return (KSUCCESS); +bad: + return (KFAILURE); +} diff --git a/kerberosIV/krb/tkt_string.c b/kerberosIV/krb/tkt_string.c new file mode 100644 index 00000000000..fc0bea7c634 --- /dev/null +++ b/kerberosIV/krb/tkt_string.c @@ -0,0 +1,91 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /cvs/OpenBSD/src/kerberosIV/krb/Attic/tkt_string.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include <sys/param.h> +#include <sys/types.h> + +/* + * 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(void); + + 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,(int)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; +} |