diff options
390 files changed, 46955 insertions, 0 deletions
diff --git a/eBones/ARTISTIC.libdes b/eBones/ARTISTIC.libdes new file mode 100644 index 0000000..b382657 --- /dev/null +++ b/eBones/ARTISTIC.libdes @@ -0,0 +1,105 @@ + + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. + +6. Any programs linked with this library do not automatically fall +under the copyright of this Package, but belong to whomever generated +them, and may be sold commercially, and may be aggregated with this +Package. + +7. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +8. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End + diff --git a/eBones/Copyright.MIT b/eBones/Copyright.MIT new file mode 100644 index 0000000..28dd55f --- /dev/null +++ b/eBones/Copyright.MIT @@ -0,0 +1,24 @@ +# $Id: Copyright.MIT,v 1.2 1994/07/19 19:21:03 g89r4222 Exp $ + +The following Copyright notice applies to the original Bones package. + +/*- + 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. + + */ diff --git a/eBones/Copyright.SIPB b/eBones/Copyright.SIPB new file mode 100644 index 0000000..c116ad2 --- /dev/null +++ b/eBones/Copyright.SIPB @@ -0,0 +1,23 @@ +# $Id: Copyright.SIPB,v 1.2 1994/07/19 19:21:05 g89r4222 Exp $ + +The following Copyright notice applies to parts of the Bones package. +See source code for exact references. + +/*- +Copyright 1987 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. + + */ + diff --git a/eBones/Makefile b/eBones/Makefile new file mode 100644 index 0000000..b63f933 --- /dev/null +++ b/eBones/Makefile @@ -0,0 +1,25 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.12 1994/09/30 13:34:39 g89r4222 Exp $ + +SUBDIR= include + +SUBDIR+= des compile_et acl ext_srvtab include kdb kdb_destroy kdb_edit \ + kdb_init kdb_util kdestroy kerberos kinit klist krb ksrvtgt \ + kstash man register registerd make_keypair + +SDIR= ${.CURDIR}/.. + +# These are the programs which depend on kerberos +# It's nice to know who they are +kprog: + cd ${SDIR}/bin/rcp; make cleandir obj ; make -DNOMAN depend all install + cd ${SDIR}/libexec/rlogind;make cleandir;make -DNOMAN depend all install + cd ${SDIR}/libexec/rshd; make cleandir; make -DNOMAN depend all install + cd ${SDIR}/usr.bin/login; make cleandir; make -DNOMAN depend all install + cd ${SDIR}/usr.bin/passwd;make cleandir; make -DNOMAN depend all install + cd ${SDIR}/usr.bin/rlogin;make cleandir; make -DNOMAN depend all install + cd ${SDIR}/usr.bin/rsh; make cleandir; make -DNOMAN depend all install + cd ${SDIR}/usr.bin/su; make cleandir; make -DNOMAN depend all install + cd ${SDIR}/libexec/kpasswdd; make cleandir; make depend all install + +.include <bsd.subdir.mk> diff --git a/eBones/Makefile.inc b/eBones/Makefile.inc new file mode 100644 index 0000000..fc75f4b --- /dev/null +++ b/eBones/Makefile.inc @@ -0,0 +1,37 @@ +# From: @(#)Makefile.inc 5.1 (Berkeley) 6/25/90 +# $Id: Makefile.inc,v 1.3 1994/09/24 14:04:08 g89r4222 Exp $ + +BINDIR?= /usr/sbin +SHLIB_MAJOR?= 2 +SHLIB_MINOR?= 0 + +.if exists(${.CURDIR}/../des/obj) +DESOBJDIR= ${.CURDIR}/../des/obj +.else +DESOBJDIR= ${.CURDIR}/../des +.endif + +.if exists(${.CURDIR}/../krb/obj) +KRBOBJDIR= ${.CURDIR}/../krb/obj +.else +KRBOBJDIR= ${.CURDIR}/../krb +.endif + +.if exists(${.CURDIR}/../kdb/obj) +KDBOBJDIR= ${.CURDIR}/../kdb/obj +.else +KDBOBJDIR= ${.CURDIR}/../kdb +.endif + +.if exists(${.CURDIR}/../acl/obj) +ACLOBJDIR= ${.CURDIR}/../acl/obj +.else +ACLOBJDIR= ${.CURDIR}/../acl +.endif + +.if exists(${.CURDIR}/../compile_et/obj) +COMPILE_ET= ${.CURDIR}/../compile_et/obj/compile_et +.else +COMPILE_ET= ${.CURDIR}/../compile_et/compile_et +.endif + diff --git a/eBones/README.libdes b/eBones/README.libdes new file mode 100644 index 0000000..6acd62c --- /dev/null +++ b/eBones/README.libdes @@ -0,0 +1,56 @@ + + libdes, Version 3.00 93/10/07 + + Copyright (c) 1993, Eric Young + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or + + b) the "Artistic License" which comes with this Kit. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either + the GNU General Public License or the Artistic License for more details. + + You should have received a copy of the Artistic License with this + Kit, in the file named "Artistic". If not, I'll be glad to provide one. + + You should also have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +--- +This kit builds a DES encryption library and a DES encryption program. +It suports ecb, cbc, ofb, cfb, triple ecb, triple cbc and MIT's pcbc +encryption modes and also has a fast implementation of crypt(3). +It contains support routines to read keys from a terminal, +generate a random key, generate a key from an arbitary length string, +read/write encrypted data from/to a file descriptor. + +The implementation was written so as to conform with the manual entry +for the des_crypt(3) library routines from MIT's project Athena. + +destest should be run after compilation to test the des routines. +rpw should be run after compilation to test the read password routines. +The des program is a replacement for the sun des command. I believe it +conforms to the sun version. + +The Imakefile is setup for use in the kerberos distribution. + +These routines are best compiled with gcc or any other good +optimising compiler. +Just turn you optimiser up to the highest settings and run destest +after the build to make sure everything works. + +I believe these routines are close to the fastest and most portable DES +routines that use small lookup tables (4.5k) that are publicly available. +The fcrypt routine is faster than ufc's fcrypt (when compiling with +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines +(on a sun3/260 168 vs 336). + +Eric Young (eay@psych.psy.uq.oz.au) diff --git a/eBones/acl/Makefile b/eBones/acl/Makefile new file mode 100644 index 0000000..77c9a01 --- /dev/null +++ b/eBones/acl/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.3 1994/09/09 21:43:17 g89r4222 Exp $ + +LIB= acl +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 +CFLAGS+=-DDEBUG -DKERBEROS -I${.CURDIR}/../include +SRCS= acl_files.c + +.include <bsd.lib.mk> diff --git a/eBones/acl/acl_check.3 b/eBones/acl/acl_check.3 new file mode 100644 index 0000000..c142506 --- /dev/null +++ b/eBones/acl/acl_check.3 @@ -0,0 +1,183 @@ +.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $ +.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +acl_canonicalize_principal, acl_check, acl_exact_match, acl_add, +acl_delete, acl_initialize \- Access control list routines +.SH SYNOPSIS +.nf +.nj +.ft B +cc <files> \-lacl \-lkrb +.PP +.ft B +#include <krb.h> +.PP +.ft B +acl_canonicalize_principal(principal, buf) +char *principal; +char *buf; +.PP +.ft B +acl_check(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_exact_match(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_add(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_delete(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_initialize(acl_file, mode) +char *acl_file; +int mode; +.fi +.ft R +.SH DESCRIPTION +.SS Introduction +.PP +An access control list (ACL) is a list of principals, where each +principal is represented by a text string which cannot contain +whitespace. The library allows application programs to refer to named +access control lists to test membership and to atomically add and +delete principals using a natural and intuitive interface. At +present, the names of access control lists are required to be Unix +filenames, and refer to human-readable Unix files; in the future, when +a networked ACL server is implemented, the names may refer to a +different namespace specific to the ACL service. +.PP +.SS Principal Names +.PP +Principal names have the form +.nf +.in +5n +<name>[.<instance>][@<realm>] +.in -5n +e.g.: +.in +5n +asp +asp.root +asp@ATHENA.MIT.EDU +asp.@ATHENA.MIT.EDU +asp.root@ATHENA.MIT.EDU +.in -5n +.fi +It is possible for principals to be underspecified. If an instance is +missing, it is assumed to be "". If realm is missing, it is assumed +to be the local realm as determined by +.IR krb_get_lrealm (3). +The canonical form contains all of name, instance, +and realm; the acl_add and acl_delete routines will always +leave the file in that form. Note that the canonical form of +asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU. +.SS Routines +.PP +.I acl_canonicalize_principal +stores the canonical form of +.I principal +in +.IR buf . +.I Buf +must contain enough +space to store a principal, given the limits on the sizes of name, +instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ, +respectively, in +.IR /usr/include/krb.h . +.PP +.I acl_check +returns nonzero if +.I principal +appears in +.IR acl . +Returns 0 if principal +does not appear in acl, or if an error occurs. Canonicalizes +principal before checking, and allows the ACL to contain wildcards. The +only supported wildcards are entries of the form +name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the +its component field. For example, "jtkohl.*@*" would match principal +jtkohl, with any instance and any realm. +.PP +.I acl_exact_match +performs like +.IR acl_check , +but does no canonicalization or wildcard matching. +.PP +.I acl_add +atomically adds +.I principal +to +.IR acl . +Returns 0 if successful, nonzero otherwise. It is considered a failure +if +.I principal +is already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_delete +atomically deletes +.I principal +from +.IR acl . +Returns 0 if successful, +nonzero otherwise. It is considered a failure if +.I principal +is not +already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_initialize +initializes +.IR acl_file . +If the file +.I acl_file +does not exist, +.I acl_initialize +creates it with mode +.IR mode . +If the file +.I acl_file +exists, +.I acl_initialize +removes all members. Returns 0 if successful, +nonzero otherwise. WARNING: Mode argument is likely to change with +the eventual introduction of an ACL service. +.SH NOTES +In the presence of concurrency, there is a very small chance that +.I acl_add +or +.I acl_delete +could report success even though it would have +had no effect. This is a necessary side effect of using lock files +for concurrency control rather than flock(2), which is not supported +by NFS. +.PP +The current implementation caches ACLs in memory in a hash-table +format for increased efficiency in checking membership; one effect of +the caching scheme is that one file descriptor will be kept open for +each ACL cached, up to a maximum of 8. +.SH SEE ALSO +kerberos(3), krb_get_lrealm(3) +.SH AUTHOR +James Aspnes (MIT Project Athena) diff --git a/eBones/acl/acl_files.c b/eBones/acl/acl_files.c new file mode 100644 index 0000000..6f7f3fd --- /dev/null +++ b/eBones/acl/acl_files.c @@ -0,0 +1,541 @@ +/* + * + * Copyright 1987,1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $ + * $Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $"; +#endif lint + + +/*** Routines for manipulating access control list files ***/ + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/errno.h> +#include <ctype.h> +#include "krb.h" + +__BEGIN_DECLS +static int acl_abort __P((char *, FILE *)); +__END_DECLS + +#ifndef KRB_REALM +#define KRB_REALM "ATHENA.MIT.EDU" +#endif + +/* "aname.inst@realm" */ +#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3) +#define INST_SEP '.' +#define REALM_SEP '@' + +#define LINESIZE 2048 /* Maximum line length in an acl file */ + +#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */ +#define WAIT_TIME 300 /* Maximum time allowed write acl file */ + +#define CACHED_ACLS 8 /* How many acls to cache */ + /* Each acl costs 1 open file descriptor */ +#define ACL_LEN 16 /* Twice a reasonable acl length */ + +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +#define COR(a,b) ((a!=NULL)?(a):(b)) + +extern int errno; + +extern char *malloc(), *calloc(); +extern time_t time(); + +/* Canonicalize a principal name */ +/* If instance is missing, it becomes "" */ +/* If realm is missing, it becomes the local realm */ +/* Canonicalized form is put in canon, which must be big enough to hold + MAX_PRINCIPAL_SIZE characters */ +acl_canonicalize_principal(principal, canon) +char *principal; +char *canon; +{ + char *dot, *atsign, *end; + int len; + + dot = index(principal, INST_SEP); + atsign = index(principal, REALM_SEP); + + /* Maybe we're done already */ + if(dot != NULL && atsign != NULL) { + if(dot < atsign) { + /* It's for real */ + /* Copy into canon */ + strncpy(canon, principal, MAX_PRINCIPAL_SIZE); + canon[MAX_PRINCIPAL_SIZE-1] = '\0'; + return; + } else { + /* Nope, it's part of the realm */ + dot = NULL; + } + } + + /* No such luck */ + end = principal + strlen(principal); + + /* Get the principal name */ + len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal); + strncpy(canon, principal, len); + canon += len; + + /* Add INST_SEP */ + *canon++ = INST_SEP; + + /* Get the instance, if it exists */ + if(dot != NULL) { + ++dot; + len = MIN(INST_SZ, COR(atsign, end) - dot); + strncpy(canon, dot, len); + canon += len; + } + + /* Add REALM_SEP */ + *canon++ = REALM_SEP; + + /* Get the realm, if it exists */ + /* Otherwise, default to local realm */ + if(atsign != NULL) { + ++atsign; + len = MIN(REALM_SZ, end - atsign); + strncpy(canon, atsign, len); + canon += len; + *canon++ = '\0'; + } else if(krb_get_lrealm(canon, 1) != KSUCCESS) { + strcpy(canon, KRB_REALM); + } +} + +/* Get a lock to modify acl_file */ +/* Return new FILE pointer */ +/* or NULL if file cannot be modified */ +/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */ +static FILE *acl_lock_file(acl_file) +char *acl_file; +{ + struct stat s; + char new[LINESIZE]; + int nfd; + FILE *nf; + int mode; + + if(stat(acl_file, &s) < 0) return(NULL); + mode = s.st_mode; + sprintf(new, NEW_FILE, acl_file); + for(;;) { + /* Open the new file */ + if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) { + if(errno == EEXIST) { + /* Maybe somebody got here already, maybe it's just old */ + if(stat(new, &s) < 0) return(NULL); + if(time(0) - s.st_ctime > WAIT_TIME) { + /* File is stale, kill it */ + unlink(new); + continue; + } else { + /* Wait and try again */ + sleep(1); + continue; + } + } else { + /* Some other error, we lose */ + return(NULL); + } + } + + /* If we got to here, the lock file is ours and ok */ + /* Reopen it under stdio */ + if((nf = fdopen(nfd, "w")) == NULL) { + /* Oops, clean up */ + unlink(new); + } + return(nf); + } +} + +/* Commit changes to acl_file written onto FILE *f */ +/* Returns zero if successful */ +/* Returns > 0 if lock was broken */ +/* Returns < 0 if some other error occurs */ +/* Closes f */ +static int acl_commit(acl_file, f) +char *acl_file; +FILE *f; +{ + char new[LINESIZE]; + int ret; + struct stat s; + + sprintf(new, NEW_FILE, acl_file); + if(fflush(f) < 0 + || fstat(fileno(f), &s) < 0 + || s.st_nlink == 0) { + acl_abort(acl_file, f); + return(-1); + } + + ret = rename(new, acl_file); + fclose(f); + return(ret); +} + +/* + * Abort changes to acl_file written onto FILE *f + * Returns 0 if successful, < 0 otherwise + * Closes f + */ +static int +acl_abort(acl_file, f) +char *acl_file; +FILE *f; +{ + char new[LINESIZE]; + int ret; + struct stat s; + + /* make sure we aren't nuking someone else's file */ + if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) { + fclose(f); + return(-1); + } else { + sprintf(new, NEW_FILE, acl_file); + ret = unlink(new); + fclose(f); + return(ret); + } +} + +/* Initialize an acl_file */ +/* Creates the file with permissions perm if it does not exist */ +/* Erases it if it does */ +/* Returns return value of acl_commit */ +int acl_initialize(acl_file, perm) +char *acl_file; +int perm; +{ + FILE *new; + int fd; + + /* Check if the file exists already */ + if((new = acl_lock_file(acl_file)) != NULL) { + return(acl_commit(acl_file, new)); + } else { + /* File must be readable and writable by owner */ + if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) { + return(-1); + } else { + close(fd); + return(0); + } + } +} + +/* Eliminate all whitespace character in buf */ +/* Modifies its argument */ +static nuke_whitespace(buf) +char *buf; +{ + register char *pin, *pout; + + for(pin = pout = buf; *pin != '\0'; pin++) + if(!isspace(*pin)) *pout++ = *pin; + *pout = '\0'; /* Terminate the string */ +} + +/* Hash table stuff */ + +struct hashtbl { + int size; /* Max number of entries */ + int entries; /* Actual number of entries */ + char **tbl; /* Pointer to start of table */ +}; + +/* Make an empty hash table of size s */ +static struct hashtbl *make_hash(size) +int size; +{ + struct hashtbl *h; + + if(size < 1) size = 1; + h = (struct hashtbl *) malloc(sizeof(struct hashtbl)); + h->size = size; + h->entries = 0; + h->tbl = (char **) calloc(size, sizeof(char *)); + return(h); +} + +/* Destroy a hash table */ +static destroy_hash(h) +struct hashtbl *h; +{ + int i; + + for(i = 0; i < h->size; i++) { + if(h->tbl[i] != NULL) free(h->tbl[i]); + } + free(h->tbl); + free(h); +} + +/* Compute hash value for a string */ +static unsigned hashval(s) +register char *s; +{ + register unsigned hv; + + for(hv = 0; *s != '\0'; s++) { + hv ^= ((hv << 3) ^ *s); + } + return(hv); +} + +/* Add an element to a hash table */ +static add_hash(h, el) +struct hashtbl *h; +char *el; +{ + unsigned hv; + char *s; + char **old; + int i; + + /* Make space if it isn't there already */ + if(h->entries + 1 > (h->size >> 1)) { + old = h->tbl; + h->tbl = (char **) calloc(h->size << 1, sizeof(char *)); + for(i = 0; i < h->size; i++) { + if(old[i] != NULL) { + hv = hashval(old[i]) % (h->size << 1); + while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1); + h->tbl[hv] = old[i]; + } + } + h->size = h->size << 1; + free(old); + } + + hv = hashval(el) % h->size; + while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size; + s = malloc(strlen(el)+1); + strcpy(s, el); + h->tbl[hv] = s; + h->entries++; +} + +/* Returns nonzero if el is in h */ +static check_hash(h, el) +struct hashtbl *h; +char *el; +{ + unsigned hv; + + for(hv = hashval(el) % h->size; + h->tbl[hv] != NULL; + hv = (hv + 1) % h->size) { + if(!strcmp(h->tbl[hv], el)) return(1); + } + return(0); +} + +struct acl { + char filename[LINESIZE]; /* Name of acl file */ + int fd; /* File descriptor for acl file */ + struct stat status; /* File status at last read */ + struct hashtbl *acl; /* Acl entries */ +}; + +static struct acl acl_cache[CACHED_ACLS]; + +static int acl_cache_count = 0; +static int acl_cache_next = 0; + +/* Returns < 0 if unsuccessful in loading acl */ +/* Returns index into acl_cache otherwise */ +/* Note that if acl is already loaded, this is just a lookup */ +static int acl_load(name) +char *name; +{ + int i; + FILE *f; + struct stat s; + char buf[MAX_PRINCIPAL_SIZE]; + char canon[MAX_PRINCIPAL_SIZE]; + + /* See if it's there already */ + for(i = 0; i < acl_cache_count; i++) { + if(!strcmp(acl_cache[i].filename, name) + && acl_cache[i].fd >= 0) goto got_it; + } + + /* It isn't, load it in */ + /* maybe there's still room */ + if(acl_cache_count < CACHED_ACLS) { + i = acl_cache_count++; + } else { + /* No room, clean one out */ + i = acl_cache_next; + acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS; + close(acl_cache[i].fd); + if(acl_cache[i].acl) { + destroy_hash(acl_cache[i].acl); + acl_cache[i].acl = (struct hashtbl *) 0; + } + } + + /* Set up the acl */ + strcpy(acl_cache[i].filename, name); + if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1); + /* Force reload */ + acl_cache[i].acl = (struct hashtbl *) 0; + + got_it: + /* + * See if the stat matches + * + * Use stat(), not fstat(), as the file may have been re-created by + * acl_add or acl_delete. If this happens, the old inode will have + * no changes in the mod-time and the following test will fail. + */ + if(stat(acl_cache[i].filename, &s) < 0) return(-1); + if(acl_cache[i].acl == (struct hashtbl *) 0 + || s.st_nlink != acl_cache[i].status.st_nlink + || s.st_mtime != acl_cache[i].status.st_mtime + || s.st_ctime != acl_cache[i].status.st_ctime) { + /* Gotta reload */ + if(acl_cache[i].fd >= 0) close(acl_cache[i].fd); + if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1); + if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1); + if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl); + acl_cache[i].acl = make_hash(ACL_LEN); + while(fgets(buf, sizeof(buf), f) != NULL) { + nuke_whitespace(buf); + acl_canonicalize_principal(buf, canon); + add_hash(acl_cache[i].acl, canon); + } + fclose(f); + acl_cache[i].status = s; + } + return(i); +} + +/* Returns nonzero if it can be determined that acl contains principal */ +/* Principal is not canonicalized, and no wildcarding is done */ +acl_exact_match(acl, principal) +char *acl; +char *principal; +{ + int idx; + + return((idx = acl_load(acl)) >= 0 + && check_hash(acl_cache[idx].acl, principal)); +} + +/* Returns nonzero if it can be determined that acl contains principal */ +/* Recognizes wildcards in acl of the form + name.*@realm, *.*@realm, and *.*@* */ +acl_check(acl, principal) +char *acl; +char *principal; +{ + char buf[MAX_PRINCIPAL_SIZE]; + char canon[MAX_PRINCIPAL_SIZE]; + char *realm; + + acl_canonicalize_principal(principal, canon); + + /* Is it there? */ + if(acl_exact_match(acl, canon)) return(1); + + /* Try the wildcards */ + realm = index(canon, REALM_SEP); + *index(canon, INST_SEP) = '\0'; /* Chuck the instance */ + + sprintf(buf, "%s.*%s", canon, realm); + if(acl_exact_match(acl, buf)) return(1); + + sprintf(buf, "*.*%s", realm); + if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1); + + return(0); +} + +/* Adds principal to acl */ +/* Wildcards are interpreted literally */ +acl_add(acl, principal) +char *acl; +char *principal; +{ + int idx; + int i; + FILE *new; + char canon[MAX_PRINCIPAL_SIZE]; + + acl_canonicalize_principal(principal, canon); + + if((new = acl_lock_file(acl)) == NULL) return(-1); + if((acl_exact_match(acl, canon)) + || (idx = acl_load(acl)) < 0) { + acl_abort(acl, new); + return(-1); + } + /* It isn't there yet, copy the file and put it in */ + for(i = 0; i < acl_cache[idx].acl->size; i++) { + if(acl_cache[idx].acl->tbl[i] != NULL) { + if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL + || putc('\n', new) != '\n') { + acl_abort(acl, new); + return(-1); + } + } + } + fputs(canon, new); + putc('\n', new); + return(acl_commit(acl, new)); +} + +/* Removes principal from acl */ +/* Wildcards are interpreted literally */ +acl_delete(acl, principal) +char *acl; +char *principal; +{ + int idx; + int i; + FILE *new; + char canon[MAX_PRINCIPAL_SIZE]; + + acl_canonicalize_principal(principal, canon); + + if((new = acl_lock_file(acl)) == NULL) return(-1); + if((!acl_exact_match(acl, canon)) + || (idx = acl_load(acl)) < 0) { + acl_abort(acl, new); + return(-1); + } + /* It isn't there yet, copy the file and put it in */ + for(i = 0; i < acl_cache[idx].acl->size; i++) { + if(acl_cache[idx].acl->tbl[i] != NULL + && strcmp(acl_cache[idx].acl->tbl[i], canon)) { + fputs(acl_cache[idx].acl->tbl[i], new); + putc('\n', new); + } + } + return(acl_commit(acl, new)); +} + diff --git a/eBones/acl/acl_files.doc b/eBones/acl/acl_files.doc new file mode 100644 index 0000000..78c448a --- /dev/null +++ b/eBones/acl/acl_files.doc @@ -0,0 +1,107 @@ +PROTOTYPE ACL LIBRARY + +Introduction + +An access control list (ACL) is a list of principals, where each +principal is is represented by a text string which cannot contain +whitespace. The library allows application programs to refer to named +access control lists to test membership and to atomically add and +delete principals using a natural and intuitive interface. At +present, the names of access control lists are required to be Unix +filenames, and refer to human-readable Unix files; in the future, when +a networked ACL server is implemented, the names may refer to a +different namespace specific to the ACL service. + + +Usage + +cc <files> -lacl -lkrb. + + + +Principal Names + +Principal names have the form + +<name>[.<instance>][@<realm>] + +e.g. + +asp +asp.root +asp@ATHENA.MIT.EDU +asp.@ATHENA.MIT.EDU +asp.root@ATHENA.MIT.EDU + +It is possible for principals to be underspecified. If instance is +missing, it is assumed to be "". If realm is missing, it is assumed +to be local_realm. The canonical form contains all of name, instance, +and realm; the acl_add and acl_delete routines will always +leave the file in that form. Note that the canonical form of +asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU. + + +Routines + +acl_canonicalize_principal(principal, buf) +char *principal; +char *buf; /*RETVAL*/ + +Store the canonical form of principal in buf. Buf must contain enough +space to store a principal, given the limits on the sizes of name, +instance, and realm specified in /usr/include/krb.h. + +acl_check(acl, principal) +char *acl; +char *principal; + +Returns nonzero if principal appears in acl. Returns 0 if principal +does not appear in acl, or if an error occurs. Canonicalizes +principal before checking, and allows the ACL to contain wildcards. + +acl_exact_match(acl, principal) +char *acl; +char *principal; + +Like acl_check, but does no canonicalization or wildcarding. + +acl_add(acl, principal) +char *acl; +char *principal; + +Atomically adds principal to acl. Returns 0 if successful, nonzero +otherwise. It is considered a failure if principal is already in acl. +This routine will canonicalize principal, but will treat wildcards +literally. + +acl_delete(acl, principal) +char *acl; +char *principal; + +Atomically deletes principal from acl. Returns 0 if successful, +nonzero otherwise. It is consider a failure if principal is not +already in acl. This routine will canonicalize principal, but will +treat wildcards literally. + +acl_initialize(acl, mode) +char *acl; +int mode; + +Initialize acl. If acl file does not exist, creates it with mode +mode. If acl exists, removes all members. Returns 0 if successful, +nonzero otherwise. WARNING: Mode argument is likely to change with +the eventual introduction of an ACL service. + + +Known problems + +In the presence of concurrency, there is a very small chance that +acl_add or acl_delete could report success even though it would have +had no effect. This is a necessary side effect of using lock files +for concurrency control rather than flock(2), which is not supported +by NFS. + +The current implementation caches ACLs in memory in a hash-table +format for increased efficiency in checking membership; one effect of +the caching scheme is that one file descriptor will be kept open for +each ACL cached, up to a maximum of 8. diff --git a/eBones/compile_et/Makefile b/eBones/compile_et/Makefile new file mode 100644 index 0000000..9b988267 --- /dev/null +++ b/eBones/compile_et/Makefile @@ -0,0 +1,15 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:21:23 g89r4222 Exp $ + +PROG= compile_et +CFLAGS+=-I. -I${.CURDIR} +SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c +OBJS+= error_table.o +DPADD= ${LIBL} +LDADD= -ll +CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c +NOMAN= noman + +error_table.c: et_lex.lex.c + +.include <bsd.prog.mk> diff --git a/eBones/compile_et/compile_et.c b/eBones/compile_et/compile_et.c new file mode 100644 index 0000000..25be70b --- /dev/null +++ b/eBones/compile_et/compile_et.c @@ -0,0 +1,172 @@ +/* + * + * Copyright 1986, 1987 by MIT Student Information Processing Board + * For copyright info, see "Copyright.SIPB". + * + * $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $ + */ + +#include <stdio.h> +#include <sys/file.h> +#include <strings.h> +#include <sys/param.h> + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +extern char *gensym(); +extern char *current_token; +extern int table_number, current; +char buffer[BUFSIZ]; +char *table_name = (char *)NULL; +FILE *hfile, *cfile; + +/* C library */ +extern char *malloc(); +extern int errno; + +/* lex stuff */ +extern FILE *yyin; +extern int yylineno; + +/* pathnames */ +char c_file[MAXPATHLEN]; /* temporary file */ +char h_file[MAXPATHLEN]; /* output */ +char o_file[MAXPATHLEN]; /* output */ +char et_file[MAXPATHLEN]; /* input */ + +main(argc, argv) + int argc; + char **argv; +{ + register char *p; + int n_flag = 0, debug = 0; + + while (argc > 2) { + register char *arg, ch; + arg = argv[--argc]; + if (strlen(arg) != 2 || arg[0] != '-') + goto usage; + ch = arg[1]; + if (ch == 'n') + n_flag++; + else if (ch == 'd') + debug++; + else + goto usage; + } + + if (argc != 2) { + usage: + fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]); + exit(1); + } + + strcpy(et_file, argv[1]); + p = rindex(et_file, '/'); + if (p == (char *)NULL) + p = et_file; + else + p++; + p = rindex(p, '.'); + if (!strcmp(p, ".et")) + *++p = '\0'; + else { + if (!p) + p = et_file; + while (*p) + p++; + *p++ = '.'; + *p = '\0'; + } + /* p points at null where suffix should be */ + strcpy(p, "et.c"); + strcpy(c_file, et_file); + p[0] = 'h'; + p[1] = '\0'; + strcpy(h_file, et_file); + p[0] = 'o'; + strcpy(o_file, et_file); + p[0] = 'e'; + p[1] = 't'; + p[2] = '\0'; + + yyin = fopen(et_file, "r"); + if (!yyin) { + perror(et_file); + exit(1); + } + + hfile = fopen(h_file, "w"); + if (hfile == (FILE *)NULL) { + perror(h_file); + exit(1); + } + + cfile = fopen(c_file, "w"); + if (cfile == (FILE *)NULL) { + perror("Can't open temp file"); + exit(1); + } + + /* parse it */ + fputs("#define NULL 0\n", cfile); + fputs("static char *_et[] = {\n", cfile); + + yyparse(); + fclose(yyin); /* bye bye input file */ + + fputs("\t(char *)0\n};\n", cfile); + fputs("extern int init_error_table();\n\n", cfile); + fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number); + fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name); + fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n", + table_number, current); + fclose(cfile); + + fputs("extern int init_", hfile); + fputs(table_name, hfile); + fputs("_err_tbl();\nextern int ", hfile); + fputs(table_name, hfile); + fputs("_err_base;\n", hfile); + fclose(hfile); /* bye bye hfile */ + + if (n_flag) + exit(0); + + if (!fork()) { + p = rindex(c_file, '/'); + if (p) { + *p++ = '\0'; + chdir(c_file); + } + else + p = c_file; + execlp("cc", "cc", "-c", "-R", "-O", p, 0); + perror("cc"); + exit(1); + } + else wait(0); + + if (!debug) + (void) unlink(c_file); + /* make it .o file name */ + c_file[strlen(c_file)-1] = 'o'; + if (!fork()) { + execlp("cp", "cp", c_file, o_file, 0); + perror("cp"); + exit(1); + } + else wait(0); + if (!debug) + (void) unlink(c_file); + + exit(0); +} + +yyerror(s) + char *s; +{ + fputs(s, stderr); + fprintf(stderr, "\nLine number %d; last token was '%s'\n", + yylineno, current_token); +} diff --git a/eBones/compile_et/error_message.c b/eBones/compile_et/error_message.c new file mode 100644 index 0000000..92cec57 --- /dev/null +++ b/eBones/compile_et/error_message.c @@ -0,0 +1,77 @@ +/* + * Copyright 1987 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * For copyright info, see "Copyright.SIPB". + * + * from: error_message.c,v 1.1 86/11/10 21:34:34 spook Exp $ + * $Id: error_message.c,v 1.3 1994/09/09 21:43:22 g89r4222 Exp $ + */ + +#include <stdio.h> +#include "error_table.h" +extern int sys_nerr; + +static char buffer[25]; + +char * +error_message(code) + int code; +{ + register int offset; + register error_table **et; + register int table_num; + register int div; + register char *cp; + + offset = code & ((1<<ERRCODE_RANGE)-1); + table_num = code - offset; + if ((_et_list == (error_table **)NULL) && table_num) + goto oops; + if (!table_num) { + if (offset < sys_nerr) + return(sys_errlist[offset]); + else + goto oops; + } + for (et = _et_list; *et != (error_table *)NULL; et++) { + if ((*et)->base == table_num) { + /* This is the right table */ + if ((*et)->n_msgs <= offset) + goto oops; + return((*et)->msgs[offset]); + } + } + oops: + cp = buffer; + { + register char *cp1; + for (cp1 = "Unknown code "; *cp1; cp1++, cp++) + *cp = *cp1; + if (table_num) { + for (cp1 = error_table_name(table_num); *cp1; cp1++, cp++) + *cp = *cp1; + *cp++ = ' '; + *cp = '\0'; + } + } + div = 1000000000; + if (offset == 0) { + *cp++ = '0'; + *cp = '\0'; + return(buffer); + } + while (div > offset) + div /= 10; + do { + register int n = offset / div; + *cp++ = '0' + n; + offset -= n * div; + div /= 10; + } while (offset && div); + while (div) { + *cp++ = '0'; + div /= 10; + } + *cp = '\0'; + return(buffer); +} diff --git a/eBones/compile_et/error_table.h b/eBones/compile_et/error_table.h new file mode 100644 index 0000000..e32ec30 --- /dev/null +++ b/eBones/compile_et/error_table.h @@ -0,0 +1,17 @@ +#ifndef _ET +extern int errno; +typedef struct { + char **msgs; + int base; + int n_msgs; +} error_table; +extern error_table **_et_list; + +#define ERROR_CODE "int" /* type used for error codes */ + +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ + +extern char *error_table_name(); +#define _ET +#endif diff --git a/eBones/compile_et/error_table.y b/eBones/compile_et/error_table.y new file mode 100644 index 0000000..3913a84 --- /dev/null +++ b/eBones/compile_et/error_table.y @@ -0,0 +1,205 @@ +%{ +#include <stdio.h> +char *str_concat(), *ds(), *quote(), *malloc(), *realloc(); +char *current_token = (char *)NULL; +extern char *table_name; +%} +%union { + char *dynstr; +} + +%token ERROR_TABLE ERROR_CODE_ENTRY END +%token <dynstr> STRING QUOTED_STRING +%type <dynstr> ec_name description table_id +%{ +%} +%start error_table +%% + +error_table : ERROR_TABLE table_id error_codes END + { table_name = ds($2); + current_token = table_name; + put_ecs(); } + ; + +table_id : STRING + { current_token = $1; + set_table_num($1); + $$ = $1; } + ; + +error_codes : error_codes ec_entry + | ec_entry + ; + +ec_entry : ERROR_CODE_ENTRY ec_name ',' description + { add_ec($2, $4); + free($2); + free($4); } + | ERROR_CODE_ENTRY ec_name '=' STRING ',' description + { add_ec_val($2, $4, $6); + free($2); + free($4); + free($6); + } + ; + +ec_name : STRING + { $$ = ds($1); + current_token = $$; } + ; + +description : QUOTED_STRING + { $$ = ds($1); + current_token = $$; } + ; + +%% +/* + * Copyright 1986, 1987 by the MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + */ + +#include <stdlib.h> +#include <strings.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/time.h> +#include "error_table.h" + +extern FILE *hfile, *cfile; + +static long gensym_n = 0; +char * +gensym(x) + char *x; +{ + char *symbol; + if (!gensym_n) { + struct timeval tv; + struct timezone tzp; + gettimeofday(&tv, &tzp); + gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000; + } + symbol = malloc(32 * sizeof(char)); + gensym_n++; + sprintf(symbol, "et%ld", gensym_n); + return(symbol); +} + +char * +ds(string) + char *string; +{ + char *rv; + rv = malloc(strlen(string)+1); + strcpy(rv, string); + return(rv); +} + +char * +quote(string) + char *string; +{ + char *rv; + rv = malloc(strlen(string)+3); + strcpy(rv, "\""); + strcat(rv, string); + strcat(rv, "\""); + return(rv); +} + +int table_number; +int current = 0; +char **error_codes = (char **)NULL; + +add_ec(name, description) + char *name, *description; +{ + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +add_ec_val(name, val, description) + char *name, *val, *description; +{ + int ncurrent = atoi(val); + if (ncurrent < current) { + printf("Error code %s (%d) out of order", name, + current); + return; + } + + while (ncurrent > current) + fputs("\t(char *)NULL,\n", cfile), current++; + + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +put_ecs() +{ + int i; + for (i = 0; i < current; i++) { + if (error_codes[i] != (char *)NULL) + fprintf(hfile, "#define %-40s ((%s)%d)\n", + error_codes[i], ERROR_CODE, table_number + i); + } +} + +/* + * char_to_num -- maps letters and numbers into a small numbering space + * uppercase -> 1-26 + * lowercase -> 27-52 + * digits -> 53-62 + * underscore-> 63 + */ +int +char_to_num(c) + char c; +{ + if (isupper(c)) + return(c-'A'+1); + else if (islower(c)) + return(c-'a'+27); + else if (isdigit(c)) + return(c-'0'+53); + else { + fprintf(stderr, "Illegal character in name: %c\n", c); + exit(1); + /*NOTREACHED*/ + } +} + +set_table_num(string) + char *string; +{ + if (strlen(string) > 4) { + fprintf(stderr, "Table name %s too long, truncated ", + string); + string[4] = '\0'; + fprintf(stderr, "to %s\n", string); + } + while (*string != '\0') { + table_number = (table_number << BITS_PER_CHAR) + + char_to_num(*string); + string++; + } + table_number = table_number << ERRCODE_RANGE; +} + +#include "et_lex.lex.c" diff --git a/eBones/compile_et/et_lex.lex.l b/eBones/compile_et/et_lex.lex.l new file mode 100644 index 0000000..c041819 --- /dev/null +++ b/eBones/compile_et/et_lex.lex.l @@ -0,0 +1,29 @@ +%{ +extern int yylineno; +int yylineno = 1; +%} + +PC [^\"\n] +AN [A-Z_a-z0-9] +%% + +error_table return ERROR_TABLE; +et return ERROR_TABLE; +error_code return ERROR_CODE_ENTRY; +ec return ERROR_CODE_ENTRY; +end return END; + +[\t ]+ ; +\n ++yylineno; + +\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1); + if (p=rindex(yylval.dynstr, '"')) *p='\0'; + return QUOTED_STRING; + } + +{AN}* { yylval.dynstr = ds(yytext); return STRING; } + +#.*\n ++yylineno; + +. { return (*yytext); } +%% diff --git a/eBones/compile_et/et_name.c b/eBones/compile_et/et_name.c new file mode 100644 index 0000000..98ccb08 --- /dev/null +++ b/eBones/compile_et/et_name.c @@ -0,0 +1,44 @@ +/* + * Copyright 1987 by MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + * + * $Id: et_name.c,v 1.2 1994/07/19 19:21:27 g89r4222 Exp $ + */ + +#include "error_table.h" + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +char *malloc(); + +char * +error_table_name(num) + int num; +{ + register int ch; + register int i; + register char *buf, *p; + + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ + buf = malloc(5); + p = buf; + num >>= ERRCODE_RANGE; + /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ + num &= 077777777; + /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ + for (i = 0; i < 5; i++) { + ch = (num >> 24-6*i) & 077; + if (ch == 0) + continue; + else if (ch < 27) + *p++ = ch - 1 + 'A'; + else if (ch < 53) + *p++ = ch - 27 + 'a'; + else if (ch < 63) + *p++ = ch - 53 + '0'; + else /* ch == 63 */ + *p++ = '_'; + } + return(buf); +} + diff --git a/eBones/compile_et/init_et.c b/eBones/compile_et/init_et.c new file mode 100644 index 0000000..c23facb --- /dev/null +++ b/eBones/compile_et/init_et.c @@ -0,0 +1,67 @@ +/* + * Copyright 1986 by MIT Information Systems and + * MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + * + * form: init_et.c,v 1.1 86/11/10 21:42:26 spook Exp $ + * $Id: init_et.c,v 1.2 1994/07/19 19:21:28 g89r4222 Exp $ + */ + +#include <stdio.h> +#include "error_table.h" + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +extern char *malloc(), *realloc(); + +/* useful */ +typedef error_table *etp; +typedef etp *etpp; + +etpp _et_list = (etpp)NULL; +static int n_allocated = 0, n_used = 0; + +int +init_error_table(msgs, base, count) + char **msgs; + register int base; + int count; +{ + register int i; + register etp new_et; + register etpp list; + + if (!base || !count || !msgs) + return; + + new_et = (etp)malloc(sizeof(error_table)); + new_et->msgs = msgs; + new_et->base = base; + new_et->n_msgs= count; + + list = _et_list; + if (list == (etpp)NULL) { + _et_list = (etpp) malloc(10*sizeof(etp)); + list = _et_list; + if (list == (etpp)NULL) + return; /* oops */ + list[0] = new_et; + list[1] = (etp)NULL; + n_allocated = 10; + n_used = 1; + return; + } + for (i = 0; i < n_used; i++) + if (list[i]->base == base) + return; /* avoid duplicates */ + if (n_used+2 > n_allocated) { + n_allocated += 10; /* don't re-allocate too often */ + list = (etpp) realloc((char *)list, + (unsigned)n_allocated * sizeof(etp)); + _et_list = list; + if (list == (etpp)NULL) + return; /* oops */ + } + list[n_used++] = new_et; + list[n_used] = (etp)NULL; +} diff --git a/eBones/compile_et/perror.c b/eBones/compile_et/perror.c new file mode 100644 index 0000000..ef50e07 --- /dev/null +++ b/eBones/compile_et/perror.c @@ -0,0 +1,76 @@ +/* + * Copyright 1987 by MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB + * + * $Id: perror.c,v 1.2 1994/07/19 19:21:30 g89r4222 Exp $ + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/uio.h> +#include "error_table.h" + +typedef int (*int_func)(); + +#if defined(mips) && defined(ultrix) +int errno; /* this is needed to keep the loader from complaining */ +#endif + +int_func com_err_hook = (int_func) NULL; +char *error_message(); + +void +com_err(whoami, code, message) + char *whoami; + int code; + char *message; +{ + struct iovec strings[6]; + + if (com_err_hook) { + (*com_err_hook)(whoami, code, message); + return; + } + + strings[0].iov_base = whoami; + strings[0].iov_len = strlen(whoami); + if (whoami) { + strings[1].iov_base = ": "; + strings[1].iov_len = 2; + } else + strings[1].iov_len = 0; + if (code) { + register char *errmsg = error_message(code); + strings[2].iov_base = errmsg; + strings[2].iov_len = strlen(errmsg); + } else + strings[2].iov_len = 0; + strings[3].iov_base = " "; + strings[3].iov_len = 1; + strings[4].iov_base = message; + strings[4].iov_len = strlen(message); + strings[5].iov_base = "\n"; + strings[5].iov_len = 1; + (void) writev(2, strings, 6); +} + +int_func +set_com_err_hook(new_proc) + int_func new_proc; +{ + register int_func x = com_err_hook; + com_err_hook = new_proc; + return (x); +} + +reset_com_err_hook() +{ + com_err_hook = (int_func) NULL; +} + +void +perror(msg) + register const char *msg; +{ + com_err(msg, errno, (char *)NULL); +} diff --git a/eBones/compile_et/test/test.c b/eBones/compile_et/test/test.c new file mode 100644 index 0000000..df430da --- /dev/null +++ b/eBones/compile_et/test/test.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <errno.h> +#include "test1.h" +#include "test2.h" +char *error_message(); +extern int sys_nerr, errno; + +main() +{ + printf("\nBefore initiating error table:\n\n"); + printf("Table name '%s'\n", error_table_name(KRB_MK_AP_TGTEXP)); + printf("UNIX name '%s'\n", error_table_name(EPERM)); + printf("Msg TGT-expired is '%s'\n", error_message(KRB_MK_AP_TGTEXP)); + printf("Msg EPERM is '%s'\n", error_message(EPERM)); + printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR)); + printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1)); + printf("Msg {sys_nerr} is '%s'\n", error_message(sys_nerr)); + + init_error_table(0, 0, 0); + printf("With 0: tgt-expired -> %s\n", error_message(KRB_MK_AP_TGTEXP)); + + init_krb_err_tbl(); + printf("KRB error table initialized: base %d (%s), name %s\n", + krb_err_base, error_message(krb_err_base), + error_table_name(krb_err_base)); + printf("With krb: tgt-expired -> %s\n", + error_message(KRB_MK_AP_TGTEXP)); + + init_quux_err_tbl(); + printf("QUUX error table initialized: base %d (%s), name %s\n", + quux_err_base, error_message(quux_err_base), + error_table_name(quux_err_base)); + + printf("Msg for TGT-expired is '%s'\n", + error_message(KRB_MK_AP_TGTEXP)); + printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1)); + printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR)); + printf("Msg KRB_SKDC_CANT is '%s'\n", + error_message(KRB_SKDC_CANT)); + printf("Msg 1e6 is '%s'\n", error_message(1000000)); + errno = FOO_ERR; + perror("FOO_ERR"); +} diff --git a/eBones/compile_et/test/test1.et b/eBones/compile_et/test/test1.et new file mode 100644 index 0000000..4c7b77f --- /dev/null +++ b/eBones/compile_et/test/test1.et @@ -0,0 +1,69 @@ + error_table krb + + error_code KRB_MK_AP_TKFIL, + "Can't read ticket file" + + ec KRB_MK_AP_NOTKT, + "Can't find ticket or TGT" + + ec KRB_MK_AP_TGTEXP, + "TGT expired" + + ec KRB_RD_AP_UNDEC, + "Can't decode authenticator" + + ec KRB_RD_AP_EXP, + "Ticket expired" + + ec KRB_RD_AP_REPEAT, + "Repeated request" + + ec KRB_RD_AP_NOT_US, + "The ticket isn't for us" + + ec KRB_RD_AP_INCON, + "Request is inconsistent" + + ec KRB_RD_AP_TIME, + "Delta-T too big" + + ec KRB_RD_AP_BADD, + "Incorrect net address" + + ec KRB_RD_AP_VERSION, + "Protocol version mismatch" + + ec KRB_RD_AP_MSG_TYPE, + "Invalid message type" + + ec KRB_RD_AP_MODIFIED, + "Message stream modified" + + ec KRB_RD_AP_ORDER, + "Message out of order" + + ec KRB_RD_AP_UNAUTHOR, + "Unauthorized request" + + ec KRB_GT_PW_NULL, + "Current password is null" + + ec KRB_GT_PW_BADPW, + "Incorrect current password" + + ec KRB_GT_PW_PROT, + "Protocol error" + + ec KRB_GT_PW_KDCERR, + "Error returned by KDC" + + ec KRB_GT_PW_NULLTKT, + "Null ticket returned by KDC" + + ec KRB_SKDC_RETRY, + "Retry count exceeded" + + ec KRB_SKDC_CANT, + "Can't send request" + + end diff --git a/eBones/compile_et/test/test2.et b/eBones/compile_et/test/test2.et new file mode 100644 index 0000000..55ad74e --- /dev/null +++ b/eBones/compile_et/test/test2.et @@ -0,0 +1,9 @@ + error_table quux + + ec FOO_ERR, "foo" + + ec BAR_ERR, "bar" + + ec BAZ_ERR, "meow" + + end diff --git a/eBones/des/3cbc_enc.c b/eBones/des/3cbc_enc.c new file mode 100644 index 0000000..231cff5 --- /dev/null +++ b/eBones/des/3cbc_enc.c @@ -0,0 +1,58 @@ +/* 3cbc_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: 3cbc_enc.c,v 1.2 1994/07/19 19:21:37 g89r4222 Exp $ + */ + +#include "des_locl.h" + +int des_3cbc_encrypt(input,output,length,ks1,ks2,iv1,iv2,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule ks1,ks2; +des_cblock *iv1,*iv2; +int encrypt; + { + int off=length/8-1; + des_cblock niv1,niv2; + +printf("3cbc\n"); +xp(iv1); +xp(iv1); +xp(iv2); +xp(input); + if (encrypt == DES_ENCRYPT) + { + des_cbc_encrypt(input,output,length,ks1,iv1,encrypt); + if (length >= sizeof(des_cblock)) + bcopy(output[off],niv1,sizeof(des_cblock)); + des_cbc_encrypt(output,output,length,ks2,iv1,!encrypt); + des_cbc_encrypt(output,output,length,ks1,iv2, encrypt); + if (length >= sizeof(des_cblock)) + bcopy(output[off],niv2,sizeof(des_cblock)); + bcopy(niv1,*iv1,sizeof(des_cblock)); + } + else + { + if (length >= sizeof(des_cblock)) + bcopy(input[off],niv1,sizeof(des_cblock)); + des_cbc_encrypt(input,output,length,ks1,iv1,encrypt); + des_cbc_encrypt(output,output,length,ks2,iv2,!encrypt); + if (length >= sizeof(des_cblock)) + bcopy(output[off],niv2,sizeof(des_cblock)); + des_cbc_encrypt(output,output,length,ks1,iv2, encrypt); + } + bcopy(niv1,iv1,sizeof(des_cblock)); + bcopy(niv2,iv2,sizeof(des_cblock)); +xp(iv1); +xp(iv1); +xp(iv2); +xp(output); + return(0); + } + +xp(a) +unsigned char *a; +{ int i; for(i=0; i<8; i++) printf("%02X",a[i]);printf("\n");} diff --git a/eBones/des/3ecb_enc.c b/eBones/des/3ecb_enc.c new file mode 100644 index 0000000..1081f9d --- /dev/null +++ b/eBones/des/3ecb_enc.c @@ -0,0 +1,35 @@ +/* 3ecb_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: 3ecb_enc.c,v 1.2 1994/07/19 19:21:38 g89r4222 Exp $ + */ + +#include "des_locl.h" + +int des_3ecb_encrypt(input,output,ks1,ks2,encrypt) +des_cblock *input; +des_cblock *output; +des_key_schedule ks1,ks2; +int encrypt; + { + register unsigned long l0,l1,t; + register unsigned char *in,*out; + unsigned long ll[2]; + + in=(unsigned char *)input; + out=(unsigned char *)output; + c2l(in,l0); + c2l(in,l1); + ll[0]=l0; + ll[1]=l1; + des_encrypt(ll,ll,ks1,encrypt); + des_encrypt(ll,ll,ks2,!encrypt); + des_encrypt(ll,ll,ks1,encrypt); + l0=ll[0]; + l1=ll[1]; + l2c(l0,out); + l2c(l1,out); + return(0); + } + diff --git a/eBones/des/MISSING b/eBones/des/MISSING new file mode 100644 index 0000000..bffc690 --- /dev/null +++ b/eBones/des/MISSING @@ -0,0 +1,17 @@ +# $Id: MISSING,v 1.2 1994/07/19 19:21:40 g89r4222 Exp $ + +The following symbols (you can find in the USA libdes) are still missing +in this source. + +_des_cblock_print_file +_des_generate_random_block +_des_init_random_number_generator +_des_new_random_key +_des_set_random_generator_seed +_des_set_sequence_number +_des_check_key_parity +_des_fixup_key_parity +_des_debug + +# END + diff --git a/eBones/des/Makefile b/eBones/des/Makefile new file mode 100644 index 0000000..5afd5b5 --- /dev/null +++ b/eBones/des/Makefile @@ -0,0 +1,27 @@ +# @(#)Makefile 5.4 (Berkeley) 5/7/91 +# $Id: Makefile,v 1.4 1994/09/09 21:43:30 g89r4222 Exp $ + +LIB= des +SRCS= cbc_cksm.c cbc_enc.c ecb_enc.c enc_read.c enc_writ.c pcbc_enc.c \ + qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \ + cfb_enc.c 3ecb_enc.c ofb_enc.c 3cbc_enc.c +#MAN1= des.1 +#MAN3= des.3 + +#LINKS= crypt +CFLAGS+= -DDES_ENCRYPT -DKRBDES_ENCRYPT + +# Kerberos 4? +#CFLAGS+=-DKRB4 +#SRCS+= kerberos.c + +# Kerberos 5? +#CFLAGS+= -DKRB5 +#SRCS+= kerberos5.c + +CFLAGS+= -I${.CURDIR}/include -DAUTHENTICATE +SHLIB_MAJOR?= 2 +SHLIB_MINOR?= 0 + +.include "/usr/src/lib/Makefile.inc" +.include <bsd.lib.mk> diff --git a/eBones/des/cbc_cksm.c b/eBones/des/cbc_cksm.c new file mode 100644 index 0000000..b28dc75 --- /dev/null +++ b/eBones/des/cbc_cksm.c @@ -0,0 +1,55 @@ +/* cbc_cksm.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: cbc_cksm.c,v 1.2 1994/07/19 19:21:45 g89r4222 Exp $ + */ + +#include "des_locl.h" + +unsigned long des_cbc_cksum(input,output,length,schedule,ivec) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; + { + register unsigned long tout0,tout1,tin0,tin1; + register long l=length; + unsigned long tin[2],tout[2]; + unsigned char *in,*out,*iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + c2l(iv,tout0); + c2l(iv,tout1); + for (; l>0; l-=8) + { + if (l >= 8) + { + c2l(in,tin0); + c2l(in,tin1); + } + else + c2ln(in,tin0,tin1,l); + + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + des_encrypt((unsigned long *)tin,(unsigned long *)tout, + schedule,DES_ENCRYPT); + /* fix 15/10/91 eay - thanks to keithr@sco.COM */ + tout0=tout[0]; + tout1=tout[1]; + } + if (out != NULL) + { + l2c(tout0,out); + l2c(tout1,out); + } + tout0=tin0=tin1=tin[0]=tin[1]=tout[0]=tout[1]=0; + return(tout1); + } diff --git a/eBones/des/cbc_enc.c b/eBones/des/cbc_enc.c new file mode 100644 index 0000000..c2ebd3a --- /dev/null +++ b/eBones/des/cbc_enc.c @@ -0,0 +1,83 @@ +/* cbc_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: cbc_enc.c,v 1.2 1994/07/19 19:21:47 g89r4222 Exp $ + */ + +#include "des_locl.h" + +int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; + { + register unsigned long tin0,tin1; + register unsigned long tout0,tout1,xor0,xor1; + register unsigned char *in,*out; + register long l=length; + unsigned long tout[2],tin[2]; + unsigned char *iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + if (encrypt) + { + c2l(iv,tout0); + c2l(iv,tout1); + for (; l>0; l-=8) + { + if (l >= 8) + { + c2l(in,tin0); + c2l(in,tin1); + } + else + c2ln(in,tin0,tin1,l); + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + des_encrypt((unsigned long *)tin,(unsigned long *)tout, + schedule,encrypt); + tout0=tout[0]; + tout1=tout[1]; + l2c(tout0,out); + l2c(tout1,out); + } + } + else + { + c2l(iv,xor0); + c2l(iv,xor1); + for (; l>0; l-=8) + { + c2l(in,tin0); + c2l(in,tin1); + tin[0]=tin0; + tin[1]=tin1; + des_encrypt((unsigned long *)tin,(unsigned long *)tout, + schedule,encrypt); + tout0=tout[0]^xor0; + tout1=tout[1]^xor1; + if (l >= 8) + { + l2c(tout0,out); + l2c(tout1,out); + } + else + l2cn(tout0,tout1,out,l); + xor0=tin0; + xor1=tin1; + } + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=tout[0]=tout[1]=0; + return(0); + } + diff --git a/eBones/des/cfb_enc.c b/eBones/des/cfb_enc.c new file mode 100644 index 0000000..367da5f --- /dev/null +++ b/eBones/des/cfb_enc.c @@ -0,0 +1,110 @@ +/* cfb_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: cfb_enc.c,v 1.2 1994/07/19 19:21:48 g89r4222 Exp $ + */ + +#include "des_locl.h" + +/* The input and output are loaded in multiples of 8 bits. + * What this means is that if you hame numbits=12 and length=2 + * the first 12 bits will be retrieved from the first byte and half + * the second. The second 12 bits will come from the 3rd and half the 4th + * byte. + */ +int des_cfb_encrypt(in,out,numbits,length,schedule,ivec,encrypt) +unsigned char *in,*out; +int numbits; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; + { + register unsigned long d0,d1,v0,v1,n=(numbits+7)/8; + register unsigned long mask0,mask1; + register long l=length; + register int num=numbits; + unsigned long ti[2],to[2]; + unsigned char *iv; + + if (num > 64) return(0); + if (num > 32) + { + mask0=0xffffffff; + if (num == 64) + mask1=mask0; + else + mask1=(1L<<(num-32))-1; + } + else + { + if (num == 32) + mask0=0xffffffff; + else + mask0=(1L<<num)-1; + mask1=0x00000000; + } + + iv=(unsigned char *)ivec; + c2l(iv,v0); + c2l(iv,v1); + if (encrypt) + { + while (l-- > 0) + { + ti[0]=v0; + ti[1]=v1; + des_encrypt((unsigned long *)ti,(unsigned long *)to, + schedule,DES_ENCRYPT); + c2ln(in,d0,d1,n); + in+=n; + d0=(d0^to[0])&mask0; + d1=(d1^to[1])&mask1; + l2cn(d0,d1,out,n); + out+=n; + if (num > 32) + { + v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff; + v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff; + } + else + { + v0=((v0>>num)|(v1<<(32-num)))&0xffffffff; + v1=((v1>>num)|(d0<<(32-num)))&0xffffffff; + } + } + } + else + { + while (l-- > 0) + { + ti[0]=v0; + ti[1]=v1; + des_encrypt((unsigned long *)ti,(unsigned long *)to, + schedule,DES_ENCRYPT); + c2ln(in,d0,d1,n); + in+=n; + if (num > 32) + { + v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff; + v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff; + } + else + { + v0=((v0>>num)|(v1<<(32-num)))&0xffffffff; + v1=((v1>>num)|(d0<<(32-num)))&0xffffffff; + } + d0=(d0^to[0])&mask0; + d1=(d1^to[1])&mask1; + l2cn(d0,d1,out,n); + out+=n; + } + } + iv=(unsigned char *)ivec; + l2c(v0,iv); + l2c(v1,iv); + v0=v1=d0=d1=ti[0]=ti[1]=to[0]=to[1]=0; + return(0); + } + diff --git a/eBones/des/des.3 b/eBones/des/des.3 new file mode 100644 index 0000000..280860d --- /dev/null +++ b/eBones/des/des.3 @@ -0,0 +1,503 @@ +.\" $Id: des.3,v 1.2 1994/07/19 19:21:50 g89r4222 Exp $ +.TH DES_CRYPT 3 +.SH NAME +des_read_password, des_read_2password, +des_string_to_key, des_string_to_2key, des_read_pw_string, +des_random_key, des_set_key, +des_key_sched, des_ecb_encrypt, des_3ecb_encrypt, des_cbc_encrypt, +des_3cbc_encrypt, +des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt, +des_cbc_cksum, des_quad_cksum, +des_enc_read, des_enc_write, des_set_odd_parity, +des_is_weak_key, crypt \- (non USA) DES encryption +.SH SYNOPSIS +.nf +.nj +.ft B +#include <des.h> +.PP +.B int des_read_password(key,prompt,verify) +des_cblock *key; +char *prompt; +int verify; +.PP +.B int des_read_2password(key1,key2,prompt,verify) +des_cblock *key1,*key2; +char *prompt; +int verify; +.PP +.B int des_string_to_key(str,key) +char *str; +des_cblock *key; +.PP +.B int des_string_to_2keys(str,key1,key2) +char *str; +des_cblock *key1,*key2; +.PP +.B int des_read_pw_string(buf,length,prompt,verify) +char *buf; +int length; +char *prompt; +int verify; +.PP +.B int des_random_key(key) +des_cblock *key; +.PP +.B int des_set_key(key,schedule) +des_cblock *key; +des_key_schedule schedule; +.PP +.B int des_key_sched(key,schedule) +des_cblock *key; +des_key_schedule schedule; +.PP +.B int des_ecb_encrypt(input,output,schedule,encrypt) +des_cblock *input; +des_cblock *output; +des_key_schedule schedule; +int encrypt; +.PP +.B int des_3ecb_encrypt(input,output,ks1,ks2,encrypt) +des_cblock *input; +des_cblock *output; +des_key_schedule ks1,ks2; +int encrypt; +.PP +.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; +.PP +.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule sk1; +des_key_schedule sk2; +des_cblock *ivec1; +des_cblock *ivec2; +int encrypt; +.PP +.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; +.PP +.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt) +unsigned char *input; +unsigned char *output; +int numbits; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; +.PP +.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec) +unsigned char *input,*output; +int numbits; +long length; +des_key_schedule schedule; +des_cblock *ivec; +.PP +.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +.PP +.B unsigned long des_quad_cksum(input,output,length,out_count,seed) +des_cblock *input; +des_cblock *output; +long length; +int out_count; +des_cblock *seed; +.PP +.B int des_check_key; +.PP +.B int des_enc_read(fd,buf,len,sched,iv) +int fd; +char *buf; +int len; +des_key_schedule sched; +des_cblock *iv; +.PP +.B int des_enc_write(fd,buf,len,sched,iv) +int fd; +char *buf; +int len; +des_key_schedule sched; +des_cblock *iv; +.PP +.B extern int des_rw_mode; +.PP +.B void des_set_odd_parity(key) +des_cblock *key; +.PP +.B int des_is_weak_key(key) +des_cblock *key; +.PP +.B char *crypt(passwd,salt) +char *passwd; +char *salt; +.PP +.fi +.SH DESCRIPTION +This library contains a fast implementation of the DES encryption +algorithm. +.PP +There are two phases to the use of DES encryption. +The first is the generation of a +.I des_key_schedule +from a key, +the second is the actual encryption. +A des key is of type +.I des_cblock. +This type is made from 8 characters with odd parity. +The least significant bit in the character is the parity bit. +The key schedule is an expanded form of the key; it is used to speed the +encryption process. +.PP +.I des_read_password +writes the string specified by prompt to the standard output, +turns off echo and reads an input string from standard input +until terminated with a newline. +If verify is non-zero, it prompts and reads the input again and verifies +that both entered passwords are the same. +The entered string is converted into a des key by using the +.I des_string_to_key +routine. +The new key is placed in the +.I des_cblock +that was passed (by reference) to the routine. +If there were no errors, +.I des_read_password +returns 0, +-1 is returned if there was a terminal error and 1 is returned for +any other error. +.PP +.I des_read_2password +operates in the same way as +.I des_read_password +except that it generates 2 keys by using the +.I des_string_to_2key +function. +.PP +.I des_read_pw_string +is called by +.I des_read_password +to read and verify a string from a terminal device. +The string is returned in +.I buf. +The size of +.I buf +is passed to the routine via the +.I length +parameter. +.PP +.I des_string_to_key +converts a string into a valid des key. +.PP +.I des_string_to_2key +converts a string into 2 valid des keys. +This routine is best suited for used to generate keys for use with +.I des_3ecb_encrypt. +.PP +.I des_random_key +returns a random key that is made of a combination of process id, +time and an increasing counter. +.PP +Before a des key can be used it is converted into a +.I des_key_schedule +via the +.I des_set_key +routine. +If the +.I des_check_key +flag is non-zero, +.I des_set_key +will check that the key passed is of odd parity and is not a week or +semi-weak key. +If the parity is wrong, +then -1 is returned. +If the key is a weak key, +then -2 is returned. +If an error is returned, +the key schedule is not generated. +.PP +.I des_key_sched +is another name for the +.I des_set_key +function. +.PP +The following routines mostly operate on an input and output stream of +.I des_cblock's. +.PP +.I des_ecb_encrypt +is the basic DES encryption routine that encrypts or decrypts a single 8-byte +.I des_cblock +in +.I electronic code book +mode. +It always transforms the input data, pointed to by +.I input, +into the output data, +pointed to by the +.I output +argument. +If the +.I encrypt +argument is non-zero (DES_ENCRYPT), +the +.I input +(cleartext) is encrypted in to the +.I output +(ciphertext) using the key_schedule specified by the +.I schedule +argument, +previously set via +.I des_set_key. +If +.I encrypt +is zero (DES_DECRYPT), +the +.I input +(now ciphertext) +is decrypted into the +.I output +(now cleartext). +Input and output may overlap. +No meaningful value is returned. +.PP +.I des_3ecb_encrypt +encrypts/decrypts the +.I input +block by using triple ecb DES encryption. +This involves encrypting the input with +.I ks1, +decryption with the key schedule +.I ks2, +and then encryption with the first again. +This routine greatly reduces the chances of brute force breaking of +DES and has the advantage of if +.I ks1 +and +.I ks2 +are the same, it is equivalent to just encryption using ecb mode and +.I ks1 +as the key. +.PP +.I des_cbc_encrypt +encrypts/decrypts using the +.I cipher-block-chaining +mode of DES. +If the +.I encrypt +argument is non-zero, +the routine cipher-block-chain encrypts the cleartext data pointed to by the +.I input +argument into the ciphertext pointed to by the +.I output +argument, +using the key schedule provided by the +.I schedule +argument, +and initialisation vector provided by the +.I ivec +argument. +If the +.I length +argument is not an integral multiple of eight bytes, +the last block is copied to a temporary area and zero filled. +The output is always +an integral multiple of eight bytes. +To make multiple cbc encrypt calls on a large amount of data appear to +be one +.I des_cbc_encrypt +call, the +.I ivec +of subsequent calls should be the last 8 bytes of the output. +.PP +.I des_3cbc_encrypt +encrypts/decrypts the +.I input +block by using triple cbc DES encryption. +This involves encrypting the input with key schedule +.I ks1, +decryption with the key schedule +.I ks2, +and then encryption with the first again. +2 initialisation vectors are required, +.I ivec1 +and +.I ivec2. +Unlike +.I des_cbc_encrypt, +these initialisation vectors are modified by the subroutine. +This routine greatly reduces the chances of brute force breaking of +DES and has the advantage of if +.I ks1 +and +.I ks2 +are the same, it is equivalent to just encryption using cbc mode and +.I ks1 +as the key. +.PP +.I des_pcbc_encrypt +encrypt/decrypts using a modified block chaining mode. +It provides better error propagation characteristics than cbc +encryption. +.PP +.I des_cfb_encrypt +encrypt/decrypts using cipher feedback mode. This method takes an +array of characters as input and outputs and array of characters. It +does not require any padding to 8 character groups. Note: the ivec +variable is changed and the new changed value needs to be passed to +the next call to this function. Since this function runs a complete +DES ecb encryption per numbits, this function is only suggested for +use when sending small numbers of characters. +.PP +.I des_ofb_encrypt +encrypt using output feedback mode. This method takes an +array of characters as input and outputs and array of characters. It +does not require any padding to 8 character groups. Note: the ivec +variable is changed and the new changed value needs to be passed to +the next call to this function. Since this function runs a complete +DES ecb encryption per numbits, this function is only suggested for +use when sending small numbers of characters. +.PP +.I des_cbc_cksum +produces an 8 byte checksum based on the input stream (via cbc encryption). +The last 4 bytes of the checksum is returned and the complete 8 bytes is +placed in +.I output. +.PP +.I des_quad_cksum +returns a 4 byte checksum from the input bytes. +The algorithm can be iterated over the input, +depending on +.I out_count, +1, 2, 3 or 4 times. +If +.I output +is non-NULL, +the 8 bytes generated by each pass are written into +.I output. +.PP +.I des_enc_write +is used to write +.I len +bytes +to file descriptor +.I fd +from buffer +.I buf. +The data is encrypted via +.I pcbc_encrypt +(default) using +.I sched +for the key and +.I iv +as a starting vector. +The actual data send down +.I fd +consists of 4 bytes (in network byte order) containing the length of the +following encrypted data. The encrypted data then follows, padded with random +data out to a multiple of 8 bytes. +.PP +.I des_enc_read +is used to read +.I len +bytes +from file descriptor +.I fd +into buffer +.I buf. +The data being read from +.I fd +is assumed to have come from +.I des_enc_write +and is decrypted using +.I sched +for the key schedule and +.I iv +for the initial vector. +The +.I des_enc_read/des_enc_write +pair can be used to read/write to files, pipes and sockets. +I have used them in implementing a version of rlogin in which all +data is encrypted. +.PP +.I des_rw_mode +is used to specify the encryption mode to use with +.I des_enc_read +and +.I des_end_write. +If set to +.I DES_PCBC_MODE +(the default), des_pcbc_encrypt is used. +If set to +.I DES_CBC_MODE +des_cbc_encrypt is used. +These two routines and the variable are not part of the normal MIT library. +.PP +.I des_set_odd_parity +sets the parity of the passed +.I key +to odd. This routine is not part of the standard MIT library. +.PP +.I des_is_weak_key +returns 1 is the passed key is a weak key (pick again :-), +0 if it is ok. +This routine is not part of the standard MIT library. +.PP +.I crypt +is a replacement for the normal system crypt. +It is much faster than the system crypt. +.PP +.SH FILES +/usr/include/des.h +.br +/usr/lib/libdes.a +.PP +The encryption routines have been tested on 16bit, 32bit and 64bit +machines of various endian and even works under VMS. +.PP +.SH BUGS +.PP +If you think this manual is sparse, +read the des_crypt(3) manual from the MIT kerberos (or bones outside +of the USA) distribution. +.PP +.I des_cfb_encrypt +and +.I des_ofb_encrypt +operates on input of 8 bits. What this means is that if you set +numbits to 12, and length to 2, the first 12 bits will come from the 1st +input byte and the low half of the second input byte. The second 12 +bits will have the low 8 bits taken from the 3rd input byte and the +top 4 bits taken from the 4th input byte. The same holds for output. +This function has been implemented this way because most people will +be using a multiple of 8 and because once you get into pulling bytes input +bytes apart things get ugly! +.PP +.I des_read_pw_string +is the most machine/OS dependent function and normally generates the +most problems when porting this code. +.PP +.I des_string_to_key +is probably different from the MIT version since there are lots +of fun ways to implement one-way encryption of a text string. +.PP +The routines are optimised for 32 bit machines and so are not efficient +on IBM PCs. +.SH AUTHOR +Eric Young (eay@psych.psy.uq.oz.au), +Psychology Department, +University of Queensland, Australia. diff --git a/eBones/des/docs.original/ARTISTIC b/eBones/des/docs.original/ARTISTIC new file mode 100644 index 0000000..b382657 --- /dev/null +++ b/eBones/des/docs.original/ARTISTIC @@ -0,0 +1,105 @@ + + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. + +6. Any programs linked with this library do not automatically fall +under the copyright of this Package, but belong to whomever generated +them, and may be sold commercially, and may be aggregated with this +Package. + +7. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +8. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End + diff --git a/eBones/des/docs.original/CHANGES b/eBones/des/docs.original/CHANGES new file mode 100644 index 0000000..4f441fa --- /dev/null +++ b/eBones/des/docs.original/CHANGES @@ -0,0 +1,16 @@ +The main changes in this package since it was last posted to +comp.sources.misc are + +The main changes are +- Major changes to the Copyright restrictions. +- Lots and lots of features added to the des(1) command, including + - Triple DES, both triple ECB and triple CBC options. + - uuencodeing/uudecoding built in to des(1). + - generate checksums. + - hex keys. +- Cleaned up the prototypes in des.h +- Filenames are now mostly <= 8 characters long. +- OFB, CFB, triple ECB and triple CBC modes of DES added to the library. +- Compiles and runs of all 64bit machines I could test the code on + (Cray, ETA10, DEC Alpha). +- It really does work with kerberos v 4 now :-). diff --git a/eBones/des/docs.original/COPYING b/eBones/des/docs.original/COPYING new file mode 100644 index 0000000..9b1a932 --- /dev/null +++ b/eBones/des/docs.original/COPYING @@ -0,0 +1,489 @@ +Copyright (C) 1993 Eric Young + +This is a DES implementation written by Eric Young (eay@psych.psy.uq.oz.au) +The implementation was written so as to conform with the manual entry +for the des_crypt(3) library routines from MIT's project Athena. + + + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/eBones/des/docs.original/FILES b/eBones/des/docs.original/FILES new file mode 100644 index 0000000..a010ad1 --- /dev/null +++ b/eBones/des/docs.original/FILES @@ -0,0 +1,60 @@ +/* General stuff */ +CHANGES - Changes since the last posting to comp.sources.misc. +ARTISTIC - Copying info. +COPYING - Copying info. +MODES.DES - A description of the features of the different modes of DES. +FILES - This file. +INSTALL - How to make things compile. +Imakefile - For use with kerberos. +README - What this package is. +VERSION - Which version this is. +KERBEROS - Kerberos version 4 notes. +makefile - The make file. +times - Some outputs from 'speed' on my local machines. +vms.com - For use when compiling under VMS + +/* My sunOS des(1) replacement */ +des.c - des(1) source code. +des.man - des(1) manual. + +/* Testing and timing programs. */ +destest.c - Source for libdes.a test program. +speed.c - Source for libdes.a timing program. +rpw.c - Source for libdes.a testing password reading routines. + +/* libdes.a source code */ +des_crypt.man - libdes.a manual page. +des.h - Public libdes.a header file. +ecb_enc.c - des_ecb_encrypt() source, this contains the basic DES code. +3ecb_enc.c - des_3ecb_encrypt() source. +cbc_ckm.c - des_cbc_cksum() source. +cbc_enc.c - des_cbc_encrypt() source. +3cbc_enc.c - des_3cbc_encrypt() source. +cfb_enc.c - des_cfb_encrypt() source. +ofb_enc.c - des_cfb_encrypt() source. +enc_read.c - des_enc_read() source. +enc_writ.c - des_enc_write() source. +pcbc_enc.c - des_pcbc_encrypt() source. +qud_cksm.c - quad_cksum() source. +rand_key.c - des_random_key() source. +read_pwd.c - Source for des_read_password() plus related functions. +set_key.c - Source for des_set_key(). +str2key.c - Covert a string of any length into a key. +fcrypt.c - A small, fast version of crypt(3). +des_locl.h - Internal libdes.a header file. +podd.h - Odd parity tables - used in des_set_key(). +sk.h - Lookup tables used in des_set_key(). +spr.h - What is left of the S tables - used in ecb_encrypt(). + +/* The perl scripts - you can ignore these files they are only + * included for the curious */ +des.pl - des in perl anyone? des_set_key and des_ecb_encrypt + both done in a perl library. +testdes.pl - Testing program for des.pl +doIP - Perl script used to develop IP xor/shift code. +doPC1 - Perl script used to develop PC1 xor/shift code. +doPC2 - Generates sk.h. +PC1 - Output of doPC1 should be the same as output from PC1. +PC2 - used in development of doPC2. +shifts.pl - Perl library used by my perl scripts. + diff --git a/eBones/des/docs.original/INSTALL b/eBones/des/docs.original/INSTALL new file mode 100644 index 0000000..d34debe --- /dev/null +++ b/eBones/des/docs.original/INSTALL @@ -0,0 +1,53 @@ +Check the CC and CFLAGS lines in the makefile + +If your C library does not support the times(3) function, change the +#define TIMES to +#undef TIMES in speed.c +If it does, check the HZ value for the times(3) function. +If your system does not define CLK_TCK it will be assumed to +be 60. + +If possible use gcc v 2.2.2 +Turn on the maximum optimising + +type 'make' + +run './destest' to check things are ok. +run './rpw' to check the tty code for reading passwords works. +run './speed' to see how fast those optimisations make the library run :-) + +A make install will by default install +libdes.a in /usr/local/lib/libdes.a +des in /usr/local/bin/des +des_crypt.man in /usr/local/man/man3/des_crypt.3 +des.man in /usr/local/man/man1/des.1 +des.h in /usr/include/des.h + +des(1) should be compatible with sunOS's but I have been unable to +test it. + +These routines should compile on MSDOS, most 32bit and 64bit version +of Unix (BSD and SYSV) and VMS, without modification. +The only problems should be #include files that are in the wrong places. + +These routines can be compiled under MSDOS. +I have successfully encrypted files using des(1) under MSDOS and then +decrypted the files on a SparcStation. +I have been able to compile and test the routines with +Microsoft C v 5.1 and Turbo C v 2.0. +The code in this library is in no way optimised for the 16bit +operation of MSDOS. Microsoft C generates code that is 40% slower +than Turbo C's code. I believe this is due to problems it has with +code generation with the 32bit shift operation in the IP and FP +sections. I have added some 16bit optimization in ecb_encrypt.c +and this generated a %70 speedup under Turbo C. Such are the +limitations of DOS compilers :-(. + +For Turbo C v 2.0, make sure to define MSDOS, in the relevant menu. + +There is an alternative version of the D_ENCRYPT macro that can be +enabled with the -DALT_ECB option in the makefile. This alternative +macro can make a +-%20 speed difference to the DES encryption speed, +depending on the compiler/CPU combinations. +It has its greatest effect on Sparc machines when using the sun compiler. +If in doubt, try enable/disable it and running speed. diff --git a/eBones/des/docs.original/KERBEROS b/eBones/des/docs.original/KERBEROS new file mode 100644 index 0000000..d8734b2 --- /dev/null +++ b/eBones/des/docs.original/KERBEROS @@ -0,0 +1,38 @@ +To use this library with Bones (kerberos without DES): +1) Get my modified Bones - eBones. It can be found on + gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z + and + nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z + +2) Unpack this library in src/lib/des, makeing sure it is version + 3.00 or greater (libdes.tar.93-10-07.Z). This versions differences + from the version in comp.sources.misc volume 29 patchlevel2. + The primarily difference is that it should compile under kerberos :-). + It can be found at. + ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z + +Now do a normal kerberos build and things should work. + +One problem I found when I was build on my local sun. +--- +For sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c + +*** make_commands.c.orig Fri Jul 3 04:18:35 1987 +--- make_commands.c Wed May 20 08:47:42 1992 +*************** +*** 98,104 **** + if (!rename(o_file, z_file)) { + if (!vfork()) { + chdir("/tmp"); +! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n", + z_file+5, 0); + perror("/bin/ld"); + _exit(1); +--- 98,104 ---- + if (!rename(o_file, z_file)) { + if (!vfork()) { + chdir("/tmp"); +! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", + z_file+5, 0); + perror("/bin/ld"); + _exit(1); diff --git a/eBones/des/docs.original/MODES.DES b/eBones/des/docs.original/MODES.DES new file mode 100644 index 0000000..fe9c038 --- /dev/null +++ b/eBones/des/docs.original/MODES.DES @@ -0,0 +1,84 @@ +Modes of DES +Quite a bit of the following information has been taken from + AS 2805.5.2 + Australian Standard + Electronic funds transfer - Requirements for interfaces, + Part 5.2: Modes of operation for an n-bit block cipher algorithm + Appendix A + +There are several different modes in which DES can be used, they are +as follows. + +Electronic Codebook Mode (ECB) (des_ecb_encrypt()) +- 64 bits are enciphered at a time. +- The order of the blocks can be rearranged without detection. +- The same plaintext block always produces the same ciphertext block + (for the same key) making it vulnerable to a 'dictionary attack'. +- An error will only affect one ciphertext block. + +Cipher Block Chaining Mode (CBC) (des_cbc_encrypt()) +- a multiple of 64 bits are enciphered at a time. +- The CBC mode produces the same ciphertext whenever the same + plaintext is encrypted using the same key and starting variable. +- The chaining operation makes the ciphertext blocks dependent on the + current and all preceding plaintext blocks and therefore blocks can not + be rearranged. +- The use of different starting variables prevents the same plaintext + enciphering to the same ciphertext. +- An error will affect the current and the following ciphertext blocks. + +Cipher Feedback Mode (CFB) (des_cfb_encrypt()) +- a number of bits (j) <= 64 are enciphered at a time. +- The CFB mode produces the same ciphertext whenever the same + plaintext is encrypted using the same key and starting variable. +- The chaining operation makes the ciphertext variables dependent on the + current and all preceding variables and therefore j-bit variables are + chained together and con not be rearranged. +- The use of different starting variables prevents the same plaintext + enciphering to the same ciphertext. +- The strength of the CFB mode depends on the size of k (maximal if + j == k). In my implementation this is always the case. +- Selection of a small value for j will require more cycles through + the encipherment algorithm per unit of plaintext and thus cause + greater processing overheads. +- Only multiples of j bits can be enciphered. +- An error will affect the current and the following ciphertext variables. + +Output Feedback Mode (OFB) (des_ofb_encrypt()) +- a number of bits (j) <= 64 are enciphered at a time. +- The OFB mode produces the same ciphertext whenever the same + plaintext enciphered using the same key and starting variable. More + over, in the OFB mode the same key stream is produced when the same + key and start variable are used. Consequently, for security reasons + a specific start variable should be used only once for a given key. +- The absence of chaining makes the OFB more vulnerable to specific attacks. +- The use of different start variables values prevents the same + plaintext enciphering to the same ciphertext, by producing different + key streams. +- Selection of a small value for j will require more cycles through + the encipherment algorithm per unit of plaintext and thus cause + greater processing overheads. +- Only multiples of j bits can be enciphered. +- OFB mode of operation does not extend ciphertext errors in the + resultant plaintext output. Every bit error in the ciphertext causes + only one bit to be in error in the deciphered plaintext. +- OFB mode is not self-synchronising. If the two operation of + encipherment and decipherment get out of synchronism, the system needs + to be re-initialised. +- Each re-initialisation should use a value of the start variable +different from the start variable values used before with the same +key. The reason for this is that an identical bit stream would be +produced each time from the same parameters. This would be +susceptible to a ' known plaintext' attack. + +Triple ECB Mode (des_3ecb_encrypt()) +- Encrypt with key1, decrypt with key2 and encrypt with key1 again. +- As for ECB encryption but increases the effective key length to 112 bits. +- If both keys are the same it is equivalent to encrypting once with + just one key. + +Triple CBC Mode (des_3cbc_encrypt()) +- Encrypt with key1, decrypt with key2 and encrypt with key1 again. +- As for CBC encryption but increases the effective key length to 112 bits. +- If both keys are the same it is equivalent to encrypting once with + just one key. diff --git a/eBones/des/docs.original/README b/eBones/des/docs.original/README new file mode 100644 index 0000000..6acd62c --- /dev/null +++ b/eBones/des/docs.original/README @@ -0,0 +1,56 @@ + + libdes, Version 3.00 93/10/07 + + Copyright (c) 1993, Eric Young + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or + + b) the "Artistic License" which comes with this Kit. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either + the GNU General Public License or the Artistic License for more details. + + You should have received a copy of the Artistic License with this + Kit, in the file named "Artistic". If not, I'll be glad to provide one. + + You should also have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +--- +This kit builds a DES encryption library and a DES encryption program. +It suports ecb, cbc, ofb, cfb, triple ecb, triple cbc and MIT's pcbc +encryption modes and also has a fast implementation of crypt(3). +It contains support routines to read keys from a terminal, +generate a random key, generate a key from an arbitary length string, +read/write encrypted data from/to a file descriptor. + +The implementation was written so as to conform with the manual entry +for the des_crypt(3) library routines from MIT's project Athena. + +destest should be run after compilation to test the des routines. +rpw should be run after compilation to test the read password routines. +The des program is a replacement for the sun des command. I believe it +conforms to the sun version. + +The Imakefile is setup for use in the kerberos distribution. + +These routines are best compiled with gcc or any other good +optimising compiler. +Just turn you optimiser up to the highest settings and run destest +after the build to make sure everything works. + +I believe these routines are close to the fastest and most portable DES +routines that use small lookup tables (4.5k) that are publicly available. +The fcrypt routine is faster than ufc's fcrypt (when compiling with +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines +(on a sun3/260 168 vs 336). + +Eric Young (eay@psych.psy.uq.oz.au) diff --git a/eBones/des/docs.original/VERSION b/eBones/des/docs.original/VERSION new file mode 100644 index 0000000..21e3b8d --- /dev/null +++ b/eBones/des/docs.original/VERSION @@ -0,0 +1,185 @@ +Release apon comp.sources.misc +Version 3.01 08/10/93 + Added des_3cbc_encrypt() + +Version 3.00 07/10/93 + Fixed up documentation. + quad_cksum definitly compatable with MIT's now. + +Version 2.30 24/08/93 + Tripple DES now defaults to tripple cbc but can do tripple ecb + with the -b flag. + Fixed some MSDOS uuen/uudecoding problems, thanks to + Added prototypes. + +Version 2.22 29/06/93 + Fixed a bug in des_is_weak_key() which stopped it working :-( + thanks to engineering@MorningStar.Com. + +Version 2.21 03/06/93 + des(1) with no arguments gives quite a bit of help. + Added -c (generate ckecksum) flag to des(1). + Added -3 (tripple DES) flag to des(1). + Added cfb and ofb routines to the library. + +Version 2.20 11/03/93 + Added -u (uuencode) flag to des(1). + I have been playing with byte order in quad_cksum to make it + compatible with MIT's version. All I can say is aviod this + function if possible since MIT's output is endian dependent. + +Version 2.12 14/10/92 + Added MSDOS specific macro in ecb_encrypt which gives a %70 + speed up when the code is compiled with turbo C. + +Version 2.11 12/10/92 + Speedup in set_key (recoding of PC-1) + I now do it in 47 simple operations, down from 60. + Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + for motivating me to look for a faster system :-) + The speedup is probably less that 1% but it is still 13 + instructions less :-). + +Version 2.10 06/10/92 + The code now works on the 64bit ETA10 and CRAY without modifications or + #defines. I believe the code should work on any machine that + defines long, int or short to be 8 bytes long. + Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu) + for helping me fix the code to run on 64bit machines (he had + access to an ETA10). + Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov> + for testing the routines on a CRAY. + read_password.c has been renamed to read_passwd.c + string_to_key.c has been renamed to string2key.c + +Version 2.00 14/09/92 + Made mods so that the library should work on 64bit CPU's. + Removed all my uchar and ulong defs. To many different + versions of unix define them in their header files in too many + different combinations :-) + IRIX - Sillicon Graphics mods (mostly in read_password.c). + Thanks to Andrew Daviel (advax@erich.triumf.ca) + +Version 1.99 26/08/92 + Fixed a bug or 2 in enc_read.c + Fixed a bug in enc_write.c + Fixed a pseudo bug in fcrypt.c (very obscure). + +Version 1.98 31/07/92 + Support for the ETA10. This is a strange machine that defines + longs and ints as 8 bytes and shorts as 4 bytes. + Since I do evil things with long * that assume that they are 4 + bytes. Look in the Makefile for the option to compile for + this machine. quad_cksum appears to have problems but I + will don't have the time to fix it right now, and this is not + a function that uses DES and so will not effect the main uses + of the library. + +Version 1.97 20/05/92 eay + Fixed the Imakefile and made some changes to des.h to fix some + problems when building this package with Kerberos v 4. + +Version 1.96 18/05/92 eay + Fixed a small bug in string_to_key() where problems could + occur if des_check_key was set to true and the string + generated a weak key. + +Patch2 posted to comp.sources.misc +Version 1.95 13/05/92 eay + Added an alternative version of the D_ENCRYPT macro in + ecb_encrypt and fcrypt. Depending on the compiler, one version or the + other will be faster. This was inspired by + Dana How <how@isl.stanford.edu>, and her pointers about doing the + *(ulong *)((uchar *)ptr+(value&0xfc)) + vs + ptr[value&0x3f] + to stop the C compiler doing a <<2 to convert the long array index. + +Version 1.94 05/05/92 eay + Fixed an incompatibility between my string_to_key and the MIT + version. When the key is longer than 8 chars, I was wrapping + with a different method. To use the old version, define + OLD_STR_TO_KEY in the makefile. Thanks to + viktor@newsu.shearson.com (Viktor Dukhovni). + +Version 1.93 28/04/92 eay + Fixed the VMS mods so that echo is now turned off in + read_password. Thanks again to brennan@coco.cchs.su.oz.AU. + MSDOS support added. The routines can be compiled with + Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined. + +Patch1 posted to comp.sources.misc +Version 1.92 13/04/92 eay + Changed D_ENCRYPT so that the rotation of R occurs outside of + the loop. This required rotating all the longs in sp.h (now + called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + speed.c has been changed so it will work without SIGALRM. If + times(3) is not present it will try to use ftime() instead. + +Version 1.91 08/04/92 eay + Added -E/-D options to des(1) so it can use string_to_key. + Added SVR4 mods suggested by witr@rwwa.COM + Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If + anyone knows how to turn of tty echo in VMS please tell me or + implement it yourself :-). + Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS + does not like IN/OUT being used. + +Libdes posted to comp.sources.misc +Version 1.9 24/03/92 eay + Now contains a fast small crypt replacement. + Added des(1) command. + Added des_rw_mode so people can use cbc encryption with + enc_read and enc_write. + +Version 1.8 15/10/91 eay + Bug in cbc_cksum. + Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this + one out. + +Version 1.7 24/09/91 eay + Fixed set_key :-) + set_key is 4 times faster and takes less space. + There are a few minor changes that could be made. + +Version 1.6 19/09/1991 eay + Finally go IP and FP finished. + Now I need to fix set_key. + This version is quite a bit faster that 1.51 + +Version 1.52 15/06/1991 eay + 20% speedup in ecb_encrypt by changing the E bit selection + to use 2 32bit words. This also required modification of the + sp table. There is still a way to speedup the IP and IP-1 + (hints from outer@sq.com) still working on this one :-(. + +Version 1.51 07/06/1991 eay + Faster des_encrypt by loop unrolling + Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu) + +Version 1.50 28/05/1991 eay + Optimized the code a bit more for the sparc. I have improved the + speed of the inner des_encrypt by speeding up the initial and + final permutations. + +Version 1.40 23/10/1990 eay + Fixed des_random_key, it did not produce a random key :-( + +Version 1.30 2/10/1990 eay + Have made des_quad_cksum the same as MIT's, the full package + should be compatible with MIT's + Have tested on a DECstation 3100 + Still need to fix des_set_key (make it faster). + Does des_cbc_encrypts at 70.5k/sec on a 3100. + +Version 1.20 18/09/1990 eay + Fixed byte order dependencies. + Fixed (I hope) all the word alignment problems. + Speedup in des_ecb_encrypt. + +Version 1.10 11/09/1990 eay + Added des_enc_read and des_enc_write. + Still need to fix des_quad_cksum. + Still need to document des_enc_read and des_enc_write. + +Version 1.00 27/08/1990 eay diff --git a/eBones/des/ecb_enc.c b/eBones/des/ecb_enc.c new file mode 100644 index 0000000..e410eb8 --- /dev/null +++ b/eBones/des/ecb_enc.c @@ -0,0 +1,123 @@ +/* ecb_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: ecb_enc.c,v 1.2 1994/07/19 19:21:53 g89r4222 Exp $ + */ + +#include "des_locl.h" +#include "spr.h" + +int des_ecb_encrypt(input,output,ks,encrypt) +des_cblock *input; +des_cblock *output; +des_key_schedule ks; +int encrypt; + { + register unsigned long l0,l1; + register unsigned char *in,*out; + unsigned long ll[2]; + + in=(unsigned char *)input; + out=(unsigned char *)output; + c2l(in,l0); + c2l(in,l1); + ll[0]=l0; + ll[1]=l1; + des_encrypt(ll,ll,ks,encrypt); + l0=ll[0]; + l1=ll[1]; + l2c(l0,out); + l2c(l1,out); + l0=l1=ll[0]=ll[1]=0; + return(0); + } + +int des_encrypt(input,output,ks,encrypt) +unsigned long *input; +unsigned long *output; +des_key_schedule ks; +int encrypt; + { + register unsigned long l,r,t,u; +#ifdef ALT_ECB + register unsigned char *des_SP=(unsigned char *)des_SPtrans; +#endif +#ifdef MSDOS + union fudge { + unsigned long l; + unsigned short s[2]; + unsigned char c[4]; + } U,T; +#endif + register int i; + register unsigned long *s; + + l=input[0]; + r=input[1]; + + /* do IP */ + PERM_OP(r,l,t, 4,0x0f0f0f0f); + PERM_OP(l,r,t,16,0x0000ffff); + PERM_OP(r,l,t, 2,0x33333333); + PERM_OP(l,r,t, 8,0x00ff00ff); + PERM_OP(r,l,t, 1,0x55555555); + /* r and l are reversed - remember that :-) - fix + * it in the next step */ + + /* Things have been modified so that the initial rotate is + * done outside the loop. This required the + * des_SPtrans values in sp.h to be rotated 1 bit to the right. + * One perl script later and things have a 5% speed up on a sparc2. + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + * for pointing this out. */ + t=(r<<1)|(r>>31); + r=(l<<1)|(l>>31); + l=t; + + /* clear the top bits on machines with 8byte longs */ + l&=0xffffffff; + r&=0xffffffff; + + s=(unsigned long *)ks; + /* I don't know if it is worth the effort of loop unrolling the + * inner loop */ + if (encrypt) + { + for (i=0; i<32; i+=4) + { + D_ENCRYPT(l,r,i+0); /* 1 */ + D_ENCRYPT(r,l,i+2); /* 2 */ + } + } + else + { + for (i=30; i>0; i-=4) + { + D_ENCRYPT(l,r,i-0); /* 16 */ + D_ENCRYPT(r,l,i-2); /* 15 */ + } + } + l=(l>>1)|(l<<31); + r=(r>>1)|(r<<31); + /* clear the top bits on machines with 8byte longs */ + l&=0xffffffff; + r&=0xffffffff; + + /* swap l and r + * we will not do the swap so just remember they are + * reversed for the rest of the subroutine + * luckily FP fixes this problem :-) */ + + PERM_OP(r,l,t, 1,0x55555555); + PERM_OP(l,r,t, 8,0x00ff00ff); + PERM_OP(r,l,t, 2,0x33333333); + PERM_OP(l,r,t,16,0x0000ffff); + PERM_OP(r,l,t, 4,0x0f0f0f0f); + + output[0]=l; + output[1]=r; + l=r=t=u=0; + return(0); + } + diff --git a/eBones/des/enc_read.c b/eBones/des/enc_read.c new file mode 100644 index 0000000..1b77c4c --- /dev/null +++ b/eBones/des/enc_read.c @@ -0,0 +1,147 @@ +/* enc_read.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: enc_read.c,v 1.2 1994/07/19 19:21:54 g89r4222 Exp $ + */ + +#include <errno.h> +#include "des_locl.h" + +/* This has some uglies in it but it works - even over sockets. */ +extern int errno; +int des_rw_mode=DES_PCBC_MODE; + +int des_enc_read(fd,buf,len,sched,iv) +int fd; +char *buf; +int len; +des_key_schedule sched; +des_cblock *iv; + { + /* data to be unencrypted */ + int net_num=0; + unsigned char net[BSIZE]; + /* extra unencrypted data + * for when a block of 100 comes in but is des_read one byte at + * a time. */ + static char unnet[BSIZE]; + static int unnet_start=0; + static int unnet_left=0; + int i; + long num=0,rnum; + unsigned char *p; + + /* left over data from last decrypt */ + if (unnet_left != 0) + { + if (unnet_left < len) + { + /* we still still need more data but will return + * with the number of bytes we have - should always + * check the return value */ + bcopy(&(unnet[unnet_start]),buf,unnet_left); + /* eay 26/08/92 I had the next 2 lines + * reversed :-( */ + i=unnet_left; + unnet_start=unnet_left=0; + } + else + { + bcopy(&(unnet[unnet_start]),buf,len); + unnet_start+=len; + unnet_left-=len; + i=len; + } + return(i); + } + + /* We need to get more data. */ + if (len > MAXWRITE) len=MAXWRITE; + + /* first - get the length */ + net_num=0; + while (net_num < HDRSIZE) + { + i=read(fd,&(net[net_num]),HDRSIZE-net_num); + if ((i == -1) && (errno == EINTR)) continue; + if (i <= 0) return(0); + net_num+=i; + } + + /* we now have at net_num bytes in net */ + p=net; + num=0; + n2l(p,num); + /* num should be rounded up to the next group of eight + * we make sure that we have read a multiple of 8 bytes from the net. + */ + if ((num > MAXWRITE) || (num < 0)) /* error */ + return(-1); + rnum=(num < 8)?8:((num+7)/8*8); + + net_num=0; + while (net_num < rnum) + { + i=read(fd,&(net[net_num]),rnum-net_num); + if ((i == -1) && (errno == EINTR)) continue; + if (i <= 0) return(0); + net_num+=i; + } + + /* Check if there will be data left over. */ + if (len < num) + { + if (des_rw_mode & DES_PCBC_MODE) + pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet, + num,sched,iv,DES_DECRYPT); + else + cbc_encrypt((des_cblock *)net,(des_cblock *)unnet, + num,sched,iv,DES_DECRYPT); + bcopy(unnet,buf,len); + unnet_start=len; + unnet_left=num-len; + + /* The following line is done because we return num + * as the number of bytes read. */ + num=len; + } + else + { + /* >output is a multiple of 8 byes, if len < rnum + * >we must be careful. The user must be aware that this + * >routine will write more bytes than he asked for. + * >The length of the buffer must be correct. + * FIXED - Should be ok now 18-9-90 - eay */ + if (len < rnum) + { + char tmpbuf[BSIZE]; + + if (des_rw_mode & DES_PCBC_MODE) + pcbc_encrypt((des_cblock *)net, + (des_cblock *)tmpbuf, + num,sched,iv,DES_DECRYPT); + else + cbc_encrypt((des_cblock *)net, + (des_cblock *)tmpbuf, + num,sched,iv,DES_DECRYPT); + + /* eay 26/08/92 fix a bug that returned more + * bytes than you asked for (returned len bytes :-( */ + bcopy(tmpbuf,buf,num); + } + else + { + if (des_rw_mode & DES_PCBC_MODE) + pcbc_encrypt((des_cblock *)net, + (des_cblock *)buf,num,sched,iv, + DES_DECRYPT); + else + cbc_encrypt((des_cblock *)net, + (des_cblock *)buf,num,sched,iv, + DES_DECRYPT); + } + } + return(num); + } + diff --git a/eBones/des/enc_writ.c b/eBones/des/enc_writ.c new file mode 100644 index 0000000..602106b --- /dev/null +++ b/eBones/des/enc_writ.c @@ -0,0 +1,94 @@ +/* enc_writ.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: enc_writ.c,v 1.2 1994/07/19 19:21:56 g89r4222 Exp $ + */ + +#include <errno.h> +#include "des_locl.h" + +int des_enc_write(fd,buf,len,sched,iv) +int fd; +char *buf; +int len; +des_key_schedule sched; +des_cblock *iv; + { + long rnum; + int i,j,k,outnum; + char outbuf[BSIZE+HDRSIZE]; + char shortbuf[8]; + char *p; + static int start=1; + + /* If we are sending less than 8 bytes, the same char will look + * the same if we don't pad it out with random bytes */ + if (start) + { + start=0; + srandom(time(NULL)); + } + + /* lets recurse if we want to send the data in small chunks */ + if (len > MAXWRITE) + { + j=0; + for (i=0; i<len; i+=k) + { + k=des_enc_write(fd,&(buf[i]), + ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv); + if (k < 0) + return(k); + else + j+=k; + } + return(j); + } + + /* write length first */ + p=outbuf; + l2n(len,p); + + /* pad short strings */ + if (len < 8) + { + p=shortbuf; + bcopy(buf,shortbuf,len); + for (i=len; i<8; i++) + shortbuf[i]=random(); + rnum=8; + } + else + { + p=buf; + rnum=((len+7)/8*8); /* round up to nearest eight */ + } + + if (des_rw_mode & DES_PCBC_MODE) + pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]), + (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); + else + cbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]), + (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); + + /* output */ + outnum=rnum+HDRSIZE; + + for (j=0; j<outnum; j+=i) + { + /* eay 26/08/92 I was not doing writing from where we + * got upto. */ + i=write(fd,&(outbuf[j]),(int)(outnum-j)); + if (i == -1) + { + if (errno == EINTR) + i=0; + else /* This is really a bad error - very bad + * It will stuff-up both ends. */ + return(-1); + } + } + + return(len); + } diff --git a/eBones/des/fcrypt.c b/eBones/des/fcrypt.c new file mode 100644 index 0000000..c7f41ce --- /dev/null +++ b/eBones/des/fcrypt.c @@ -0,0 +1,581 @@ +/* fcrypt.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: fcrypt.c,v 1.2 1994/07/19 19:21:58 g89r4222 Exp $ + */ + +#include <stdio.h> + +/* Eric Young. + * This version of crypt has been developed from my MIT compatable + * DES library. + * The library is available at pub/DES at ftp.psy.uq.oz.au + * eay@psych.psy.uq.oz.au + */ + +typedef unsigned char des_cblock[8]; + +typedef struct des_ks_struct + { + union { + des_cblock _; + /* make sure things are correct size on machines with + * 8 byte longs */ + unsigned long pad[2]; + } ks; +#define _ ks._ + } des_key_schedule[16]; + +#define DES_KEY_SZ (sizeof(des_cblock)) +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<<24) + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +static unsigned long SPtrans[8][64]={ +/* nibble 0 */ +0x00820200, 0x00020000, 0x80800000, 0x80820200, +0x00800000, 0x80020200, 0x80020000, 0x80800000, +0x80020200, 0x00820200, 0x00820000, 0x80000200, +0x80800200, 0x00800000, 0x00000000, 0x80020000, +0x00020000, 0x80000000, 0x00800200, 0x00020200, +0x80820200, 0x00820000, 0x80000200, 0x00800200, +0x80000000, 0x00000200, 0x00020200, 0x80820000, +0x00000200, 0x80800200, 0x80820000, 0x00000000, +0x00000000, 0x80820200, 0x00800200, 0x80020000, +0x00820200, 0x00020000, 0x80000200, 0x00800200, +0x80820000, 0x00000200, 0x00020200, 0x80800000, +0x80020200, 0x80000000, 0x80800000, 0x00820000, +0x80820200, 0x00020200, 0x00820000, 0x80800200, +0x00800000, 0x80000200, 0x80020000, 0x00000000, +0x00020000, 0x00800000, 0x80800200, 0x00820200, +0x80000000, 0x80820000, 0x00000200, 0x80020200, +/* nibble 1 */ +0x10042004, 0x00000000, 0x00042000, 0x10040000, +0x10000004, 0x00002004, 0x10002000, 0x00042000, +0x00002000, 0x10040004, 0x00000004, 0x10002000, +0x00040004, 0x10042000, 0x10040000, 0x00000004, +0x00040000, 0x10002004, 0x10040004, 0x00002000, +0x00042004, 0x10000000, 0x00000000, 0x00040004, +0x10002004, 0x00042004, 0x10042000, 0x10000004, +0x10000000, 0x00040000, 0x00002004, 0x10042004, +0x00040004, 0x10042000, 0x10002000, 0x00042004, +0x10042004, 0x00040004, 0x10000004, 0x00000000, +0x10000000, 0x00002004, 0x00040000, 0x10040004, +0x00002000, 0x10000000, 0x00042004, 0x10002004, +0x10042000, 0x00002000, 0x00000000, 0x10000004, +0x00000004, 0x10042004, 0x00042000, 0x10040000, +0x10040004, 0x00040000, 0x00002004, 0x10002000, +0x10002004, 0x00000004, 0x10040000, 0x00042000, +/* nibble 2 */ +0x41000000, 0x01010040, 0x00000040, 0x41000040, +0x40010000, 0x01000000, 0x41000040, 0x00010040, +0x01000040, 0x00010000, 0x01010000, 0x40000000, +0x41010040, 0x40000040, 0x40000000, 0x41010000, +0x00000000, 0x40010000, 0x01010040, 0x00000040, +0x40000040, 0x41010040, 0x00010000, 0x41000000, +0x41010000, 0x01000040, 0x40010040, 0x01010000, +0x00010040, 0x00000000, 0x01000000, 0x40010040, +0x01010040, 0x00000040, 0x40000000, 0x00010000, +0x40000040, 0x40010000, 0x01010000, 0x41000040, +0x00000000, 0x01010040, 0x00010040, 0x41010000, +0x40010000, 0x01000000, 0x41010040, 0x40000000, +0x40010040, 0x41000000, 0x01000000, 0x41010040, +0x00010000, 0x01000040, 0x41000040, 0x00010040, +0x01000040, 0x00000000, 0x41010000, 0x40000040, +0x41000000, 0x40010040, 0x00000040, 0x01010000, +/* nibble 3 */ +0x00100402, 0x04000400, 0x00000002, 0x04100402, +0x00000000, 0x04100000, 0x04000402, 0x00100002, +0x04100400, 0x04000002, 0x04000000, 0x00000402, +0x04000002, 0x00100402, 0x00100000, 0x04000000, +0x04100002, 0x00100400, 0x00000400, 0x00000002, +0x00100400, 0x04000402, 0x04100000, 0x00000400, +0x00000402, 0x00000000, 0x00100002, 0x04100400, +0x04000400, 0x04100002, 0x04100402, 0x00100000, +0x04100002, 0x00000402, 0x00100000, 0x04000002, +0x00100400, 0x04000400, 0x00000002, 0x04100000, +0x04000402, 0x00000000, 0x00000400, 0x00100002, +0x00000000, 0x04100002, 0x04100400, 0x00000400, +0x04000000, 0x04100402, 0x00100402, 0x00100000, +0x04100402, 0x00000002, 0x04000400, 0x00100402, +0x00100002, 0x00100400, 0x04100000, 0x04000402, +0x00000402, 0x04000000, 0x04000002, 0x04100400, +/* nibble 4 */ +0x02000000, 0x00004000, 0x00000100, 0x02004108, +0x02004008, 0x02000100, 0x00004108, 0x02004000, +0x00004000, 0x00000008, 0x02000008, 0x00004100, +0x02000108, 0x02004008, 0x02004100, 0x00000000, +0x00004100, 0x02000000, 0x00004008, 0x00000108, +0x02000100, 0x00004108, 0x00000000, 0x02000008, +0x00000008, 0x02000108, 0x02004108, 0x00004008, +0x02004000, 0x00000100, 0x00000108, 0x02004100, +0x02004100, 0x02000108, 0x00004008, 0x02004000, +0x00004000, 0x00000008, 0x02000008, 0x02000100, +0x02000000, 0x00004100, 0x02004108, 0x00000000, +0x00004108, 0x02000000, 0x00000100, 0x00004008, +0x02000108, 0x00000100, 0x00000000, 0x02004108, +0x02004008, 0x02004100, 0x00000108, 0x00004000, +0x00004100, 0x02004008, 0x02000100, 0x00000108, +0x00000008, 0x00004108, 0x02004000, 0x02000008, +/* nibble 5 */ +0x20000010, 0x00080010, 0x00000000, 0x20080800, +0x00080010, 0x00000800, 0x20000810, 0x00080000, +0x00000810, 0x20080810, 0x00080800, 0x20000000, +0x20000800, 0x20000010, 0x20080000, 0x00080810, +0x00080000, 0x20000810, 0x20080010, 0x00000000, +0x00000800, 0x00000010, 0x20080800, 0x20080010, +0x20080810, 0x20080000, 0x20000000, 0x00000810, +0x00000010, 0x00080800, 0x00080810, 0x20000800, +0x00000810, 0x20000000, 0x20000800, 0x00080810, +0x20080800, 0x00080010, 0x00000000, 0x20000800, +0x20000000, 0x00000800, 0x20080010, 0x00080000, +0x00080010, 0x20080810, 0x00080800, 0x00000010, +0x20080810, 0x00080800, 0x00080000, 0x20000810, +0x20000010, 0x20080000, 0x00080810, 0x00000000, +0x00000800, 0x20000010, 0x20000810, 0x20080800, +0x20080000, 0x00000810, 0x00000010, 0x20080010, +/* nibble 6 */ +0x00001000, 0x00000080, 0x00400080, 0x00400001, +0x00401081, 0x00001001, 0x00001080, 0x00000000, +0x00400000, 0x00400081, 0x00000081, 0x00401000, +0x00000001, 0x00401080, 0x00401000, 0x00000081, +0x00400081, 0x00001000, 0x00001001, 0x00401081, +0x00000000, 0x00400080, 0x00400001, 0x00001080, +0x00401001, 0x00001081, 0x00401080, 0x00000001, +0x00001081, 0x00401001, 0x00000080, 0x00400000, +0x00001081, 0x00401000, 0x00401001, 0x00000081, +0x00001000, 0x00000080, 0x00400000, 0x00401001, +0x00400081, 0x00001081, 0x00001080, 0x00000000, +0x00000080, 0x00400001, 0x00000001, 0x00400080, +0x00000000, 0x00400081, 0x00400080, 0x00001080, +0x00000081, 0x00001000, 0x00401081, 0x00400000, +0x00401080, 0x00000001, 0x00001001, 0x00401081, +0x00400001, 0x00401080, 0x00401000, 0x00001001, +/* nibble 7 */ +0x08200020, 0x08208000, 0x00008020, 0x00000000, +0x08008000, 0x00200020, 0x08200000, 0x08208020, +0x00000020, 0x08000000, 0x00208000, 0x00008020, +0x00208020, 0x08008020, 0x08000020, 0x08200000, +0x00008000, 0x00208020, 0x00200020, 0x08008000, +0x08208020, 0x08000020, 0x00000000, 0x00208000, +0x08000000, 0x00200000, 0x08008020, 0x08200020, +0x00200000, 0x00008000, 0x08208000, 0x00000020, +0x00200000, 0x00008000, 0x08000020, 0x08208020, +0x00008020, 0x08000000, 0x00000000, 0x00208000, +0x08200020, 0x08008020, 0x08008000, 0x00200020, +0x08208000, 0x00000020, 0x00200020, 0x08008000, +0x08208020, 0x00200000, 0x08200000, 0x08000020, +0x00208000, 0x00008020, 0x08008020, 0x08200000, +0x00000020, 0x08208000, 0x00208020, 0x00000000, +0x08000000, 0x08200020, 0x00008000, 0x00208020}; +static unsigned long skb[8][64]={ +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000,0x00000010,0x20000000,0x20000010, +0x00010000,0x00010010,0x20010000,0x20010010, +0x00000800,0x00000810,0x20000800,0x20000810, +0x00010800,0x00010810,0x20010800,0x20010810, +0x00000020,0x00000030,0x20000020,0x20000030, +0x00010020,0x00010030,0x20010020,0x20010030, +0x00000820,0x00000830,0x20000820,0x20000830, +0x00010820,0x00010830,0x20010820,0x20010830, +0x00080000,0x00080010,0x20080000,0x20080010, +0x00090000,0x00090010,0x20090000,0x20090010, +0x00080800,0x00080810,0x20080800,0x20080810, +0x00090800,0x00090810,0x20090800,0x20090810, +0x00080020,0x00080030,0x20080020,0x20080030, +0x00090020,0x00090030,0x20090020,0x20090030, +0x00080820,0x00080830,0x20080820,0x20080830, +0x00090820,0x00090830,0x20090820,0x20090830, +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ +0x00000000,0x02000000,0x00002000,0x02002000, +0x00200000,0x02200000,0x00202000,0x02202000, +0x00000004,0x02000004,0x00002004,0x02002004, +0x00200004,0x02200004,0x00202004,0x02202004, +0x00000400,0x02000400,0x00002400,0x02002400, +0x00200400,0x02200400,0x00202400,0x02202400, +0x00000404,0x02000404,0x00002404,0x02002404, +0x00200404,0x02200404,0x00202404,0x02202404, +0x10000000,0x12000000,0x10002000,0x12002000, +0x10200000,0x12200000,0x10202000,0x12202000, +0x10000004,0x12000004,0x10002004,0x12002004, +0x10200004,0x12200004,0x10202004,0x12202004, +0x10000400,0x12000400,0x10002400,0x12002400, +0x10200400,0x12200400,0x10202400,0x12202400, +0x10000404,0x12000404,0x10002404,0x12002404, +0x10200404,0x12200404,0x10202404,0x12202404, +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ +0x00000000,0x00000001,0x00040000,0x00040001, +0x01000000,0x01000001,0x01040000,0x01040001, +0x00000002,0x00000003,0x00040002,0x00040003, +0x01000002,0x01000003,0x01040002,0x01040003, +0x00000200,0x00000201,0x00040200,0x00040201, +0x01000200,0x01000201,0x01040200,0x01040201, +0x00000202,0x00000203,0x00040202,0x00040203, +0x01000202,0x01000203,0x01040202,0x01040203, +0x08000000,0x08000001,0x08040000,0x08040001, +0x09000000,0x09000001,0x09040000,0x09040001, +0x08000002,0x08000003,0x08040002,0x08040003, +0x09000002,0x09000003,0x09040002,0x09040003, +0x08000200,0x08000201,0x08040200,0x08040201, +0x09000200,0x09000201,0x09040200,0x09040201, +0x08000202,0x08000203,0x08040202,0x08040203, +0x09000202,0x09000203,0x09040202,0x09040203, +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ +0x00000000,0x00100000,0x00000100,0x00100100, +0x00000008,0x00100008,0x00000108,0x00100108, +0x00001000,0x00101000,0x00001100,0x00101100, +0x00001008,0x00101008,0x00001108,0x00101108, +0x04000000,0x04100000,0x04000100,0x04100100, +0x04000008,0x04100008,0x04000108,0x04100108, +0x04001000,0x04101000,0x04001100,0x04101100, +0x04001008,0x04101008,0x04001108,0x04101108, +0x00020000,0x00120000,0x00020100,0x00120100, +0x00020008,0x00120008,0x00020108,0x00120108, +0x00021000,0x00121000,0x00021100,0x00121100, +0x00021008,0x00121008,0x00021108,0x00121108, +0x04020000,0x04120000,0x04020100,0x04120100, +0x04020008,0x04120008,0x04020108,0x04120108, +0x04021000,0x04121000,0x04021100,0x04121100, +0x04021008,0x04121008,0x04021108,0x04121108, +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000,0x10000000,0x00010000,0x10010000, +0x00000004,0x10000004,0x00010004,0x10010004, +0x20000000,0x30000000,0x20010000,0x30010000, +0x20000004,0x30000004,0x20010004,0x30010004, +0x00100000,0x10100000,0x00110000,0x10110000, +0x00100004,0x10100004,0x00110004,0x10110004, +0x20100000,0x30100000,0x20110000,0x30110000, +0x20100004,0x30100004,0x20110004,0x30110004, +0x00001000,0x10001000,0x00011000,0x10011000, +0x00001004,0x10001004,0x00011004,0x10011004, +0x20001000,0x30001000,0x20011000,0x30011000, +0x20001004,0x30001004,0x20011004,0x30011004, +0x00101000,0x10101000,0x00111000,0x10111000, +0x00101004,0x10101004,0x00111004,0x10111004, +0x20101000,0x30101000,0x20111000,0x30111000, +0x20101004,0x30101004,0x20111004,0x30111004, +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ +0x00000000,0x08000000,0x00000008,0x08000008, +0x00000400,0x08000400,0x00000408,0x08000408, +0x00020000,0x08020000,0x00020008,0x08020008, +0x00020400,0x08020400,0x00020408,0x08020408, +0x00000001,0x08000001,0x00000009,0x08000009, +0x00000401,0x08000401,0x00000409,0x08000409, +0x00020001,0x08020001,0x00020009,0x08020009, +0x00020401,0x08020401,0x00020409,0x08020409, +0x02000000,0x0A000000,0x02000008,0x0A000008, +0x02000400,0x0A000400,0x02000408,0x0A000408, +0x02020000,0x0A020000,0x02020008,0x0A020008, +0x02020400,0x0A020400,0x02020408,0x0A020408, +0x02000001,0x0A000001,0x02000009,0x0A000009, +0x02000401,0x0A000401,0x02000409,0x0A000409, +0x02020001,0x0A020001,0x02020009,0x0A020009, +0x02020401,0x0A020401,0x02020409,0x0A020409, +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ +0x00000000,0x00000100,0x00080000,0x00080100, +0x01000000,0x01000100,0x01080000,0x01080100, +0x00000010,0x00000110,0x00080010,0x00080110, +0x01000010,0x01000110,0x01080010,0x01080110, +0x00200000,0x00200100,0x00280000,0x00280100, +0x01200000,0x01200100,0x01280000,0x01280100, +0x00200010,0x00200110,0x00280010,0x00280110, +0x01200010,0x01200110,0x01280010,0x01280110, +0x00000200,0x00000300,0x00080200,0x00080300, +0x01000200,0x01000300,0x01080200,0x01080300, +0x00000210,0x00000310,0x00080210,0x00080310, +0x01000210,0x01000310,0x01080210,0x01080310, +0x00200200,0x00200300,0x00280200,0x00280300, +0x01200200,0x01200300,0x01280200,0x01280300, +0x00200210,0x00200310,0x00280210,0x00280310, +0x01200210,0x01200310,0x01280210,0x01280310, +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ +0x00000000,0x04000000,0x00040000,0x04040000, +0x00000002,0x04000002,0x00040002,0x04040002, +0x00002000,0x04002000,0x00042000,0x04042000, +0x00002002,0x04002002,0x00042002,0x04042002, +0x00000020,0x04000020,0x00040020,0x04040020, +0x00000022,0x04000022,0x00040022,0x04040022, +0x00002020,0x04002020,0x00042020,0x04042020, +0x00002022,0x04002022,0x00042022,0x04042022, +0x00000800,0x04000800,0x00040800,0x04040800, +0x00000802,0x04000802,0x00040802,0x04040802, +0x00002800,0x04002800,0x00042800,0x04042800, +0x00002802,0x04002802,0x00042802,0x04042802, +0x00000820,0x04000820,0x00040820,0x04040820, +0x00000822,0x04000822,0x00040822,0x04040822, +0x00002820,0x04002820,0x00042820,0x04042820, +0x00002822,0x04002822,0x00042822,0x04042822, +}; + +/* See ecb_encrypt.c for a pseudo description of these macros. */ +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n))))\ + +static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; + +static int body(); +static int des_set___key(); + +static int des_set___key(key,schedule) +des_cblock *key; +des_key_schedule schedule; + { + register unsigned long c,d,t,s; + register unsigned char *in; + register unsigned long *k; + register int i; + + k=(unsigned long *)schedule; + in=(unsigned char *)key; + + c2l(in,c); + c2l(in,d); + + /* I now do it in 47 simple operations :-) + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + * for the inspiration. :-) */ + PERM_OP (d,c,t,4,0x0f0f0f0f); + HPERM_OP(c,t,-2,0xcccc0000); + HPERM_OP(d,t,-2,0xcccc0000); + PERM_OP (d,c,t,1,0x55555555); + PERM_OP (c,d,t,8,0x00ff00ff); + PERM_OP (d,c,t,1,0x55555555); + d= (((d&0x000000ff)<<16)| (d&0x0000ff00) | + ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4)); + c&=0x0fffffff; + + for (i=0; i<ITERATIONS; i++) + { + if (shifts2[i]) + { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); } + else + { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); } + c&=0x0fffffff; + d&=0x0fffffff; + /* could be a few less shifts but I am to lazy at this + * point in time to investigate */ + s= skb[0][ (c )&0x3f ]| + skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]| + skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]| + skb[3][((c>>20)&0x01)|((c>>21)&0x06) | + ((c>>22)&0x38)]; + t= skb[4][ (d )&0x3f ]| + skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]| + skb[6][ (d>>15)&0x3f ]| + skb[7][((d>>21)&0x0f)|((d>>22)&0x30)]; + + /* table contained 0213 4657 */ + *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff; + s= ((s>>16)|(t&0xffff0000)); + + s=(s<<4)|(s>>28); + *(k++)=s&0xffffffff; + } + return(0); + } + +/****************************************************************** + * modified stuff for crypt. + ******************************************************************/ + +/* The changes to this macro may help or hinder, depending on the + * compiler and the achitecture. gcc2 always seems to do well :-). + * Inspired by Dana How <how@isl.stanford.edu> + * DO NOT use the alternative version on machines with 8 byte longs. + */ +#ifdef ALT_ECB +#define D_ENCRYPT(L,R,S) \ + v=(R^(R>>16)); \ + u=(v&E0); \ + v=(v&E1); \ + u=((u^(u<<16))^R^s[S ])<<2; \ + t=(v^(v<<16))^R^s[S+1]; \ + t=(t>>2)|(t<<30); \ + L^= \ + *(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \ + *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \ + *(unsigned long *)(des_SP+ ((u )&0xfc))+ \ + *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc)); +#else /* original version */ +#define D_ENCRYPT(L,R,S) \ + v=(R^(R>>16)); \ + u=(v&E0); \ + v=(v&E1); \ + u=(u^(u<<16))^R^s[S ]; \ + t=(v^(v<<16))^R^s[S+1]; \ + t=(t>>4)|(t<<28); \ + L^= SPtrans[1][(t )&0x3f]| \ + SPtrans[3][(t>> 8)&0x3f]| \ + SPtrans[5][(t>>16)&0x3f]| \ + SPtrans[7][(t>>24)&0x3f]| \ + SPtrans[0][(u )&0x3f]| \ + SPtrans[2][(u>> 8)&0x3f]| \ + SPtrans[4][(u>>16)&0x3f]| \ + SPtrans[6][(u>>24)&0x3f]; +#endif + +unsigned char con_salt[128]={ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, +0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, +0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A, +0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12, +0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A, +0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, +0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24, +0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C, +0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34, +0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C, +0x3D,0x3E,0x3F,0x00,0x00,0x00,0x00,0x00, +}; + +unsigned char cov_2char[64]={ +0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, +0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, +0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, +0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, +0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, +0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, +0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, +0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A +}; + +char *crypt(buf,salt) +char *buf; +char *salt; + { + unsigned int i,j,x,y; + unsigned long Eswap0=0,Eswap1=0; + unsigned long out[2],ll; + des_cblock key; + des_key_schedule ks; + static unsigned char buff[20]; + unsigned char bb[9]; + unsigned char *b=bb; + unsigned char c,u; + + /* eay 25/08/92 + * If you call crypt("pwd","*") as often happens when you + * have * as the pwd field in /etc/passwd, the function + * returns *\0XXXXXXXXX + * The \0 makes the string look like * so the pwd "*" would + * crypt to "*". This was found when replacing the crypt in + * our shared libraries. People found that the disbled + * accounts effectivly had no passwd :-(. */ + if (salt[0] == '\0') salt[0]='A'; + if (salt[1] == '\0') salt[1]='A'; + x=buff[0]=salt[0]; + Eswap0=con_salt[x]; + x=buff[1]=salt[1]; + Eswap1=con_salt[x]<<4; + + for (i=0; i<8; i++) + { + c= *(buf++); + if (!c) break; + key[i]=(c<<1); + } + for (; i<8; i++) + key[i]=0; + + des_set___key((des_cblock *)(key),ks); + body(&out[0],&out[1],ks,Eswap0,Eswap1); + + ll=out[0]; l2c(ll,b); + ll=out[1]; l2c(ll,b); + y=0; + u=0x80; + bb[8]=0; + for (i=2; i<13; i++) + { + c=0; + for (j=0; j<6; j++) + { + c<<=1; + if (bb[y] & u) c|=1; + u>>=1; + if (!u) + { + y++; + u=0x80; + } + } + buff[i]=cov_2char[c]; + } + return((char *)buff); + } + +static int body(out0,out1,ks,Eswap0,Eswap1) +unsigned long *out0,*out1; +des_key_schedule *ks; +unsigned long Eswap0,Eswap1; + { + register unsigned long l,r,t,u,v; +#ifdef ALT_ECB + register unsigned char *des_SP=(unsigned char *)SPtrans; +#endif + register unsigned long *s; + register int i,j; + register unsigned long E0,E1; + + l=0; + r=0; + + s=(unsigned long *)ks; + E0=Eswap0; + E1=Eswap1; + + for (j=0; j<25; j++) + { + for (i=0; i<(ITERATIONS*2); i+=4) + { + D_ENCRYPT(l,r, i); /* 1 */ + D_ENCRYPT(r,l, i+2); /* 2 */ + } + t=l; + l=r; + r=t; + } + t=r; + r=(l>>1)|(l<<31); + l=(t>>1)|(t<<31); + /* clear the top bits on machines with 8byte longs */ + l&=0xffffffff; + r&=0xffffffff; + + PERM_OP(r,l,t, 1,0x55555555); + PERM_OP(l,r,t, 8,0x00ff00ff); + PERM_OP(r,l,t, 2,0x33333333); + PERM_OP(l,r,t,16,0x0000ffff); + PERM_OP(r,l,t, 4,0x0f0f0f0f); + + *out0=l; + *out1=r; + return(0); + } + diff --git a/eBones/des/include/des.h b/eBones/des/include/des.h new file mode 100644 index 0000000..3cfc894 --- /dev/null +++ b/eBones/des/include/des.h @@ -0,0 +1,121 @@ +/* des.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: des.h,v 1.2 1994/07/19 19:22:17 g89r4222 Exp $ + */ + +#ifndef DES_DEFS +#define DES_DEFS + +typedef unsigned char des_cblock[8]; +typedef struct des_ks_struct + { + union { + des_cblock _; + /* make sure things are correct size on machines with + * 8 byte longs */ + unsigned long pad[2]; + } ks; +#define _ ks._ + } des_key_schedule[16]; + +#define DES_KEY_SZ (sizeof(des_cblock)) +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +#define C_Block des_cblock +#define Key_schedule des_key_schedule +#define ENCRYPT DES_ENCRYPT +#define DECRYPT DES_DECRYPT +#define KEY_SZ DES_KEY_SZ +#define string_to_key des_string_to_key +#define read_pw_string des_read_pw_string +#define random_key des_random_key +#define pcbc_encrypt des_pcbc_encrypt +#define set_key des_set__key +#define key_sched des_key_sched +#define ecb_encrypt des_ecb_encrypt +#define cbc_encrypt des_cbc_encrypt +#define cbc_cksum des_cbc_cksum +#define quad_cksum des_quad_cksum + +/* For compatibility with the MIT lib - eay 20/05/92 */ +typedef struct des_ks_struct bit_64; + +extern int des_check_key; /* defaults to false */ +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ + +/* The next line is used to disable full ANSI prototypes, if your + * compiler has problems with the prototypes, make sure this line always + * evaluates to true :-) */ +#if !defined(MSDOS) && !defined(__STDC__) +#ifndef KERBEROS +int des_3ecb_encrypt(); +int des_cbc_encrypt(); +int des_3cbc_encrypt(); +int des_cfb_encrypt(); +int des_ecb_encrypt(); +int des_encrypt(); +int des_enc_read(); +int des_enc_write(); +int des_ofb_encrypt(); +int des_pcbc_encrypt(); +int des_random_key(); +int des_read_password(); +int des_read_2passwords(); +int des_read_pw_string(); +int des_is_weak_key(); +int des_set__key(); +int des_key_sched(); +int des_string_to_key(); +int des_string_to_2keys(); +#endif +char *crypt(); +unsigned long des_cbc_cksum(); +unsigned long des_quad_cksum(); +unsigned long des_cbc_cksum(); +void des_set_odd_parity(); +#else /* PROTO */ +int des_3ecb_encrypt(des_cblock *input,des_cblock *output,\ + des_key_schedule ks1,des_key_schedule ks2,int encrypt); +unsigned long des_cbc_cksum(des_cblock *input,des_cblock *output,\ + long length,des_key_schedule schedule,des_cblock *ivec); +int des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,\ + des_key_schedule schedule,des_cblock *ivec,int encrypt); +int des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,\ + des_key_schedule sk1,des_key_schedule sk2,\ + des_cblock *ivec1,des_cblock *ivec2,int encrypt); +int des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,\ + long length,des_key_schedule schedule,des_cblock *ivec,int encrypt); +int des_ecb_encrypt(des_cblock *input,des_cblock *output,\ + des_key_schedule ks,int encrypt); +int des_encrypt(unsigned long *input,unsigned long *output, + des_key_schedule ks, int encrypt); +int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,\ + des_cblock *iv); +int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,\ + des_cblock *iv); +char *crypt(char *buf,char *salt); +int des_ofb_encrypt(unsigned char *in,unsigned char *out,\ + int numbits,long length,des_key_schedule schedule,des_cblock *ivec); +int des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,\ + des_key_schedule schedule,des_cblock *ivec,int encrypt); +unsigned long des_quad_cksum(des_cblock *input,des_cblock *output,\ + long length,int out_count,des_cblock *seed); +int des_random_key(des_cblock ret); +int des_read_password(des_cblock *key,char *prompt,int verify); +int des_read_2passwords(des_cblock *key1,des_cblock *key2, \ + char *prompt,int verify); +int des_read_pw_string(char *buf,int length,char *prompt,int verify); +void des_set_odd_parity(des_cblock *key); +int des_is_weak_key(des_cblock *key); +int des_set__key(des_cblock *key,des_key_schedule schedule); +int des_key_sched(des_cblock *key,des_key_schedule schedule); +int des_string_to_key(char *str,des_cblock *key); +int des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2); +#endif +#endif diff --git a/eBones/des/include/des_locl.h b/eBones/des/include/des_locl.h new file mode 100644 index 0000000..b35f33c --- /dev/null +++ b/eBones/des/include/des_locl.h @@ -0,0 +1,186 @@ +/* des_locl.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: des_locl.h,v 1.2 1994/07/19 19:22:18 g89r4222 Exp $ + */ + +#include <stdio.h> +#include "des.h" + +#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) +#include <string.h> +#define bcopy(b1,b2,len) memcpy(b2, b1, (size_t)(len)) +#define bzero(b,len) memset(b, 0, (size_t)(len)) +#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len)) +#define index(s1,char) strchr(s1,char) +#endif + +#ifdef MSDOS +#define getpid() 2 +#define RAND +extern int errno; +#define PROTO +#endif + +#ifdef __STDC__ +#define PROTO +#endif + +#ifdef RAND +#define random() rand() +#define srandom(s) srand(s) +#endif + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +/* used in des_read and des_write */ +#define MAXWRITE (1024*16) +#define BSIZE (MAXWRITE+4) + +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<<24) + +/* NOTE - c is not incremented as per c2l */ +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2|=((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1|=((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +/* replacements for htonl and ntohl since I have no idea what to do + * when faced with machines with 8 byte longs. */ +#define HDRSIZE 4 + +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))) + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* The changes to this macro may help or hinder, depending on the + * compiler and the achitecture. gcc2 always seems to do well :-). + * Inspired by Dana How <how@isl.stanford.edu> + * DO NOT use the alternative version on machines with 8 byte longs. */ +#ifdef ALT_ECB +#define D_ENCRYPT(L,R,S) \ + u=((R^s[S ])<<2); \ + t= R^s[S+1]; \ + t=((t>>2)+(t<<30)); \ + L^= \ + *(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \ + *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \ + *(unsigned long *)(des_SP+ ((u )&0xfc))+ \ + *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \ + *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc)); +#else /* original version */ +#ifdef MSDOS +#define D_ENCRYPT(L,R,S) \ + U.l=R^s[S+1]; \ + T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \ + T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \ + U.l=(R^s[S ])&0x3f3f3f3f; \ + L^= des_SPtrans[1][(T.c[0])]| \ + des_SPtrans[3][(T.c[1])]| \ + des_SPtrans[5][(T.c[2])]| \ + des_SPtrans[7][(T.c[3])]| \ + des_SPtrans[0][(U.c[0])]| \ + des_SPtrans[2][(U.c[1])]| \ + des_SPtrans[4][(U.c[2])]| \ + des_SPtrans[6][(U.c[3])]; +#else +#define D_ENCRYPT(L,R,S) \ + u=(R^s[S ]); \ + t=R^s[S+1]; \ + t=((t>>4)+(t<<28)); \ + L^= des_SPtrans[1][(t )&0x3f]| \ + des_SPtrans[3][(t>> 8)&0x3f]| \ + des_SPtrans[5][(t>>16)&0x3f]| \ + des_SPtrans[7][(t>>24)&0x3f]| \ + des_SPtrans[0][(u )&0x3f]| \ + des_SPtrans[2][(u>> 8)&0x3f]| \ + des_SPtrans[4][(u>>16)&0x3f]| \ + des_SPtrans[6][(u>>24)&0x3f]; +#endif +#endif + + /* IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + + The output has been subject to swaps of the form + 0 1 -> 3 1 but the odd and even bits have been put into + 2 3 2 0 + different words. The main trick is to remember that + t=((l>>size)^r)&(mask); + r^=t; + l^=(t<<size); + can be used to swap and move bits between words. + + So l = 0 1 2 3 r = 16 17 18 19 + 4 5 6 7 20 21 22 23 + 8 9 10 11 24 25 26 27 + 12 13 14 15 28 29 30 31 + becomes (for size == 2 and mask == 0x3333) + t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 + 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 + 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 + 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 + + Thanks for hints from Richard Outerbridge - he told me IP&FP + could be done in 15 xor, 10 shifts and 5 ands. + When I finally started to think of the problem in 2D + I first got ~42 operations without xors. When I remembered + how to use xors :-) I got it to its final state. + */ +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + diff --git a/eBones/des/include/podd.h b/eBones/des/include/podd.h new file mode 100644 index 0000000..52b89d3 --- /dev/null +++ b/eBones/des/include/podd.h @@ -0,0 +1,24 @@ +/* podd.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: podd.h,v 1.2 1994/07/19 19:22:20 g89r4222 Exp $ + */ + +static unsigned char odd_parity[256]={ + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254}; diff --git a/eBones/des/include/sk.h b/eBones/des/include/sk.h new file mode 100644 index 0000000..5aaf7d8 --- /dev/null +++ b/eBones/des/include/sk.h @@ -0,0 +1,145 @@ +/* sk.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: sk.h,v 1.2 1994/07/19 19:22:22 g89r4222 Exp $ + */ + +static unsigned long des_skb[8][64]={ +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000,0x00000010,0x20000000,0x20000010, +0x00010000,0x00010010,0x20010000,0x20010010, +0x00000800,0x00000810,0x20000800,0x20000810, +0x00010800,0x00010810,0x20010800,0x20010810, +0x00000020,0x00000030,0x20000020,0x20000030, +0x00010020,0x00010030,0x20010020,0x20010030, +0x00000820,0x00000830,0x20000820,0x20000830, +0x00010820,0x00010830,0x20010820,0x20010830, +0x00080000,0x00080010,0x20080000,0x20080010, +0x00090000,0x00090010,0x20090000,0x20090010, +0x00080800,0x00080810,0x20080800,0x20080810, +0x00090800,0x00090810,0x20090800,0x20090810, +0x00080020,0x00080030,0x20080020,0x20080030, +0x00090020,0x00090030,0x20090020,0x20090030, +0x00080820,0x00080830,0x20080820,0x20080830, +0x00090820,0x00090830,0x20090820,0x20090830, +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ +0x00000000,0x02000000,0x00002000,0x02002000, +0x00200000,0x02200000,0x00202000,0x02202000, +0x00000004,0x02000004,0x00002004,0x02002004, +0x00200004,0x02200004,0x00202004,0x02202004, +0x00000400,0x02000400,0x00002400,0x02002400, +0x00200400,0x02200400,0x00202400,0x02202400, +0x00000404,0x02000404,0x00002404,0x02002404, +0x00200404,0x02200404,0x00202404,0x02202404, +0x10000000,0x12000000,0x10002000,0x12002000, +0x10200000,0x12200000,0x10202000,0x12202000, +0x10000004,0x12000004,0x10002004,0x12002004, +0x10200004,0x12200004,0x10202004,0x12202004, +0x10000400,0x12000400,0x10002400,0x12002400, +0x10200400,0x12200400,0x10202400,0x12202400, +0x10000404,0x12000404,0x10002404,0x12002404, +0x10200404,0x12200404,0x10202404,0x12202404, +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ +0x00000000,0x00000001,0x00040000,0x00040001, +0x01000000,0x01000001,0x01040000,0x01040001, +0x00000002,0x00000003,0x00040002,0x00040003, +0x01000002,0x01000003,0x01040002,0x01040003, +0x00000200,0x00000201,0x00040200,0x00040201, +0x01000200,0x01000201,0x01040200,0x01040201, +0x00000202,0x00000203,0x00040202,0x00040203, +0x01000202,0x01000203,0x01040202,0x01040203, +0x08000000,0x08000001,0x08040000,0x08040001, +0x09000000,0x09000001,0x09040000,0x09040001, +0x08000002,0x08000003,0x08040002,0x08040003, +0x09000002,0x09000003,0x09040002,0x09040003, +0x08000200,0x08000201,0x08040200,0x08040201, +0x09000200,0x09000201,0x09040200,0x09040201, +0x08000202,0x08000203,0x08040202,0x08040203, +0x09000202,0x09000203,0x09040202,0x09040203, +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ +0x00000000,0x00100000,0x00000100,0x00100100, +0x00000008,0x00100008,0x00000108,0x00100108, +0x00001000,0x00101000,0x00001100,0x00101100, +0x00001008,0x00101008,0x00001108,0x00101108, +0x04000000,0x04100000,0x04000100,0x04100100, +0x04000008,0x04100008,0x04000108,0x04100108, +0x04001000,0x04101000,0x04001100,0x04101100, +0x04001008,0x04101008,0x04001108,0x04101108, +0x00020000,0x00120000,0x00020100,0x00120100, +0x00020008,0x00120008,0x00020108,0x00120108, +0x00021000,0x00121000,0x00021100,0x00121100, +0x00021008,0x00121008,0x00021108,0x00121108, +0x04020000,0x04120000,0x04020100,0x04120100, +0x04020008,0x04120008,0x04020108,0x04120108, +0x04021000,0x04121000,0x04021100,0x04121100, +0x04021008,0x04121008,0x04021108,0x04121108, +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000,0x10000000,0x00010000,0x10010000, +0x00000004,0x10000004,0x00010004,0x10010004, +0x20000000,0x30000000,0x20010000,0x30010000, +0x20000004,0x30000004,0x20010004,0x30010004, +0x00100000,0x10100000,0x00110000,0x10110000, +0x00100004,0x10100004,0x00110004,0x10110004, +0x20100000,0x30100000,0x20110000,0x30110000, +0x20100004,0x30100004,0x20110004,0x30110004, +0x00001000,0x10001000,0x00011000,0x10011000, +0x00001004,0x10001004,0x00011004,0x10011004, +0x20001000,0x30001000,0x20011000,0x30011000, +0x20001004,0x30001004,0x20011004,0x30011004, +0x00101000,0x10101000,0x00111000,0x10111000, +0x00101004,0x10101004,0x00111004,0x10111004, +0x20101000,0x30101000,0x20111000,0x30111000, +0x20101004,0x30101004,0x20111004,0x30111004, +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ +0x00000000,0x08000000,0x00000008,0x08000008, +0x00000400,0x08000400,0x00000408,0x08000408, +0x00020000,0x08020000,0x00020008,0x08020008, +0x00020400,0x08020400,0x00020408,0x08020408, +0x00000001,0x08000001,0x00000009,0x08000009, +0x00000401,0x08000401,0x00000409,0x08000409, +0x00020001,0x08020001,0x00020009,0x08020009, +0x00020401,0x08020401,0x00020409,0x08020409, +0x02000000,0x0A000000,0x02000008,0x0A000008, +0x02000400,0x0A000400,0x02000408,0x0A000408, +0x02020000,0x0A020000,0x02020008,0x0A020008, +0x02020400,0x0A020400,0x02020408,0x0A020408, +0x02000001,0x0A000001,0x02000009,0x0A000009, +0x02000401,0x0A000401,0x02000409,0x0A000409, +0x02020001,0x0A020001,0x02020009,0x0A020009, +0x02020401,0x0A020401,0x02020409,0x0A020409, +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ +0x00000000,0x00000100,0x00080000,0x00080100, +0x01000000,0x01000100,0x01080000,0x01080100, +0x00000010,0x00000110,0x00080010,0x00080110, +0x01000010,0x01000110,0x01080010,0x01080110, +0x00200000,0x00200100,0x00280000,0x00280100, +0x01200000,0x01200100,0x01280000,0x01280100, +0x00200010,0x00200110,0x00280010,0x00280110, +0x01200010,0x01200110,0x01280010,0x01280110, +0x00000200,0x00000300,0x00080200,0x00080300, +0x01000200,0x01000300,0x01080200,0x01080300, +0x00000210,0x00000310,0x00080210,0x00080310, +0x01000210,0x01000310,0x01080210,0x01080310, +0x00200200,0x00200300,0x00280200,0x00280300, +0x01200200,0x01200300,0x01280200,0x01280300, +0x00200210,0x00200310,0x00280210,0x00280310, +0x01200210,0x01200310,0x01280210,0x01280310, +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ +0x00000000,0x04000000,0x00040000,0x04040000, +0x00000002,0x04000002,0x00040002,0x04040002, +0x00002000,0x04002000,0x00042000,0x04042000, +0x00002002,0x04002002,0x00042002,0x04042002, +0x00000020,0x04000020,0x00040020,0x04040020, +0x00000022,0x04000022,0x00040022,0x04040022, +0x00002020,0x04002020,0x00042020,0x04042020, +0x00002022,0x04002022,0x00042022,0x04042022, +0x00000800,0x04000800,0x00040800,0x04040800, +0x00000802,0x04000802,0x00040802,0x04040802, +0x00002800,0x04002800,0x00042800,0x04042800, +0x00002802,0x04002802,0x00042802,0x04042802, +0x00000820,0x04000820,0x00040820,0x04040820, +0x00000822,0x04000822,0x00040822,0x04040822, +0x00002820,0x04002820,0x00042820,0x04042820, +0x00002822,0x04002822,0x00042822,0x04042822, +}; diff --git a/eBones/des/include/spr.h b/eBones/des/include/spr.h new file mode 100644 index 0000000..dbe2ae1 --- /dev/null +++ b/eBones/des/include/spr.h @@ -0,0 +1,151 @@ +/* spr.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: spr.h,v 1.2 1994/07/19 19:22:23 g89r4222 Exp $ + */ + +static unsigned long des_SPtrans[8][64]={ +/* nibble 0 */ +0x00820200, 0x00020000, 0x80800000, 0x80820200, +0x00800000, 0x80020200, 0x80020000, 0x80800000, +0x80020200, 0x00820200, 0x00820000, 0x80000200, +0x80800200, 0x00800000, 0x00000000, 0x80020000, +0x00020000, 0x80000000, 0x00800200, 0x00020200, +0x80820200, 0x00820000, 0x80000200, 0x00800200, +0x80000000, 0x00000200, 0x00020200, 0x80820000, +0x00000200, 0x80800200, 0x80820000, 0x00000000, +0x00000000, 0x80820200, 0x00800200, 0x80020000, +0x00820200, 0x00020000, 0x80000200, 0x00800200, +0x80820000, 0x00000200, 0x00020200, 0x80800000, +0x80020200, 0x80000000, 0x80800000, 0x00820000, +0x80820200, 0x00020200, 0x00820000, 0x80800200, +0x00800000, 0x80000200, 0x80020000, 0x00000000, +0x00020000, 0x00800000, 0x80800200, 0x00820200, +0x80000000, 0x80820000, 0x00000200, 0x80020200, + +/* nibble 1 */ +0x10042004, 0x00000000, 0x00042000, 0x10040000, +0x10000004, 0x00002004, 0x10002000, 0x00042000, +0x00002000, 0x10040004, 0x00000004, 0x10002000, +0x00040004, 0x10042000, 0x10040000, 0x00000004, +0x00040000, 0x10002004, 0x10040004, 0x00002000, +0x00042004, 0x10000000, 0x00000000, 0x00040004, +0x10002004, 0x00042004, 0x10042000, 0x10000004, +0x10000000, 0x00040000, 0x00002004, 0x10042004, +0x00040004, 0x10042000, 0x10002000, 0x00042004, +0x10042004, 0x00040004, 0x10000004, 0x00000000, +0x10000000, 0x00002004, 0x00040000, 0x10040004, +0x00002000, 0x10000000, 0x00042004, 0x10002004, +0x10042000, 0x00002000, 0x00000000, 0x10000004, +0x00000004, 0x10042004, 0x00042000, 0x10040000, +0x10040004, 0x00040000, 0x00002004, 0x10002000, +0x10002004, 0x00000004, 0x10040000, 0x00042000, + +/* nibble 2 */ +0x41000000, 0x01010040, 0x00000040, 0x41000040, +0x40010000, 0x01000000, 0x41000040, 0x00010040, +0x01000040, 0x00010000, 0x01010000, 0x40000000, +0x41010040, 0x40000040, 0x40000000, 0x41010000, +0x00000000, 0x40010000, 0x01010040, 0x00000040, +0x40000040, 0x41010040, 0x00010000, 0x41000000, +0x41010000, 0x01000040, 0x40010040, 0x01010000, +0x00010040, 0x00000000, 0x01000000, 0x40010040, +0x01010040, 0x00000040, 0x40000000, 0x00010000, +0x40000040, 0x40010000, 0x01010000, 0x41000040, +0x00000000, 0x01010040, 0x00010040, 0x41010000, +0x40010000, 0x01000000, 0x41010040, 0x40000000, +0x40010040, 0x41000000, 0x01000000, 0x41010040, +0x00010000, 0x01000040, 0x41000040, 0x00010040, +0x01000040, 0x00000000, 0x41010000, 0x40000040, +0x41000000, 0x40010040, 0x00000040, 0x01010000, + +/* nibble 3 */ +0x00100402, 0x04000400, 0x00000002, 0x04100402, +0x00000000, 0x04100000, 0x04000402, 0x00100002, +0x04100400, 0x04000002, 0x04000000, 0x00000402, +0x04000002, 0x00100402, 0x00100000, 0x04000000, +0x04100002, 0x00100400, 0x00000400, 0x00000002, +0x00100400, 0x04000402, 0x04100000, 0x00000400, +0x00000402, 0x00000000, 0x00100002, 0x04100400, +0x04000400, 0x04100002, 0x04100402, 0x00100000, +0x04100002, 0x00000402, 0x00100000, 0x04000002, +0x00100400, 0x04000400, 0x00000002, 0x04100000, +0x04000402, 0x00000000, 0x00000400, 0x00100002, +0x00000000, 0x04100002, 0x04100400, 0x00000400, +0x04000000, 0x04100402, 0x00100402, 0x00100000, +0x04100402, 0x00000002, 0x04000400, 0x00100402, +0x00100002, 0x00100400, 0x04100000, 0x04000402, +0x00000402, 0x04000000, 0x04000002, 0x04100400, + +/* nibble 4 */ +0x02000000, 0x00004000, 0x00000100, 0x02004108, +0x02004008, 0x02000100, 0x00004108, 0x02004000, +0x00004000, 0x00000008, 0x02000008, 0x00004100, +0x02000108, 0x02004008, 0x02004100, 0x00000000, +0x00004100, 0x02000000, 0x00004008, 0x00000108, +0x02000100, 0x00004108, 0x00000000, 0x02000008, +0x00000008, 0x02000108, 0x02004108, 0x00004008, +0x02004000, 0x00000100, 0x00000108, 0x02004100, +0x02004100, 0x02000108, 0x00004008, 0x02004000, +0x00004000, 0x00000008, 0x02000008, 0x02000100, +0x02000000, 0x00004100, 0x02004108, 0x00000000, +0x00004108, 0x02000000, 0x00000100, 0x00004008, +0x02000108, 0x00000100, 0x00000000, 0x02004108, +0x02004008, 0x02004100, 0x00000108, 0x00004000, +0x00004100, 0x02004008, 0x02000100, 0x00000108, +0x00000008, 0x00004108, 0x02004000, 0x02000008, + +/* nibble 5 */ +0x20000010, 0x00080010, 0x00000000, 0x20080800, +0x00080010, 0x00000800, 0x20000810, 0x00080000, +0x00000810, 0x20080810, 0x00080800, 0x20000000, +0x20000800, 0x20000010, 0x20080000, 0x00080810, +0x00080000, 0x20000810, 0x20080010, 0x00000000, +0x00000800, 0x00000010, 0x20080800, 0x20080010, +0x20080810, 0x20080000, 0x20000000, 0x00000810, +0x00000010, 0x00080800, 0x00080810, 0x20000800, +0x00000810, 0x20000000, 0x20000800, 0x00080810, +0x20080800, 0x00080010, 0x00000000, 0x20000800, +0x20000000, 0x00000800, 0x20080010, 0x00080000, +0x00080010, 0x20080810, 0x00080800, 0x00000010, +0x20080810, 0x00080800, 0x00080000, 0x20000810, +0x20000010, 0x20080000, 0x00080810, 0x00000000, +0x00000800, 0x20000010, 0x20000810, 0x20080800, +0x20080000, 0x00000810, 0x00000010, 0x20080010, + +/* nibble 6 */ +0x00001000, 0x00000080, 0x00400080, 0x00400001, +0x00401081, 0x00001001, 0x00001080, 0x00000000, +0x00400000, 0x00400081, 0x00000081, 0x00401000, +0x00000001, 0x00401080, 0x00401000, 0x00000081, +0x00400081, 0x00001000, 0x00001001, 0x00401081, +0x00000000, 0x00400080, 0x00400001, 0x00001080, +0x00401001, 0x00001081, 0x00401080, 0x00000001, +0x00001081, 0x00401001, 0x00000080, 0x00400000, +0x00001081, 0x00401000, 0x00401001, 0x00000081, +0x00001000, 0x00000080, 0x00400000, 0x00401001, +0x00400081, 0x00001081, 0x00001080, 0x00000000, +0x00000080, 0x00400001, 0x00000001, 0x00400080, +0x00000000, 0x00400081, 0x00400080, 0x00001080, +0x00000081, 0x00001000, 0x00401081, 0x00400000, +0x00401080, 0x00000001, 0x00001001, 0x00401081, +0x00400001, 0x00401080, 0x00401000, 0x00001001, + +/* nibble 7 */ +0x08200020, 0x08208000, 0x00008020, 0x00000000, +0x08008000, 0x00200020, 0x08200000, 0x08208020, +0x00000020, 0x08000000, 0x00208000, 0x00008020, +0x00208020, 0x08008020, 0x08000020, 0x08200000, +0x00008000, 0x00208020, 0x00200020, 0x08008000, +0x08208020, 0x08000020, 0x00000000, 0x00208000, +0x08000000, 0x00200000, 0x08008020, 0x08200020, +0x00200000, 0x00008000, 0x08208000, 0x00000020, +0x00200000, 0x00008000, 0x08000020, 0x08208020, +0x00008020, 0x08000000, 0x00000000, 0x00208000, +0x08200020, 0x08008020, 0x08008000, 0x00200020, +0x08208000, 0x00000020, 0x00200020, 0x08008000, +0x08208020, 0x00200000, 0x08200000, 0x08000020, +0x00208000, 0x00008020, 0x08008020, 0x08200000, +0x00000020, 0x08208000, 0x00208020, 0x00000000, +0x08000000, 0x08200020, 0x00008000, 0x00208020}; diff --git a/eBones/des/ofb_enc.c b/eBones/des/ofb_enc.c new file mode 100644 index 0000000..9a94372 --- /dev/null +++ b/eBones/des/ofb_enc.c @@ -0,0 +1,72 @@ +/* ofb_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: ofb_enc.c,v 1.2 1994/07/19 19:21:59 g89r4222 Exp $ + */ + +#include "des_locl.h" + +/* The input and output are loaded in multiples of 8 bits. + * What this means is that if you hame numbits=12 and length=2 + * the first 12 bits will be retrieved from the first byte and half + * the second. The second 12 bits will come from the 3rd and half the 4th + * byte. + */ +int des_ofb_encrypt(in,out,numbits,length,schedule,ivec) +unsigned char *in,*out; +int numbits; +long length; +des_key_schedule schedule; +des_cblock *ivec; + { + register unsigned long d0,d1,v0,v1,n=(numbits+7)/8; + register unsigned long mask0,mask1; + register long l=length; + register int num=numbits; + unsigned long ti[2]; + unsigned char *iv; + + if (num > 64) return(0); + if (num > 32) + { + mask0=0xffffffff; + if (num >= 64) + mask1=mask0; + else + mask1=(1L<<(num-32))-1; + } + else + { + if (num == 32) + mask0=0xffffffff; + else + mask0=(1L<<num)-1; + mask1=0x00000000; + } + + iv=(unsigned char *)ivec; + c2l(iv,v0); + c2l(iv,v1); + ti[0]=v0; + ti[1]=v1; + while (l-- > 0) + { + des_encrypt((unsigned long *)ti,(unsigned long *)ti, + schedule,DES_ENCRYPT); + c2ln(in,d0,d1,n); + in+=n; + d0=(d0^ti[0])&mask0; + d1=(d1^ti[1])&mask1; + l2cn(d0,d1,out,n); + out+=n; + } + v0=ti[0]; + v1=ti[1]; + iv=(unsigned char *)ivec; + l2c(v0,iv); + l2c(v1,iv); + v0=v1=d0=d1=ti[0]=ti[1]=0; + return(0); + } + diff --git a/eBones/des/pcbc_enc.c b/eBones/des/pcbc_enc.c new file mode 100644 index 0000000..216bdb2 --- /dev/null +++ b/eBones/des/pcbc_enc.c @@ -0,0 +1,78 @@ +/* pcbc_enc.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: pcbc_enc.c,v 1.2 1994/07/19 19:22:01 g89r4222 Exp $ + */ + +#include "des_locl.h" + +int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +register long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; + { + register unsigned long sin0,sin1,xor0,xor1,tout0,tout1; + unsigned long tin[2],tout[2]; + unsigned char *in,*out,*iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + if (encrypt) + { + c2l(iv,xor0); + c2l(iv,xor1); + for (; length>0; length-=8) + { + if (length >= 8) + { + c2l(in,sin0); + c2l(in,sin1); + } + else + c2ln(in,sin0,sin1,length); + tin[0]=sin0^xor0; + tin[1]=sin1^xor1; + des_encrypt((unsigned long *)tin,(unsigned long *)tout, + schedule,encrypt); + tout0=tout[0]; + tout1=tout[1]; + xor0=sin0^tout[0]; + xor1=sin1^tout[1]; + l2c(tout0,out); + l2c(tout1,out); + } + } + else + { + c2l(iv,xor0); c2l(iv,xor1); + for (; length>0; length-=8) + { + c2l(in,sin0); + c2l(in,sin1); + tin[0]=sin0; + tin[1]=sin1; + des_encrypt((unsigned long *)tin,(unsigned long *)tout, + schedule,encrypt); + tout0=tout[0]^xor0; + tout1=tout[1]^xor1; + if (length >= 8) + { + l2c(tout0,out); + l2c(tout1,out); + } + else + l2cn(tout0,tout1,out,length); + xor0=tout0^sin0; + xor1=tout1^sin1; + } + } + tin[0]=tin[1]=tout[0]=tout[1]=0; + sin0=sin1=xor0=xor1=tout0=tout1=0; + return(0); + } diff --git a/eBones/des/qud_cksm.c b/eBones/des/qud_cksm.c new file mode 100644 index 0000000..eb7773f --- /dev/null +++ b/eBones/des/qud_cksm.c @@ -0,0 +1,93 @@ +/* qud_cksm.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: qud_cksm.c,v 1.2 1994/07/19 19:22:02 g89r4222 Exp $ + */ + +/* From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer + * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 + * This module in only based on the code in this paper and is + * almost definitely not the same as the MIT implementation. + */ +#include "des_locl.h" + +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ +#define B0(a) (((unsigned long)(a))) +#define B1(a) (((unsigned long)(a))<<8) +#define B2(a) (((unsigned long)(a))<<16) +#define B3(a) (((unsigned long)(a))<<24) + +/* used to scramble things a bit */ +/* Got the value MIT uses via brute force :-) 2/10/90 eay */ +#define NOISE ((unsigned long)83653421) + +unsigned long des_quad_cksum(input,output,length,out_count,seed) +des_cblock *input; +des_cblock *output; +long length; +int out_count; +des_cblock *seed; + { + unsigned long z0,z1,t0,t1; + int i; + long l=0; + unsigned char *cp; + unsigned char *lp; + + if (out_count < 1) out_count=1; + lp=(unsigned char *)output; + + z0=B0((*seed)[0])|B1((*seed)[1])|B2((*seed)[2])|B3((*seed)[3]); + z1=B0((*seed)[4])|B1((*seed)[5])|B2((*seed)[6])|B3((*seed)[7]); + + for (i=0; ((i<4)&&(i<out_count)); i++) + { + cp=(unsigned char *)input; + l=length; + while (l > 0) + { + if (l > 1) + { + t0= (unsigned long)(*(cp++)); + t0|=(unsigned long)B1(*(cp++)); + l--; + } + else + t0= (unsigned long)(*(cp++)); + l--; + /* add */ + t0+=z0; + t0&=0xffffffff; + t1=z1; + /* square, well sort of square */ + z0=((((t0*t0)&0xffffffff)+((t1*t1)&0xffffffff)) + &0xffffffff)%0x7fffffff; + z1=((t0*((t1+NOISE)&0xffffffff))&0xffffffff)%0x7fffffff; + } + if (lp != NULL) + { + /* I believe I finally have things worked out. + * The MIT library assumes that the checksum + * is one huge number and it is returned in a + * host dependant byte order. + */ + static unsigned long l=1; + static unsigned char *c=(unsigned char *)&l; + + if (c[0]) + { + l2c(z0,lp); + l2c(z1,lp); + } + else + { + lp=output[out_count-i-1]; + l2n(z1,lp); + l2n(z0,lp); + } + } + } + return(z0); + } + diff --git a/eBones/des/rand_key.c b/eBones/des/rand_key.c new file mode 100644 index 0000000..d8d2345 --- /dev/null +++ b/eBones/des/rand_key.c @@ -0,0 +1,45 @@ +/* rand_key.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: rand_key.c,v 1.2 1994/07/19 19:22:04 g89r4222 Exp $ + */ + +#include "des_locl.h" + +int des_random_key(ret) +des_cblock ret; + { + des_key_schedule ks; + static unsigned long c=0; + static unsigned short pid=0; + static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + des_cblock key; + unsigned char *p; + unsigned long t; + +#ifdef MSDOS + pid=1; +#else + if (!pid) pid=getpid(); +#endif + p=key; + t=(unsigned long)time(NULL); + l2c(t,p); + t=(unsigned long)((pid)|((c++)<<16)); + l2c(t,p); + + des_set_odd_parity((des_cblock *)data); + des_set__key((des_cblock *)data,ks); + des_cbc_cksum((des_cblock *)key,(des_cblock *)key, + (long)sizeof(key),ks,(des_cblock *)data); + des_set_odd_parity((des_cblock *)key); + des_cbc_cksum((des_cblock *)key,(des_cblock *)key, + (long)sizeof(key),ks,(des_cblock *)data); + + bcopy(key,ret,sizeof(key)); + bzero(key,sizeof(key)); + bzero(ks,sizeof(ks)); + t=0; + return(0); + } diff --git a/eBones/des/read_pwd.c b/eBones/des/read_pwd.c new file mode 100644 index 0000000..8375f64 --- /dev/null +++ b/eBones/des/read_pwd.c @@ -0,0 +1,333 @@ +/* read_pwd.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ +/* 06-Apr-92 Luke Brennan Support for VMS */ + +/*- + * $Id: read_pwd.c,v 1.2 1994/07/19 19:22:05 g89r4222 Exp $ + */ + +#include "des_locl.h" +#include <string.h> +#include <signal.h> +#include <setjmp.h> + +#include <sys/param.h> + +#ifdef BSD +#include <pwd.h> +extern char * getpass(const char * prompt); +#endif + +#ifndef VMS +#ifndef MSDOS +#ifndef _IRIX +#ifdef CRAY +#include <termio.h> +#define sgttyb termio +#define sg_flags c_lflag +#else /* !CRAY */ +#include <sgtty.h> +#endif +#include <sys/ioctl.h> +#else /* _IRIX */ +struct sgttyb { + char sg_ispeed; /* input speed */ + char sg_ospeed; /* output speed */ + char sg_erase; /* erase character */ + char sg_kill; /* kill character */ + short sg_flags; /* mode flags */ + }; +#endif +#else /* MSDOS */ +#define fgets(a,b,c) noecho_fgets(a,b,c) +#ifndef NSIG +#define NSIG 32 +#endif +#endif +#else /* VMS */ +#include <ssdef.h> +#include <iodef.h> +#include <ttdef.h> +#include <descrip.h> +struct IOSB { + short iosb$w_value; + short iosb$w_count; + long iosb$l_info; + }; +#endif + +static void read_till_nl(); +static int read_pw(); +static void recsig(); +static void pushsig(); +static void popsig(); +#ifdef MSDOS +static int noecho_fgets(); +#endif + +static void (*savsig[NSIG])(); +static jmp_buf save; + +int des_read_password(key,prompt,verify) +des_cblock *key; +char *prompt; +int verify; + { + int ok; + char buf[BUFSIZ],buff[BUFSIZ]; + + if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0) + des_string_to_key(buf,key); + bzero(buf,BUFSIZ); + bzero(buff,BUFSIZ); + return(ok); + } + +int des_read_2passwords(key1,key2,prompt,verify) +des_cblock *key1; +des_cblock *key2; +char *prompt; +int verify; + { + int ok; + char buf[BUFSIZ],buff[BUFSIZ]; + + if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0) + des_string_to_2keys(buf,key1,key2); + bzero(buf,BUFSIZ); + bzero(buff,BUFSIZ); + return(ok); + } + +#if defined(BSD) +int des_read_pw_string(buf, length, prompt, verify) + char *buf; + int length; + char * prompt; + int verify; +{ + int len = MIN(_PASSWORD_LEN, length); + char * s; + int ok = 0; + + fflush(stdout); + while (!ok) { + s = getpass(prompt); + strncpy(buf, s, len); + if(verify) { + printf("\nVerifying password"); fflush(stdout); + if(strncmp(getpass(prompt), buf, len) != 0) { + printf("\nVerify failure - try again\n"); + fflush(stdout); + continue; + } + } + ok = 1; + buf[len-1] = '\0'; + } + return (!ok); +} + +#else /* BSD */ + +int des_read_pw_string(buf,length,prompt,verify) +char *buf; +int length; +char *prompt; +int verify; + { + char buff[BUFSIZ]; + int ret; + + ret=read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); + bzero(buff,BUFSIZ); + return(ret); + } +#endif + +static void read_till_nl(in) +FILE *in; + { +#define SIZE 4 + char buf[SIZE+1]; + + do { + fgets(buf,SIZE,in); + } while (index(buf,'\n') == NULL); + } + +/* return 0 if ok, 1 (or -1) otherwise */ +static int read_pw(buf,buff,size,prompt,verify) +char *buf,*buff; +int size; +char *prompt; +int verify; + { +#ifndef VMS +#ifndef MSDOS + struct sgttyb tty_orig,tty_new; +#endif /* !MSDOS */ +#else + struct IOSB iosb; + $DESCRIPTOR(terminal,"TT"); + long tty_orig[3], tty_new[3]; + long status; + unsigned short channel = 0; +#endif + int ok=0; + char *p; + int ps=0; + FILE *tty; + +#ifndef MSDOS + if ((tty=fopen("/dev/tty","r")) == NULL) + tty=stdin; +#else /* MSDOS */ + if ((tty=fopen("con","r")) == NULL) + tty=stdin; +#endif /* MSDOS */ +#ifndef VMS +#ifdef TIOCGETP + if (ioctl(fileno(tty),TIOCGETP,(char *)&tty_orig) == -1) + return(-1); + bcopy(&(tty_orig),&(tty_new),sizeof(tty_orig)); +#endif +#else /* VMS */ + status = SYS$ASSIGN(&terminal,&channel,0,0); + if (status != SS$_NORMAL) + return(-1); + status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return(-1); +#endif + + if (setjmp(save)) + { + ok=0; + goto error; + } + pushsig(); + ps=1; +#ifndef VMS +#ifndef MSDOS + tty_new.sg_flags &= ~ECHO; +#endif /* !MSDOS */ +#ifdef TIOCSETP + if (ioctl(fileno(tty),TIOCSETP,(char *)&tty_new) == -1) + return(-1); +#endif +#else /* VMS */ + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1] | TT$M_NOECHO; + tty_new[2] = tty_orig[2]; + status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return(-1); +#endif /* VMS */ + ps=2; + + fflush(stdout); + fflush(stderr); + while (!ok) + { + fputs(prompt,stderr); + fflush(stderr); + + buf[0]='\0'; + fgets(buf,size,tty); + if (feof(tty)) goto error; + if ((p=(char *)index(buf,'\n')) != NULL) + *p='\0'; + else read_till_nl(tty); + if (verify) + { + fprintf(stderr,"\nVerifying password %s",prompt); + fflush(stderr); + buff[0]='\0'; + fgets(buff,size,tty); + if (feof(tty)) goto error; + if ((p=(char *)index(buff,'\n')) != NULL) + *p='\0'; + else read_till_nl(tty); + + if (strcmp(buf,buff) != 0) + { + fprintf(stderr,"\nVerify failure - try again\n"); + fflush(stderr); + continue; + } + } + ok=1; + } + +error: + fprintf(stderr,"\n"); + /* What can we do if there is an error? */ +#ifndef VMS +#ifdef TIOCSETP + if (ps >= 2) ioctl(fileno(tty),TIOCSETP,(char *)&tty_orig); +#endif +#else /* VMS */ + if (ps >= 2) + status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0 + ,tty_orig,12,0,0,0,0); +#endif /* VMS */ + + if (ps >= 1) popsig(); + if (stdin != tty) fclose(tty); +#ifdef VMS + status = SYS$DASSGN(channel); +#endif + return(!ok); + } + +static void pushsig() + { + int i; + + for (i=0; i<NSIG; i++) + savsig[i]=signal(i,recsig); + } + +static void popsig() + { + int i; + + for (i=0; i<NSIG; i++) + signal(i,savsig[i]); + } + +static void recsig() + { + longjmp(save,1); + } + +#ifdef MSDOS +static int noecho_fgets(buf,size,tty) +char *buf; +int size; +FILE *tty; + { + int i; + char *p; + + p=buf; + for (;;) + { + if (size == 0) + { + *p='\0'; + break; + } + size--; + i=getch(); + if (i == '\r') i='\n'; + *(p++)=i; + if (i == '\n') + { + *p='\0'; + break; + } + } + } +#endif diff --git a/eBones/des/set_key.c b/eBones/des/set_key.c new file mode 100644 index 0000000..f1ca3f4 --- /dev/null +++ b/eBones/des/set_key.c @@ -0,0 +1,190 @@ +/* set_key.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ +/* set_key.c v 1.4 eay 24/9/91 + * 1.4 Speed up by 400% :-) + * 1.3 added register declarations. + * 1.2 unrolled make_key_sched a bit more + * 1.1 added norm_expand_bits + * 1.0 First working version + */ + +/*- + * $Id: set_key.c,v 1.2 1994/07/19 19:22:07 g89r4222 Exp $ + */ + +#include "des_locl.h" +#include "podd.h" +#include "sk.h" + +static int check_parity(); + +int des_check_key=0; + +void des_set_odd_parity(key) +des_cblock *key; + { + int i; + + for (i=0; i<DES_KEY_SZ; i++) + (*key)[i]=odd_parity[(*key)[i]]; + } + +static int check_parity(key) +des_cblock *key; + { + int i; + + for (i=0; i<DES_KEY_SZ; i++) + { + if ((*key)[i] != odd_parity[(*key)[i]]) + return(0); + } + return(1); + } + +/* Weak and semi week keys as take from + * %A D.W. Davies + * %A W.L. Price + * %T Security for Computer Networks + * %I John Wiley & Sons + * %D 1984 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference + * (and actual cblock values). + */ +#define NUM_WEAK_KEY 16 +static des_cblock weak_keys[NUM_WEAK_KEY]={ + /* weak keys */ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, + 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0, + /* semi-weak keys */ + 0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE, + 0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01, + 0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1, + 0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E, + 0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1, + 0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01, + 0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE, + 0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E, + 0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E, + 0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01, + 0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE, + 0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}; + +int des_is_weak_key(key) +des_cblock *key; + { + int i; + + for (i=0; i<NUM_WEAK_KEY; i++) + /* Added == 0 to comparision, I obviously don't run + * this section very often :-(, thanks to + * engineering@MorningStar.Com for the fix + * eay 93/06/29 */ + if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1); + return(0); + } + +/* NOW DEFINED IN des_local.h + * See ecb_encrypt.c for a pseudo description of these macros. + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + * (b)^=(t),\ + * (a)=((a)^((t)<<(n)))) + */ + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n)))) + +static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; + +/* return 0 if key parity is odd (correct), + * return -1 if key parity error, + * return -2 if illegal weak key. + */ +int des_set__key(key,schedule) +des_cblock *key; +des_key_schedule schedule; + { + register unsigned long c,d,t,s; + register unsigned char *in; + register unsigned long *k; + register int i; + + if (des_check_key) + { + if (!check_parity(key)) + return(-1); + + if (des_is_weak_key(key)) + return(-2); + } + + k=(unsigned long *)schedule; + in=(unsigned char *)key; + + c2l(in,c); + c2l(in,d); + + /* do PC1 in 60 simple operations */ +/* PERM_OP(d,c,t,4,0x0f0f0f0f); + HPERM_OP(c,t,-2, 0xcccc0000); + HPERM_OP(c,t,-1, 0xaaaa0000); + HPERM_OP(c,t, 8, 0x00ff0000); + HPERM_OP(c,t,-1, 0xaaaa0000); + HPERM_OP(d,t,-8, 0xff000000); + HPERM_OP(d,t, 8, 0x00ff0000); + HPERM_OP(d,t, 2, 0x33330000); + d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55); + d=(d>>8)|((c&0xf0000000)>>4); + c&=0x0fffffff; */ + + /* I now do it in 47 simple operations :-) + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + * for the inspiration. :-) */ + PERM_OP (d,c,t,4,0x0f0f0f0f); + HPERM_OP(c,t,-2,0xcccc0000); + HPERM_OP(d,t,-2,0xcccc0000); + PERM_OP (d,c,t,1,0x55555555); + PERM_OP (c,d,t,8,0x00ff00ff); + PERM_OP (d,c,t,1,0x55555555); + d= (((d&0x000000ff)<<16)| (d&0x0000ff00) | + ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4)); + c&=0x0fffffff; + + for (i=0; i<ITERATIONS; i++) + { + if (shifts2[i]) + { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); } + else + { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); } + c&=0x0fffffff; + d&=0x0fffffff; + /* could be a few less shifts but I am to lazy at this + * point in time to investigate */ + s= des_skb[0][ (c )&0x3f ]| + des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]| + des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]| + des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) | + ((c>>22)&0x38)]; + t= des_skb[4][ (d )&0x3f ]| + des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]| + des_skb[6][ (d>>15)&0x3f ]| + des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)]; + + /* table contained 0213 4657 */ + *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff; + s= ((s>>16)|(t&0xffff0000)); + + s=(s<<4)|(s>>28); + *(k++)=s&0xffffffff; + } + return(0); + } + +int des_key_sched(key,schedule) +des_cblock *key; +des_key_schedule schedule; + { + return(des_set__key(key,schedule)); + } diff --git a/eBones/des/str2key.c b/eBones/des/str2key.c new file mode 100644 index 0000000..baad3c2 --- /dev/null +++ b/eBones/des/str2key.c @@ -0,0 +1,121 @@ +/* str2key.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ + +/*- + * $Id: str2key.c,v 1.2 1994/07/19 19:22:08 g89r4222 Exp $ + */ + +#include "des_locl.h" + +extern int des_check_key; + +int des_string_to_key(str,key) +char *str; +des_cblock *key; + { + des_key_schedule ks; + int i,length; + register unsigned char j; + + bzero(key,8); + length=strlen(str); +#ifdef OLD_STR_TO_KEY + for (i=0; i<length; i++) + (*key)[i%8]^=(str[i]<<1); +#else /* MIT COMPATIBLE */ + for (i=0; i<length; i++) + { + j=str[i]; + if ((i%16) < 8) + (*key)[i%8]^=(j<<1); + else + { + /* Reverse the bit order 05/05/92 eay */ + j=((j<<4)&0xf0)|((j>>4)&0x0f); + j=((j<<2)&0xcc)|((j>>2)&0x33); + j=((j<<1)&0xaa)|((j>>1)&0x55); + (*key)[7-(i%8)]^=j; + } + } +#endif + des_set_odd_parity((des_cblock *)key); + i=des_check_key; + des_check_key=0; + des_set__key((des_cblock *)key,ks); + des_check_key=i; + des_cbc_cksum((des_cblock *)str,(des_cblock *)key,(long)length,ks, + (des_cblock *)key); + bzero(ks,sizeof(ks)); + des_set_odd_parity((des_cblock *)key); + return(0); + } + +int des_string_to_2keys(str,key1,key2) +char *str; +des_cblock *key1,*key2; + { + des_key_schedule ks; + int i,length; + register unsigned char j; + + bzero(key1,8); + bzero(key2,8); + length=strlen(str); +#ifdef OLD_STR_TO_KEY + if (length <= 8) + { + for (i=0; i<length; i++) + { + (*key2)[i]=(*key1)[i]=(str[i]<<1); + } + } + else + { + for (i=0; i<length; i++) + { + if ((i/8)&1) + (*key2)[i%8]^=(str[i]<<1); + else + (*key1)[i%8]^=(str[i]<<1); + } + } +#else /* MIT COMPATIBLE */ + for (i=0; i<length; i++) + { + j=str[i]; + if ((i%32) < 16) + { + if ((i%16) < 8) + (*key1)[i%8]^=(j<<1); + else + (*key2)[i%8]^=(j<<1); + } + else + { + j=((j<<4)&0xf0)|((j>>4)&0x0f); + j=((j<<2)&0xcc)|((j>>2)&0x33); + j=((j<<1)&0xaa)|((j>>1)&0x55); + if ((i%16) < 8) + (*key1)[7-(i%8)]^=j; + else + (*key2)[7-(i%8)]^=j; + } + } + if (length <= 8) bcopy(key1,key2,8); +#endif + des_set_odd_parity((des_cblock *)key1); + des_set_odd_parity((des_cblock *)key2); + i=des_check_key; + des_check_key=0; + des_set__key((des_cblock *)key1,ks); + des_cbc_cksum((des_cblock *)str,(des_cblock *)key1,(long)length,ks, + (des_cblock *)key1); + des_set__key((des_cblock *)key2,ks); + des_cbc_cksum((des_cblock *)str,(des_cblock *)key2,(long)length,ks, + (des_cblock *)key2); + des_check_key=i; + bzero(ks,sizeof(ks)); + des_set_odd_parity(key1); + des_set_odd_parity(key2); + return(0); + } diff --git a/eBones/des/test/Makefile b/eBones/des/test/Makefile new file mode 100644 index 0000000..e636a3a --- /dev/null +++ b/eBones/des/test/Makefile @@ -0,0 +1,9 @@ +# from: @(#)Makefile 5.4 (Berkeley) 5/11/90 +# $Id: Makefile,v 1.2 1994/07/19 19:22:28 g89r4222 Exp $ + +PROG= destest +CFLAGS+= -I${.CURDIR}/../include +DPADD= ${LIBDES} +LDADD= -ldes + +.include <bsd.prog.mk> diff --git a/eBones/des/test/destest.c b/eBones/des/test/destest.c new file mode 100644 index 0000000..bc0552c --- /dev/null +++ b/eBones/des/test/destest.c @@ -0,0 +1,365 @@ +/* destest.c */ +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include <stdio.h> +#include "des_locl.h" /* for des.h and bcopy macros */ +/* tisk tisk - the test keys don't all have odd parity :-( */ + +/* test data */ +#define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8]={ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10, + 0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57, + 0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E, + 0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86, + 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, + 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, + 0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE, + 0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6, + 0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE, + 0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16, + 0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F, + 0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46, + 0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E, + 0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76, + 0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07, + 0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F, + 0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7, + 0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF, + 0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6, + 0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E, + 0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}; + +static unsigned char plain_data[NUM_TESTS][8]={ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42, + 0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA, + 0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72, + 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A, + 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2, + 0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A, + 0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2, + 0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A, + 0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02, + 0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A, + 0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32, + 0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA, + 0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62, + 0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2, + 0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA, + 0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92, + 0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A, + 0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2, + 0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + +static unsigned char cipher_data[NUM_TESTS][8]={ + 0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7, + 0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58, + 0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B, + 0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33, + 0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D, + 0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD, + 0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7, + 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4, + 0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B, + 0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71, + 0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A, + 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A, + 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95, + 0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B, + 0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09, + 0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A, + 0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F, + 0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88, + 0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77, + 0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A, + 0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56, + 0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56, + 0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56, + 0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC, + 0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A, + 0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41, + 0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93, + 0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00, + 0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06, + 0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7, + 0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51, + 0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE, + 0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D, + 0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}; + +static unsigned char cbc_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cbc_iv[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static unsigned char cbc_data[40]="7654321 Now is the time for "; + +static unsigned char cbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, + 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, + 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +static unsigned char pcbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, + 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, + 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; + +static unsigned char cksum_ok[8]={ + 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char cfb_buf1[24],cfb_buf2[24],cfb_tmp[8]; +static unsigned char cfb_plain[24]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char cfb_cipher[24]= + { + 0xf3,0x1f,0xda,0x07,0x01,0x14, + 0x62,0xee,0x18,0x7f,0x43,0xd8, + 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, + 0x90,0xda,0x6e,0x5b,0x9a,0x87 + }; + +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char ofb_plain[24]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; +static unsigned char ofb_cipher[24]= + { + 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, + 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, + 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 + }; + +char *malloc(); +char *pt(); + +main() + { + int i,j; + des_cblock in,out,outin; + des_key_schedule ks; + unsigned char cbc_in[40],cbc_out[40]; + unsigned long cs; + unsigned char qret[4][4]; + unsigned long lqret[4]; + char *str; + + printf("Doing ecb\n"); + for (i=0; i<NUM_TESTS; i++) + { + if ((j=key_sched((C_Block *)(key_data[i]),ks)) != 0) + printf("Key error %2d:%d\n",i+1,j); + bcopy(plain_data[i],in,8); + bzero(out,8); + bzero(outin,8); + des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT); + des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT); + + if (bcmp(out,cipher_data[i],8) != 0) + { + printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", + i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]), + pt(out)); + } + if (bcmp(in,outin,8) != 0) + { + printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", + i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); + } + } + + printf("Doing cbc\n"); + if ((j=key_sched((C_Block *)cbc_key,ks)) != 0) + printf("Key error %2d:%d\n",i+1,j); + bzero(cbc_out,40); + bzero(cbc_in,40); + des_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT); + if (bcmp(cbc_out,cbc_ok,32) != 0) + printf("cbc_encrypt encrypt error\n"); + des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT); + if (bcmp(cbc_in,cbc_data,32) != 0) + printf("cbc_encrypt decrypt error\n"); + + printf("Doing pcbc\n"); + if ((j=key_sched((C_Block *)cbc_key,ks)) != 0) + printf("Key error %2d:%d\n",i+1,j); + bzero(cbc_out,40); + bzero(cbc_in,40); + des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT); + if (bcmp(cbc_out,pcbc_ok,32) != 0) + printf("pcbc_encrypt encrypt error\n"); + des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT); + if (bcmp(cbc_in,cbc_data,32) != 0) + printf("pcbc_encrypt decrypt error\n"); + + printf("Doing cfb\n"); + key_sched((C_Block *)cfb_key,ks); + bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv)); + des_cfb_encrypt(cfb_plain,cfb_buf1,8,(long)sizeof(cfb_plain),ks, + (C_Block *)cfb_tmp,DES_ENCRYPT); + if (bcmp(cfb_cipher,cfb_buf1,sizeof(cfb_buf1)) != 0) + printf("cfb_encrypt encrypt error\n"); + bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1,cfb_buf2,8,(long)sizeof(cfb_buf1),ks, + (C_Block *)cfb_tmp,DES_DECRYPT); + if (bcmp(cfb_plain,cfb_buf2,sizeof(cfb_buf2)) != 0) + printf("cfb_encrypt decrypt error\n"); + + bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv)); + for (i=0; i<sizeof(cfb_plain); i++) + des_cfb_encrypt(&(cfb_plain[i]),&(cfb_buf1[i]), + 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT); + if (bcmp(cfb_cipher,cfb_buf1,sizeof(cfb_buf1)) != 0) + printf("cfb_encrypt small encrypt error\n"); + + bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv)); + for (i=0; i<sizeof(cfb_plain); i++) + des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]), + 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT); + if (bcmp(cfb_plain,cfb_buf2,sizeof(cfb_buf2)) != 0) + printf("cfb_encrypt small decrypt error\n"); + + printf("Doing ofb\n"); + key_sched((C_Block *)ofb_key,ks); + bcopy(ofb_iv,ofb_tmp,sizeof(ofb_iv)); + des_ofb_encrypt(ofb_plain,ofb_buf1,64,(long)sizeof(cfb_plain)/8,ks, + (C_Block *)ofb_tmp); + if (bcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) + printf("ofb_encrypt encrypt error\n"); + bcopy(ofb_iv,ofb_tmp,sizeof(ofb_iv)); + des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks, + (C_Block *)ofb_tmp); + if (bcmp(ofb_plain,ofb_buf2,sizeof(ofb_buf2)) != 0) + printf("ofb_encrypt decrypt error\n"); + + printf("Doing cbc_cksum\n"); + des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cbc_out, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv); + if (bcmp(cbc_out,cksum_ok,8) != 0) + printf("cbc_cksum error\n"); + + printf("Doing quad_cksum\n"); + cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret, + (long)strlen(cbc_data),2,(C_Block *)cbc_iv); + for (i=0; i<4; i++) + { + lqret[i]=0; + bcopy(&(qret[i][0]),&(lqret[i]),4); + } + { /* Big-endian fix */ + static unsigned long l=1; + static unsigned char *c=(unsigned char *)&l; + unsigned long ll; + + if (!c[0]) + { + ll=lqret[0]^lqret[3]; + lqret[0]^=ll; + lqret[3]^=ll; + ll=lqret[1]^lqret[2]; + lqret[1]^=ll; + lqret[2]^=ll; + } + } + if (cs != 0x70d7a63a) + printf("quad_cksum error, ret %08x should be 70d7a63a\n",cs); + if (lqret[0] != 0x327eba8d) + printf("quad_cksum error, out[0] %08x is not %08x\n", + lqret[0],0x327eba8d); + if (lqret[1] != 0x201a49cc) + printf("quad_cksum error, out[1] %08x is not %08x\n", + lqret[1],0x201a49cc); + if (lqret[2] != 0x70d7a63a) + printf("quad_cksum error, out[2] %08x is not %08x\n", + lqret[2],0x70d7a63a); + if (lqret[3] != 0x501c2c26) + printf("quad_cksum error, out[3] %08x is not %08x\n", + lqret[3],0x501c2c26); + + printf("input word alignment test"); + for (i=0; i<4; i++) + { + printf(" %d",i); + des_cbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in, + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv, + DES_ENCRYPT); + } + printf("\noutput word alignment test"); + for (i=0; i<4; i++) + { + printf(" %d",i); + des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]), + (long)strlen(cbc_data),ks,(C_Block *)cbc_iv, + DES_ENCRYPT); + } + printf("\n"); + printf("fast crypt test "); + str=crypt("testing","ef"); + if (strcmp("efGnQx2725bI2",str) != 0) + printf("fast crypt error, %x should be efGnQx2725bI2\n",str); + str=crypt("bca76;23","yA"); + if (strcmp("yA1Rp/1hZXIJk",str) != 0) + printf("fast crypt error, %x should be yA1Rp/1hZXIJk\n",str); + printf("\n"); + exit(0); + } + +char *pt(p) +unsigned char *p; + { + char *ret; + int i; + static char *f="0123456789ABCDEF"; + + ret=(char *)malloc(17); + for (i=0; i<8; i++) + { + ret[i*2]=f[(p[i]>>4)&0xf]; + ret[i*2+1]=f[p[i]&0xf]; + } + ret[16]='\0'; + return(ret); + } + diff --git a/eBones/ext_srvtab/Makefile b/eBones/ext_srvtab/Makefile new file mode 100644 index 0000000..f30bbbb --- /dev/null +++ b/eBones/ext_srvtab/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:22:34 g89r4222 Exp $ + +PROG= ext_srvtab +CFLAGS+=-DKERBEROS -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD+= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/ext_srvtab/ext_srvtab.8 b/eBones/ext_srvtab/ext_srvtab.8 new file mode 100644 index 0000000..af980a9 --- /dev/null +++ b/eBones/ext_srvtab/ext_srvtab.8 @@ -0,0 +1,63 @@ +.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $ +.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ext_srvtab \- extract service key files from Kerberos key distribution center database +.SH SYNOPSIS +ext_srvtab [ +.B \-n +] [ +.B \-r realm +] [ +.B hostname ... +] +.SH DESCRIPTION +.I ext_srvtab +extracts service key files from the Kerberos key distribution center +(KDC) database. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +For each +.I hostname +specified on the command line, +.I ext_srvtab +creates the service key file +.IR hostname -new-srvtab, +containing all the entries in the database with an instance field of +.I hostname. +This new file contains all the keys registered for Kerberos-mediated +service providing programs which use the +.IR krb_get_phost (3) +principal and instance conventions to run on the host +.IR hostname . +If the +.B \-r +option is specified, the realm fields in the extracted file will +match the given realm rather than the local realm. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +.IR hostname -new-srvtab +Service key file generated for +.I hostname +.TP +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. +.SH SEE ALSO +read_service_key(3), krb_get_phost(3) diff --git a/eBones/ext_srvtab/ext_srvtab.c b/eBones/ext_srvtab/ext_srvtab.c new file mode 100644 index 0000000..3a5dcec --- /dev/null +++ b/eBones/ext_srvtab/ext_srvtab.c @@ -0,0 +1,164 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $ + * $Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <signal.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +#define TRUE 1 +#define FALSE 0 + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +char progname[] = "ext_srvtab"; +char realm[REALM_SZ]; + +main(argc, argv) + int argc; + char *argv[]; +{ + FILE *fout; + char fname[1024]; + int fopen_errs = 0; + int arg; + Principal princs[40]; + int more; + int prompt = TRUE; + register int n, i; + + bzero(realm, sizeof(realm)); + + /* Parse commandline arguments */ + if (argc < 2) + usage(); + else { + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-n") == 0) + prompt = FALSE; + else if (strcmp(argv[i], "-r") == 0) { + if (++i >= argc) + usage(); + else { + strcpy(realm, argv[i]); + /* + * This is to humor the broken way commandline + * argument parsing is done. Later, this + * program ignores everything that starts with -. + */ + argv[i][0] = '-'; + } + } + else if (argv[i][0] == '-') + usage(); + else + if (!k_isinst(argv[i])) { + fprintf(stderr, "%s: bad instance name: %s\n", + progname, argv[i]); + usage(); + } + } + } + + if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + fflush (stderr); + exit(1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + exit(1); + } + + /* For each arg, search for instances of arg, and produce */ + /* srvtab file */ + if (!realm[0]) + if (krb_get_lrealm(realm, 1) != KSUCCESS) { + fprintf(stderr, "%s: couldn't get local realm\n", progname); + exit(1); + } + (void) umask(077); + + for (arg = 1; arg < argc; arg++) { + if (argv[arg][0] == '-') + continue; + sprintf(fname, "%s-new-srvtab", argv[arg]); + if ((fout = fopen(fname, "w")) == NULL) { + fprintf(stderr, "Couldn't create file '%s'.\n", fname); + fopen_errs++; + continue; + } + printf("Generating '%s'....\n", fname); + n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more); + if (more) + fprintf(stderr, "More than 40 found...\n"); + for (i = 0; i < n; i++) { + FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout); + FWrite(princs[i].instance, strlen(princs[i].instance) + 1, + 1, fout); + FWrite(realm, strlen(realm) + 1, 1, fout); + FWrite(&princs[i].key_version, + sizeof(princs[i].key_version), 1, fout); + bcopy(&princs[i].key_low, session_key, sizeof(long)); + bcopy(&princs[i].key_high, session_key + sizeof(long), + sizeof(long)); + kdb_encrypt_key (session_key, session_key, + master_key, master_key_schedule, DES_DECRYPT); + FWrite(session_key, sizeof session_key, 1, fout); + } + fclose(fout); + } + + StampOutSecrets(); + + exit(fopen_errs); /* 0 errors if successful */ + +} + +Die() +{ + StampOutSecrets(); + exit(1); +} + +FWrite(p, size, n, f) + char *p; + int size; + int n; + FILE *f; +{ + if (fwrite(p, size, n, f) != n) { + printf("Error writing output file. Terminating.\n"); + Die(); + } +} + +StampOutSecrets() +{ + bzero(master_key, sizeof master_key); + bzero(session_key, sizeof session_key); + bzero(master_key_schedule, sizeof master_key_schedule); +} + +usage() +{ + fprintf(stderr, + "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname); + exit(1); +} diff --git a/eBones/include/ChangeLog b/eBones/include/ChangeLog new file mode 100644 index 0000000..254b8dd --- /dev/null +++ b/eBones/include/ChangeLog @@ -0,0 +1,25 @@ +# $Id: ChangeLog,v 1.2 1994/07/19 19:22:41 g89r4222 Exp $ + +Mon Mar 21 15:48:59 MET 1994 Piero Serini + * 1st port to FreeBSD + +Tue Nov 29 11:52:51 1988 John T Kohl (jtkohl at lycus) + + * osconf.h: add #ifdef's for SUN processors (bsd/m68k) + + * conf-bsdm68k.h: new file for BSD unix/M68000-based unix boxes + +Mon Sep 12 14:33:58 1988 Bill Sommerfeld (wesommer at ra) + + * des_conf.h: deleted file (superceded by conf.h) + + * des.h: remove #include of des_conf.h + + * des.h: remove internal details (sbox structure, bit_{32,64}) from +interface. + Rename data types. + Add #defines, turned off if NCOMPAT, for compatibility with old + versions. + + + diff --git a/eBones/include/Makefile b/eBones/include/Makefile new file mode 100644 index 0000000..8b46c65 --- /dev/null +++ b/eBones/include/Makefile @@ -0,0 +1,17 @@ +# from: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.3 1994/09/09 21:43:35 g89r4222 Exp $ + +FILES= des.h kadm.h kparse.h krb.h krb_db.h + +# mit-copyright.h kadm_err.h krb_err.h + +NOOBJ= noobj +NOMAN= noman + +all include clean cleandir depend lint tags: + +beforeinstall: + install -c -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${FILES} ${DESTDIR}/usr/include/kerberosIV + +.include <bsd.prog.mk> diff --git a/eBones/include/addr_comp.h b/eBones/include/addr_comp.h new file mode 100644 index 0000000..8d001d3 --- /dev/null +++ b/eBones/include/addr_comp.h @@ -0,0 +1,35 @@ +/* + * Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for address comparison macros. + * + * from: addr_comp.h,v 4.0 89/01/23 09:57:44 jtkohl Exp $ + * $Id: addr_comp.h,v 1.2 1994/07/19 19:22:44 g89r4222 Exp $ + */ + +#ifndef ADDR_COMP_DEFS +#define ADDR_COMP_DEFS + +/* +** Look boys and girls, a big kludge +** We need to compare the two internet addresses in network byte order, not +** local byte order. This is a *really really slow way of doing that* +** But..... +** .....it works +** so we run with it +** +** long_less_than gets fed two (u_char *)'s.... +*/ + +#define u_char_comp(x,y) \ + (((x)>(y))?(1):(((x)==(y))?(0):(-1))) + +#define long_less_than(x,y) \ + (u_char_comp((x)[0],(y)[0])?u_char_comp((x)[0],(y)[0]): \ + (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \ + (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \ + (u_char_comp((x)[3],(y)[3]))))) + +#endif /* ADDR_COMP_DEFS */ diff --git a/eBones/include/admin_server.h b/eBones/include/admin_server.h new file mode 100644 index 0000000..db29c15 --- /dev/null +++ b/eBones/include/admin_server.h @@ -0,0 +1,42 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for the Kerberos administration server. + * + * from: admin_server.h,v 4.7 89/01/11 11:59:42 steiner Exp $ + * $Id: admin_server.h,v 1.2 1994/07/19 19:22:47 g89r4222 Exp $ + */ + +#ifndef ADMIN_SERVER_DEFS +#define ADMIN_SERVER_DEFS + +#define PW_SRV_VERSION 2 /* version number */ + +#define INSTALL_NEW_PW (1<<0) /* + * ver, cmd, name, password, + * old_pass, crypt_pass, uid + */ + +#define ADMIN_NEW_PW (2<<1) /* + * ver, cmd, name, passwd, + * old_pass + * (grot), crypt_pass (grot) + */ + +#define ADMIN_SET_KDC_PASSWORD (3<<1) /* ditto */ +#define ADMIN_ADD_NEW_KEY (4<<1) /* ditto */ +#define ADMIN_ADD_NEW_KEY_ATTR (5<<1) /* + * ver, cmd, name, passwd, + * inst, attr (grot) + */ +#define INSTALL_REPLY (1<<1) /* ver, cmd, name, password */ +#define RETRY_LIMIT 1 +#define TIME_OUT 30 +#define USER_TIMEOUT 90 +#define MAX_KPW_LEN 40 + +#define KADM "changepw" /* service name */ + +#endif /* ADMIN_SERVER_DEFS */ diff --git a/eBones/include/conf-bsd386i.h b/eBones/include/conf-bsd386i.h new file mode 100644 index 0000000..0f63212 --- /dev/null +++ b/eBones/include/conf-bsd386i.h @@ -0,0 +1,16 @@ +/* + * Copyright 1989 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: Sun 386i using SunOS (~BSD) + * + * from: conf-bsd386i.h,v 4.0 89/12/19 13:26:55 jtkohl Exp $ + * $Id: conf-bsd386i.h,v 1.2 1994/07/19 19:22:48 g89r4222 Exp $ + */ + +#define BITS32 +#define BIG +#define LSBFIRST +#define BSDUNIX + diff --git a/eBones/include/conf-bsdapollo.h b/eBones/include/conf-bsdapollo.h new file mode 100644 index 0000000..532d2aa --- /dev/null +++ b/eBones/include/conf-bsdapollo.h @@ -0,0 +1,21 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: conf-bsdapollo.h,v 4.1 89/01/24 14:26:22 jtkohl Exp $ + * $Id: conf-bsdapollo.h,v 1.2 1994/07/19 19:22:50 g89r4222 Exp $ + */ + +#define BSDUNIX +#define BITS32 +#define BIG +#define MSBFIRST +#define DES_SHIFT_SHIFT +/* + * As of SR10, the C compiler claims to be __STDC__, but doesn't support + * const. Sigh. + */ +#define const + + diff --git a/eBones/include/conf-bsdibm032.h b/eBones/include/conf-bsdibm032.h new file mode 100644 index 0000000..285fbf6 --- /dev/null +++ b/eBones/include/conf-bsdibm032.h @@ -0,0 +1,18 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: IBM 032 (RT/PC) + * + * from: conf-bsdibm032.h,v 4.0 89/01/23 09:58:01 jtkohl Exp $ + * $Id: conf-bsdibm032.h,v 1.2 1994/07/19 19:22:51 g89r4222 Exp $ + */ + +#define BSDUNIX +#define IBMWS +#define IBMWSASM +#define BITS32 +#define BIG +#define MSBFIRST +#define MUSTALIGN diff --git a/eBones/include/conf-bsdm68k.h b/eBones/include/conf-bsdm68k.h new file mode 100644 index 0000000..fcc2c57 --- /dev/null +++ b/eBones/include/conf-bsdm68k.h @@ -0,0 +1,16 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: 68000 with BSD Unix, e.g. SUN + * + * from: conf-bsdm68k.h,v 4.0 88/11/29 11:46:58 jtkohl Exp $ + * $Id: conf-bsdm68k.h,v 1.2 1994/07/19 19:22:53 g89r4222 Exp $ + */ + +#define BITS32 +#define BIG +#define MSBFIRST +#define BSDUNIX + diff --git a/eBones/include/conf-bsdsparc.h b/eBones/include/conf-bsdsparc.h new file mode 100644 index 0000000..abfa2ae --- /dev/null +++ b/eBones/include/conf-bsdsparc.h @@ -0,0 +1,17 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: SPARC with BSD Unix, e.g. SUN-4 + * + * from: conf-bsdsparc.h,v 4.0 89/06/02 13:04:06 jtkohl Exp $ + * $Id: conf-bsdsparc.h,v 1.2 1994/07/19 19:22:54 g89r4222 Exp $ + */ + +#define BITS32 +#define BIG +#define MSBFIRST +#define BSDUNIX +#define MUSTALIGN + diff --git a/eBones/include/conf-bsdtahoe.h b/eBones/include/conf-bsdtahoe.h new file mode 100644 index 0000000..8095dc5 --- /dev/null +++ b/eBones/include/conf-bsdtahoe.h @@ -0,0 +1,16 @@ +/* + * Copyright 1989 by the Regents of the University of California + * + * Machine Description : TAHOE. + * + * from: conf-bsdtahoe.h,v 4.0 89/08/30 11:06:53 jtkohl Exp $ + * $Id: conf-bsdtahoe.h,v 1.2 1994/07/19 19:22:56 g89r4222 Exp $ + */ + +#define TAHOE +#define BSDUNIX +#define BITS32 +#define BIG +#define MSBFIRST +#define MUSTALIGN +#define NOASM diff --git a/eBones/include/conf-bsdvax.h b/eBones/include/conf-bsdvax.h new file mode 100644 index 0000000..6b82102 --- /dev/null +++ b/eBones/include/conf-bsdvax.h @@ -0,0 +1,22 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: VAX + * + * from: conf-bsdvax.h,v 4.0 89/01/23 09:58:12 jtkohl Exp $ + * $Id: conf-bsdvax.h,v 1.2 1994/07/19 19:22:57 g89r4222 Exp $ + */ + +#define VAX +#define BITS32 +#define BIG +#define LSBFIRST +#define BSDUNIX + +#ifndef __STDC__ +#ifndef NOASM +#define VAXASM +#endif /* no assembly */ +#endif /* standard C */ diff --git a/eBones/include/conf-ibm370.h b/eBones/include/conf-ibm370.h new file mode 100644 index 0000000..e4bccfc --- /dev/null +++ b/eBones/include/conf-ibm370.h @@ -0,0 +1,15 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: IBM 370 + * + * from: conf-ibm370.h,v 4.0 89/01/23 09:58:19 jtkohl Exp $ + * $Id: conf-ibm370.h,v 1.2 1994/07/19 19:22:59 g89r4222 Exp $ + */ + +/* What else? */ +#define BIG +#define NONASCII +#define SHORTNAMES diff --git a/eBones/include/conf-pc.h b/eBones/include/conf-pc.h new file mode 100644 index 0000000..25218e3 --- /dev/null +++ b/eBones/include/conf-pc.h @@ -0,0 +1,16 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: IBM PC 8086 + * + * from: conf-pc.h,v 4.0 89/01/23 09:58:26 jtkohl Exp $ + * $Id: conf-pc.h,v 1.2 1994/07/19 19:23:00 g89r4222 Exp $ + * + */ + +#define IBMPC +#define BITS16 +#define CROSSMSDOS +#define LSBFIRST diff --git a/eBones/include/conf-pyr.h b/eBones/include/conf-pyr.h new file mode 100644 index 0000000..e88e528 --- /dev/null +++ b/eBones/include/conf-pyr.h @@ -0,0 +1,15 @@ +/* + * Copyright 1989 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: Pyramid + * + * from: conf-pyr.h,v 4.0 89/12/19 13:27:16 jtkohl Exp $ + * $Id: conf-pyr.h,v 1.2 1994/07/19 19:23:02 g89r4222 Exp $ + */ + +#define BITS32 +#define BIG +#define MSBFIRST +#define BSDUNIX diff --git a/eBones/include/conf-ultmips2.h b/eBones/include/conf-ultmips2.h new file mode 100644 index 0000000..7d202f5 --- /dev/null +++ b/eBones/include/conf-ultmips2.h @@ -0,0 +1,17 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Machine-type definitions: DECstation 3100 (MIPS R2000) + * + * from: conf-ultmips2.h,v 4.0 89/01/23 09:58:32 jtkohl Exp $ + * $Id: conf-ultmips2.h,v 1.2 1994/07/19 19:23:03 g89r4222 Exp $ + */ + +#define MIPS2 +#define BITS32 +#define BIG +#define LSBFIRST +#define BSDUNIX +#define MUSTALIGN diff --git a/eBones/include/conf.h b/eBones/include/conf.h new file mode 100644 index 0000000..30186c5 --- /dev/null +++ b/eBones/include/conf.h @@ -0,0 +1,73 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Configuration info for operating system, hardware description, + * language implementation, C library, etc. + * + * This file should be included in (almost) every file in the Kerberos + * sources, and probably should *not* be needed outside of those + * sources. (How do we deal with /usr/include/des.h and + * /usr/include/krb.h?) + * + * from: conf.h,v 4.0 89/01/23 09:58:40 jtkohl Exp $ + * $Id: conf.h,v 1.2 1994/07/19 19:23:05 g89r4222 Exp $ + */ + +#ifndef _CONF_H_ + +#include "osconf.h" + +#ifdef SHORTNAMES +#include "names.h" +#endif + +/* + * Language implementation-specific definitions + */ + +/* special cases */ +#ifdef __HIGHC__ +/* broken implementation of ANSI C */ +#undef __STDC__ +#endif + +#ifndef __STDC__ +#define const +#define volatile +#define signed +typedef char *pointer; /* pointer to generic data */ +#define PROTOTYPE(p) () +#else +typedef void *pointer; +#define PROTOTYPE(p) p +#endif + +/* Does your compiler understand "void"? */ +#ifdef notdef +#define void int +#endif + +/* + * A few checks to see that necessary definitions are included. + */ + +/* byte order */ + +#ifndef MSBFIRST +#ifndef LSBFIRST +Error: byte order not defined. +#endif +#endif + +/* machine size */ +#ifndef BITS16 +#ifndef BITS32 +Error: how big is this machine anyways? +#endif +#endif + +/* end of checks */ + +#endif /* _CONF_H_ */ diff --git a/eBones/include/des.h b/eBones/include/des.h new file mode 100644 index 0000000..9cc2056 --- /dev/null +++ b/eBones/include/des.h @@ -0,0 +1,44 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for the Data Encryption Standard library. + * + * from: des.h,v 4.11 89/01/17 16:24:57 rfrench Exp $ + * $Id: des.h,v 1.2 1994/07/19 19:23:06 g89r4222 Exp $ + */ + +/* only do the whole thing once */ +#ifndef DES_DEFS +#define DES_DEFS + +typedef unsigned char des_cblock[8]; /* crypto-block size */ +/* Key schedule */ +typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16]; + +#define DES_KEY_SZ (sizeof(des_cblock)) +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#ifndef NCOMPAT +#define C_Block des_cblock +#define Key_schedule des_key_schedule +#define ENCRYPT DES_ENCRYPT +#define DECRYPT DES_DECRYPT +#define KEY_SZ DES_KEY_SZ +#define string_to_key des_string_to_key +#define read_pw_string des_read_pw_string +#define random_key des_random_key +#define pcbc_encrypt des_pcbc_encrypt +#define key_sched des_key_sched +#define cbc_encrypt des_cbc_encrypt +#define cbc_cksum des_cbc_cksum +#define C_Block_print des_cblock_print +#define quad_cksum des_quad_cksum +typedef struct des_ks_struct bit_64; +#endif + +#define des_cblock_print(x) des_cblock_print_file(x, stdout) + +#endif DES_DEFS diff --git a/eBones/include/highc.h b/eBones/include/highc.h new file mode 100644 index 0000000..be50e3f --- /dev/null +++ b/eBones/include/highc.h @@ -0,0 +1,32 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Known breakage in the version of Metaware's High C compiler that + * we've got available.... + * + * from: highc.h,v 4.0 89/01/23 09:59:15 jtkohl Exp $ + * $Id: highc.h,v 1.2 1994/07/19 19:23:08 g89r4222 Exp $ + */ + +#define const +/*#define volatile*/ + +/* + * Some builtin functions we can take advantage of for inlining.... + */ + +#define abs _abs +/* the _max and _min builtins accept any number of arguments */ +#undef MAX +#define MAX(x,y) _max(x,y) +#undef MIN +#define MIN(x,y) _min(x,y) +/* + * I'm not sure if 65535 is a limit for this builtin, but it's + * reasonable for a string length. Or is it? + */ +/*#define strlen(s) _find_char(s,65535,0)*/ +#define bzero(ptr,len) _fill_char(ptr,len,'\0') +#define bcmp(b1,b2,len) _compare(b1,b2,len) diff --git a/eBones/include/kadm.h b/eBones/include/kadm.h new file mode 100644 index 0000000..a1cca81 --- /dev/null +++ b/eBones/include/kadm.h @@ -0,0 +1,138 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Definitions for Kerberos administration server & client + * + * from: kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp $ + * $Id: kadm.h,v 1.2 1994/07/19 19:23:09 g89r4222 Exp $ + */ + +#ifndef KADM_DEFS +#define KADM_DEFS + +/* + * kadm.h + * Header file for the fourth attempt at an admin server + * Doug Church, December 28, 1989, MIT Project Athena + */ + +/* for those broken Unixes without this defined... should be in sys/param.h */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#include <sys/types.h> +#include <netinet/in.h> +#include <krb.h> +#include <des.h> + +/* The global structures for the client and server */ +typedef struct { + struct sockaddr_in admin_addr; + struct sockaddr_in my_addr; + int my_addr_len; + int admin_fd; /* file descriptor for link to admin server */ + char sname[ANAME_SZ]; /* the service name */ + char sinst[INST_SZ]; /* the services instance */ + char krbrlm[REALM_SZ]; +} Kadm_Client; + +typedef struct { /* status of the server, i.e the parameters */ + int inter; /* Space for command line flags */ + char *sysfile; /* filename of server */ +} admin_params; /* Well... it's the admin's parameters */ + +/* Largest password length to be supported */ +#define MAX_KPW_LEN 128 + +/* Largest packet the admin server will ever allow itself to return */ +#define KADM_RET_MAX 2048 + +/* That's right, versions are 8 byte strings */ +#define KADM_VERSTR "KADM0.0A" +#define KADM_ULOSE "KYOULOSE" /* sent back when server can't + decrypt client's msg */ +#define KADM_VERSIZE strlen(KADM_VERSTR) + +/* the lookups for the server instances */ +#define PWSERV_NAME "changepw" +#define KADM_SNAME "kerberos_master" +#define KADM_SINST "kerberos" + +/* Attributes fields constants and macros */ +#define ALLOC 2 +#define RESERVED 3 +#define DEALLOC 4 +#define DEACTIVATED 5 +#define ACTIVE 6 + +/* Kadm_vals structure for passing db fields into the server routines */ +#define FLDSZ 4 + +typedef struct { + u_char fields[FLDSZ]; /* The active fields in this struct */ + char name[ANAME_SZ]; + char instance[INST_SZ]; + unsigned long key_low; + unsigned long key_high; + unsigned long exp_date; + unsigned short attributes; + unsigned char max_life; +} Kadm_vals; /* The basic values structure in Kadm */ + +/* Kadm_vals structure for passing db fields into the server routines */ +#define FLDSZ 4 + +/* Need to define fields types here */ +#define KADM_NAME 31 +#define KADM_INST 30 +#define KADM_EXPDATE 29 +#define KADM_ATTR 28 +#define KADM_MAXLIFE 27 +#define KADM_DESKEY 26 + +/* To set a field entry f in a fields structure d */ +#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8))) + +/* To set a field entry f in a fields structure d */ +#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8)))) + +/* Is field f in fields structure d */ +#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8))) + +/* Various return codes */ +#define KADM_SUCCESS 0 + +#define WILDCARD_STR "*" + +enum acl_types { +ADDACL, +GETACL, +MODACL +}; + +/* Various opcodes for the admin server's functions */ +#define CHANGE_PW 2 +#define ADD_ENT 3 +#define MOD_ENT 4 +#define GET_ENT 5 + +extern long kdb_get_master_key(); /* XXX should be in krb_db.h */ +extern long kdb_verify_master_key(); /* XXX ditto */ + +extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */ +extern void krb_set_tkt_string(); /* XXX ditto */ + +extern unsigned long quad_cksum(); /* XXX should be in des.h */ + +/* XXX This doesn't belong here!!! */ +char *malloc(), *realloc(); +#ifdef POSIX +typedef void sigtype; +#else +typedef int sigtype; +#endif + +#endif KADM_DEFS diff --git a/eBones/include/kdc.h b/eBones/include/kdc.h new file mode 100644 index 0000000..518e5e9 --- /dev/null +++ b/eBones/include/kdc.h @@ -0,0 +1,36 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for the Kerberos Key Distribution Center. + * + * from: kdc.h,v 4.1 89/01/24 17:54:04 jon Exp $ + * $Id: kdc.h,v 1.2 1994/07/19 19:23:11 g89r4222 Exp $ + */ + +#ifndef KDC_DEFS +#define KDC_DEFS + +#define S_AD_SZ sizeof(struct sockaddr_in) + +#define max(a,b) (a>b ? a : b) +#define min(a,b) (a<b ? a : b) + +#define TRUE 1 +#define FALSE 0 + +#define MKEYFILE "/etc/kerberosIV/master_key" +#define K_LOGFIL "/var/log/kpropd.log" +#define KS_LOGFIL "/var/log/kerberos_slave.log" +#define KRB_ACL "/etc/kerberosIV/kerberos.acl" +#define KRB_PROG "./kerberos" + +#define ONE_MINUTE 60 +#define FIVE_MINUTES (5 * ONE_MINUTE) +#define ONE_HOUR (60 * ONE_MINUTE) +#define ONE_DAY (24 * ONE_HOUR) +#define THREE_DAYS (3 * ONE_DAY) + +#endif /* KDC_DEFS */ + diff --git a/eBones/include/klog.h b/eBones/include/klog.h new file mode 100644 index 0000000..e8c5070 --- /dev/null +++ b/eBones/include/klog.h @@ -0,0 +1,39 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This file defines the types of log messages logged by klog. Each + * type of message may be selectively turned on or off. + * + * from: klog.h,v 4.7 89/01/24 17:55:07 jon Exp $ + * $Id: klog.h,v 1.2 1994/07/19 19:23:12 g89r4222 Exp $ + */ + +#ifndef KLOG_DEFS +#define KLOG_DEFS + +#define KRBLOG "/var/log/kerberos.log" /* master server */ +#define KRBSLAVELOG "/var/log/kerberos_slave.log" /* master server */ +#define NLOGTYPE 100 /* Maximum number of log msg types */ + +#define L_NET_ERR 1 /* Error in network code */ +#define L_NET_INFO 2 /* Info on network activity */ +#define L_KRB_PERR 3 /* Kerberos protocol errors */ +#define L_KRB_PINFO 4 /* Kerberos protocol info */ +#define L_INI_REQ 5 /* Request for initial ticket */ +#define L_NTGT_INTK 6 /* Initial request not for TGT */ +#define L_DEATH_REQ 7 /* Request for server death */ +#define L_TKT_REQ 8 /* All ticket requests using a tgt */ +#define L_ERR_SEXP 9 /* Service expired */ +#define L_ERR_MKV 10 /* Master key version incorrect */ +#define L_ERR_NKY 11 /* User's key is null */ +#define L_ERR_NUN 12 /* Principal not unique */ +#define L_ERR_UNK 13 /* Principal Unknown */ +#define L_ALL_REQ 14 /* All requests */ +#define L_APPL_REQ 15 /* Application requests (using tgt) */ +#define L_KRB_PWARN 16 /* Protocol warning messages */ + +char *klog(); + +#endif /* KLOG_DEFS */ diff --git a/eBones/include/kparse.h b/eBones/include/kparse.h new file mode 100644 index 0000000..9bdc07c --- /dev/null +++ b/eBones/include/kparse.h @@ -0,0 +1,87 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for kparse routines. + * + * from: kparse.h,v 4.5 89/01/11 12:05:53 steiner Exp $ + * $Id: kparse.h,v 1.2 1994/07/19 19:23:14 g89r4222 Exp $ + */ + +#ifndef KPARSE_DEFS +#define KPARSE_DEFS + +/* + * values returned by fGetParameterSet() + */ + +#define PS_BAD_KEYWORD -2 /* unknown or duplicate keyword */ +#define PS_SYNTAX -1 /* syntax error */ +#define PS_OKAY 0 /* got a complete parameter set */ +#define PS_EOF 1 /* nothing more in the file */ + +/* + * values returned by fGetKeywordValue() + */ + +#define KV_SYNTAX -2 /* syntax error */ +#define KV_EOF -1 /* nothing more in the file */ +#define KV_OKAY 0 /* got a keyword/value pair */ +#define KV_EOL 1 /* nothing more on this line */ + +/* + * values returned by fGetToken() + */ + +#define GTOK_BAD_QSTRING -1 /* newline found in quoted string */ +#define GTOK_EOF 0 /* end of file encountered */ +#define GTOK_QSTRING 1 /* quoted string */ +#define GTOK_STRING 2 /* unquoted string */ +#define GTOK_NUMBER 3 /* one or more digits */ +#define GTOK_PUNK 4 /* punks are punctuation, newline, + * etc. */ +#define GTOK_WHITE 5 /* one or more whitespace chars */ + +/* + * extended character classification macros + */ + +#define ISOCTAL(CH) ( (CH>='0') && (CH<='7') ) +#define ISQUOTE(CH) ( (CH=='\"') || (CH=='\'') || (CH=='`') ) +#define ISWHITESPACE(C) ( (C==' ') || (C=='\t') ) +#define ISLINEFEED(C) ( (C=='\n') || (C=='\r') || (C=='\f') ) + +/* + * tokens consist of any printable charcacter except comma, equal, or + * whitespace + */ + +#define ISTOKENCHAR(C) ((C>040) && (C<0177) && (C != ',') && (C != '=')) + +/* + * the parameter table defines the keywords that will be recognized by + * fGetParameterSet, and their default values if not specified. + */ + +typedef struct { + char *keyword; + char *defvalue; + char *value; +} parmtable; + +#define PARMCOUNT(P) (sizeof(P)/sizeof(P[0])) + +extern int LineNbr; /* current line # in parameter file */ + +extern char ErrorMsg[]; /* + * meaningful only when KV_SYNTAX, + * PS_SYNTAX, or PS_BAD_KEYWORD is + * returned by fGetKeywordValue or + * fGetParameterSet + */ + +extern char *strsave(); /* defined in this module */ +extern char *strutol(); /* defined in this module */ + +#endif /* KPARSE_DEFS */ diff --git a/eBones/include/krb.h b/eBones/include/krb.h new file mode 100644 index 0000000..15e831b --- /dev/null +++ b/eBones/include/krb.h @@ -0,0 +1,376 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for the Kerberos library. + * + * from: krb.h,v 4.26 89/08/08 17:55:25 jtkohl Exp $ + * $Id: krb.h,v 1.4 1994/09/24 14:15:41 g89r4222 Exp $ + */ + +/* Only one time, please */ +#ifndef KRB_DEFS +#define KRB_DEFS + +/* Need some defs from des.h */ +#include <kerberosIV/des.h> + +/* Text describing error codes */ +#define MAX_KRB_ERRORS 256 +extern char *krb_err_txt[MAX_KRB_ERRORS]; + +/* These are not defined for at least SunOS 3.3 and Ultrix 2.2 */ +#if defined(ULTRIX022) || (defined(SunOS) && SunOS < 40) +#define FD_ZERO(p) ((p)->fds_bits[0] = 0) +#define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n))) +#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << (n))) +#endif /* ULTRIX022 || SunOS */ + +/* General definitions */ +#define KSUCCESS 0 +#define KFAILURE 255 + +#ifdef NO_UIDGID_T +typedef unsigned short uid_t; +typedef unsigned short gid_t; +#endif /* NO_UIDGID_T */ + +/* + * Kerberos specific definitions + * + * KRBLOG is the log file for the kerberos master server. KRB_CONF is + * the configuration file where different host machines running master + * and slave servers can be found. KRB_MASTER is the name of the + * machine with the master database. The admin_server runs on this + * machine, and all changes to the db (as opposed to read-only + * requests, which can go to slaves) must go to it. KRB_HOST is the + * default machine * when looking for a kerberos slave server. Other + * possibilities are * in the KRB_CONF file. KRB_REALM is the name of + * the realm. + */ + +#ifdef notdef +this is server - only, does not belong here; +#define KRBLOG "/etc/kerberosIV/kerberos.log" +are these used anyplace '?'; +#define VX_KRB_HSTFILE "/etc/krbhst" +#define PC_KRB_HSTFILE "\\kerberos\\krbhst" +#endif + +#define KRB_CONF "/etc/kerberosIV/krb.conf" +#define KRB_RLM_TRANS "/etc/kerberosIV/krb.realms" +#define KRB_MASTER "kerberos" +#define KRB_HOST KRB_MASTER +#define KRB_REALM "ATHENA.MIT.EDU" + +/* The maximum sizes for aname, realm, sname, and instance +1 */ +#define ANAME_SZ 40 +#define REALM_SZ 40 +#define SNAME_SZ 40 +#define INST_SZ 40 +/* include space for '.' and '@' */ +#define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) +#define KKEY_SZ 100 +#define VERSION_SZ 1 +#define MSG_TYPE_SZ 1 +#define DATE_SZ 26 /* RTI date output */ + +#define MAX_HSTNM 100 + +#ifndef DEFAULT_TKT_LIFE /* allow compile-time override */ +#define DEFAULT_TKT_LIFE 96 /* default lifetime for krb_mk_req + & co., 8 hrs */ +#endif + +/* Definition of text structure used to pass text around */ +#define MAX_KTXT_LEN 1250 + +struct ktext { + int length; /* Length of the text */ + unsigned char dat[MAX_KTXT_LEN]; /* The data itself */ + unsigned long mbz; /* zero to catch runaway strings */ +}; + +typedef struct ktext *KTEXT; +typedef struct ktext KTEXT_ST; + + +/* Definitions for send_to_kdc */ +#define CLIENT_KRB_TIMEOUT 4 /* time between retries */ +#define CLIENT_KRB_RETRY 5 /* retry this many times */ +#define CLIENT_KRB_BUFLEN 512 /* max unfragmented packet */ + +/* Definitions for ticket file utilities */ +#define R_TKT_FIL 0 +#define W_TKT_FIL 1 + +/* Definitions for cl_get_tgt */ +#ifdef PC +#define CL_GTGT_INIT_FILE "\\kerberos\\k_in_tkts" +#else +#define CL_GTGT_INIT_FILE "/etc/k_in_tkts" +#endif PC + +/* Parameters for rd_ap_req */ +/* Maximum alloable clock skew in seconds */ +#define CLOCK_SKEW 5*60 +/* Filename for readservkey */ +#define KEYFILE "/etc/kerberosIV/srvtab" + +/* Structure definition for rd_ap_req */ + +struct auth_dat { + unsigned char k_flags; /* Flags from ticket */ + char pname[ANAME_SZ]; /* Principal's name */ + char pinst[INST_SZ]; /* His Instance */ + char prealm[REALM_SZ]; /* His Realm */ + unsigned long checksum; /* Data checksum (opt) */ + C_Block session; /* Session Key */ + int life; /* Life of ticket */ + unsigned long time_sec; /* Time ticket issued */ + unsigned long address; /* Address in ticket */ + KTEXT_ST reply; /* Auth reply (opt) */ +}; + +typedef struct auth_dat AUTH_DAT; + +/* Structure definition for credentials returned by get_cred */ + +struct credentials { + char service[ANAME_SZ]; /* Service name */ + char instance[INST_SZ]; /* Instance */ + char realm[REALM_SZ]; /* Auth domain */ + C_Block session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT_ST ticket_st; /* The ticket itself */ + long issue_date; /* The issue time */ + char pname[ANAME_SZ]; /* Principal's name */ + char pinst[INST_SZ]; /* Principal's instance */ +}; + +typedef struct credentials CREDENTIALS; + +/* Structure definition for rd_private_msg and rd_safe_msg */ + +struct msg_dat { + unsigned char *app_data; /* pointer to appl data */ + unsigned long app_length; /* length of appl data */ + unsigned long hash; /* hash to lookup replay */ + int swap; /* swap bytes? */ + long time_sec; /* msg timestamp seconds */ + unsigned char time_5ms; /* msg timestamp 5ms units */ +}; + +typedef struct msg_dat MSG_DAT; + + +/* Location of ticket file for save_cred and get_cred */ +#ifdef PC +#define TKT_FILE "\\kerberos\\ticket.ses" +#else +#define TKT_FILE tkt_string() +#define TKT_ROOT "/tmp/tkt" +#endif PC + +/* Error codes returned from the KDC */ +#define KDC_OK 0 /* Request OK */ +#define KDC_NAME_EXP 1 /* Principal expired */ +#define KDC_SERVICE_EXP 2 /* Service expired */ +#define KDC_AUTH_EXP 3 /* Auth expired */ +#define KDC_PKT_VER 4 /* Protocol version unknown */ +#define KDC_P_MKEY_VER 5 /* Wrong master key version */ +#define KDC_S_MKEY_VER 6 /* Wrong master key version */ +#define KDC_BYTE_ORDER 7 /* Byte order unknown */ +#define KDC_PR_UNKNOWN 8 /* Principal unknown */ +#define KDC_PR_N_UNIQUE 9 /* Principal not unique */ +#define KDC_NULL_KEY 10 /* Principal has null key */ +#define KDC_GEN_ERR 20 /* Generic error from KDC */ + + +/* Values returned by get_credentials */ +#define GC_OK 0 /* Retrieve OK */ +#define RET_OK 0 /* Retrieve OK */ +#define GC_TKFIL 21 /* Can't read ticket file */ +#define RET_TKFIL 21 /* Can't read ticket file */ +#define GC_NOTKT 22 /* Can't find ticket or TGT */ +#define RET_NOTKT 22 /* Can't find ticket or TGT */ + + +/* Values returned by mk_ap_req */ +#define MK_AP_OK 0 /* Success */ +#define MK_AP_TGTEXP 26 /* TGT Expired */ + +/* Values returned by rd_ap_req */ +#define RD_AP_OK 0 /* Request authentic */ +#define RD_AP_UNDEC 31 /* Can't decode authenticator */ +#define RD_AP_EXP 32 /* Ticket expired */ +#define RD_AP_NYV 33 /* Ticket not yet valid */ +#define RD_AP_REPEAT 34 /* Repeated request */ +#define RD_AP_NOT_US 35 /* The ticket isn't for us */ +#define RD_AP_INCON 36 /* Request is inconsistent */ +#define RD_AP_TIME 37 /* delta_t too big */ +#define RD_AP_BADD 38 /* Incorrect net address */ +#define RD_AP_VERSION 39 /* protocol version mismatch */ +#define RD_AP_MSG_TYPE 40 /* invalid msg type */ +#define RD_AP_MODIFIED 41 /* message stream modified */ +#define RD_AP_ORDER 42 /* message out of order */ +#define RD_AP_UNAUTHOR 43 /* unauthorized request */ + +/* Values returned by get_pw_tkt */ +#define GT_PW_OK 0 /* Got password changing tkt */ +#define GT_PW_NULL 51 /* Current PW is null */ +#define GT_PW_BADPW 52 /* Incorrect current password */ +#define GT_PW_PROT 53 /* Protocol Error */ +#define GT_PW_KDCERR 54 /* Error returned by KDC */ +#define GT_PW_NULLTKT 55 /* Null tkt returned by KDC */ + + +/* Values returned by send_to_kdc */ +#define SKDC_OK 0 /* Response received */ +#define SKDC_RETRY 56 /* Retry count exceeded */ +#define SKDC_CANT 57 /* Can't send request */ + +/* + * Values returned by get_intkt + * (can also return SKDC_* and KDC errors) + */ + +#define INTK_OK 0 /* Ticket obtained */ +#define INTK_W_NOTALL 61 /* Not ALL tickets returned */ +#define INTK_BADPW 62 /* Incorrect password */ +#define INTK_PROT 63 /* Protocol Error */ +#define INTK_ERR 70 /* Other error */ + +/* Values returned by get_adtkt */ +#define AD_OK 0 /* Ticket Obtained */ +#define AD_NOTGT 71 /* Don't have tgt */ + +/* Error codes returned by ticket file utilities */ +#define NO_TKT_FIL 76 /* No ticket file found */ +#define TKT_FIL_ACC 77 /* Couldn't access tkt file */ +#define TKT_FIL_LCK 78 /* Couldn't lock ticket file */ +#define TKT_FIL_FMT 79 /* Bad ticket file format */ +#define TKT_FIL_INI 80 /* tf_init not called first */ + +/* Error code returned by kparse_name */ +#define KNAME_FMT 81 /* Bad Kerberos name format */ + +/* Error code returned by krb_mk_safe */ +#define SAFE_PRIV_ERROR -1 /* syscall error */ + +/* + * macros for byte swapping; also scratch space + * u_quad 0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0 + * u_long 0-->3, 1-->2, 2-->1, 3-->0 + * u_short 0-->1, 1-->0 + */ + +#define swap_u_16(x) {\ + unsigned long _krb_swap_tmp[4];\ + swab(((char *) x) +0, ((char *) _krb_swap_tmp) +14 ,2); \ + swab(((char *) x) +2, ((char *) _krb_swap_tmp) +12 ,2); \ + swab(((char *) x) +4, ((char *) _krb_swap_tmp) +10 ,2); \ + swab(((char *) x) +6, ((char *) _krb_swap_tmp) +8 ,2); \ + swab(((char *) x) +8, ((char *) _krb_swap_tmp) +6 ,2); \ + swab(((char *) x) +10,((char *) _krb_swap_tmp) +4 ,2); \ + swab(((char *) x) +12,((char *) _krb_swap_tmp) +2 ,2); \ + swab(((char *) x) +14,((char *) _krb_swap_tmp) +0 ,2); \ + bcopy((char *)_krb_swap_tmp,(char *)x,16);\ + } + +#define swap_u_12(x) {\ + unsigned long _krb_swap_tmp[4];\ + swab(( char *) x, ((char *) _krb_swap_tmp) +10 ,2); \ + swab(((char *) x) +2, ((char *) _krb_swap_tmp) +8 ,2); \ + swab(((char *) x) +4, ((char *) _krb_swap_tmp) +6 ,2); \ + swab(((char *) x) +6, ((char *) _krb_swap_tmp) +4 ,2); \ + swab(((char *) x) +8, ((char *) _krb_swap_tmp) +2 ,2); \ + swab(((char *) x) +10,((char *) _krb_swap_tmp) +0 ,2); \ + bcopy((char *)_krb_swap_tmp,(char *)x,12);\ + } + +#define swap_C_Block(x) {\ + unsigned long _krb_swap_tmp[4];\ + swab(( char *) x, ((char *) _krb_swap_tmp) +6 ,2); \ + swab(((char *) x) +2,((char *) _krb_swap_tmp) +4 ,2); \ + swab(((char *) x) +4,((char *) _krb_swap_tmp) +2 ,2); \ + swab(((char *) x) +6,((char *) _krb_swap_tmp) ,2); \ + bcopy((char *)_krb_swap_tmp,(char *)x,8);\ + } +#define swap_u_quad(x) {\ + unsigned long _krb_swap_tmp[4];\ + swab(( char *) &x, ((char *) _krb_swap_tmp) +6 ,2); \ + swab(((char *) &x) +2,((char *) _krb_swap_tmp) +4 ,2); \ + swab(((char *) &x) +4,((char *) _krb_swap_tmp) +2 ,2); \ + swab(((char *) &x) +6,((char *) _krb_swap_tmp) ,2); \ + bcopy((char *)_krb_swap_tmp,(char *)&x,8);\ + } + +#define swap_u_long(x) {\ + unsigned long _krb_swap_tmp[4];\ + swab((char *) &x, ((char *) _krb_swap_tmp) +2 ,2); \ + swab(((char *) &x) +2,((char *) _krb_swap_tmp),2); \ + x = _krb_swap_tmp[0]; \ + } + +#define swap_u_short(x) {\ + unsigned short _krb_swap_sh_tmp; \ + swab((char *) &x, ( &_krb_swap_sh_tmp) ,2); \ + x = (unsigned short) _krb_swap_sh_tmp; \ + } + +/* Kerberos ticket flag field bit definitions */ +#define K_FLAG_ORDER 0 /* bit 0 --> lsb */ +#define K_FLAG_1 /* reserved */ +#define K_FLAG_2 /* reserved */ +#define K_FLAG_3 /* reserved */ +#define K_FLAG_4 /* reserved */ +#define K_FLAG_5 /* reserved */ +#define K_FLAG_6 /* reserved */ +#define K_FLAG_7 /* reserved, bit 7 --> msb */ + +#ifndef PC +char *tkt_string(); +#endif PC + +#ifdef OLDNAMES +#define krb_mk_req mk_ap_req +#define krb_rd_req rd_ap_req +#define krb_kntoln an_to_ln +#define krb_set_key set_serv_key +#define krb_get_cred get_credentials +#define krb_mk_priv mk_private_msg +#define krb_rd_priv rd_private_msg +#define krb_mk_safe mk_safe_msg +#define krb_rd_safe rd_safe_msg +#define krb_mk_err mk_appl_err_msg +#define krb_rd_err rd_appl_err_msg +#define krb_ck_repl check_replay +#define krb_get_pw_in_tkt get_in_tkt +#define krb_get_svc_in_tkt get_svc_in_tkt +#define krb_get_pw_tkt get_pw_tkt +#define krb_realmofhost krb_getrealm +#define krb_get_phost get_phost +#define krb_get_krbhst get_krbhst +#define krb_get_lrealm get_krbrlm +#endif OLDNAMES + +/* Defines for krb_sendauth and krb_recvauth */ + +#define KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */ +#define KOPT_DO_MUTUAL 0x00000002 /* do mutual auth */ + +#define KOPT_DONT_CANON 0x00000004 /* + * don't canonicalize inst as + * a hostname + */ + +#define KRB_SENDAUTH_VLEN 8 /* length for version strings */ + +#ifdef ATHENA_COMPAT +#define KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */ +#endif ATHENA_COMPAT + +#endif KRB_DEFS diff --git a/eBones/include/krb_conf.h b/eBones/include/krb_conf.h new file mode 100644 index 0000000..824d5fe --- /dev/null +++ b/eBones/include/krb_conf.h @@ -0,0 +1,29 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This file contains configuration information for the Kerberos library + * which is machine specific; currently, this file contains + * configuration information for the vax, the "ibm032" (RT), and the + * "PC8086" (IBM PC). + * + * Note: cross-compiled targets must appear BEFORE their corresponding + * cross-compiler host. Otherwise, both will be defined when running + * the native compiler on the programs that construct cross-compiled + * sources. + * + * from: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp $ + * $Id: krb_conf.h,v 1.2 1994/07/19 19:23:18 g89r4222 Exp $ + */ + +#ifndef KRB_CONF_DEFS +#define KRB_CONF_DEFS + +/* Byte ordering */ +extern int krbONE; +#define HOST_BYTE_ORDER (* (char *) &krbONE) +#define MSB_FIRST 0 /* 68000, IBM RT/PC */ +#define LSB_FIRST 1 /* Vax, PC8086 */ + +#endif KRB_CONF_DEFS diff --git a/eBones/include/krb_db.h b/eBones/include/krb_db.h new file mode 100644 index 0000000..cbe00b9 --- /dev/null +++ b/eBones/include/krb_db.h @@ -0,0 +1,100 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * spm Project Athena 8/85 + * + * This file defines data structures for the kerberos + * authentication/authorization database. + * + * They MUST correspond to those defined in *.rel + * + * from: krb_db.h,v 4.9 89/01/24 17:55:39 jon Exp $ + * $Id: krb_db.h,v 1.2 1994/07/19 19:23:19 g89r4222 Exp $ + */ + +#ifndef KRB_DB_DEFS +#define KRB_DB_DEFS + +#define KERB_M_NAME "K" /* Kerberos */ +#define KERB_M_INST "M" /* Master */ +#define KERB_DEFAULT_NAME "default" +#define KERB_DEFAULT_INST "" +#define DBM_FILE "/etc/kerberosIV/principal" + +/* this also defines the number of queue headers */ +#define KERB_DB_HASH_MODULO 64 + + +/* Arguments to kerb_dbl_lock() */ + +#define KERB_DBL_EXCLUSIVE 1 +#define KERB_DBL_SHARED 0 + +/* arguments to kerb_db_set_lockmode() */ + +#define KERB_DBL_BLOCKING 0 +#define KERB_DBL_NONBLOCKING 1 + +/* Principal defines the structure of a principal's name */ + +typedef struct { + char name[ANAME_SZ]; + char instance[INST_SZ]; + + unsigned long key_low; + unsigned long key_high; + unsigned long exp_date; + char exp_date_txt[DATE_SZ]; + unsigned long mod_date; + char mod_date_txt[DATE_SZ]; + unsigned short attributes; + unsigned char max_life; + unsigned char kdc_key_ver; + unsigned char key_version; + + char mod_name[ANAME_SZ]; + char mod_instance[INST_SZ]; + char *old; /* cast to (Principal *); not in db, + * ptr to old vals */ +} + Principal; + +typedef struct { + long cpu; + long elapsed; + long dio; + long pfault; + long t_stamp; + long n_retrieve; + long n_replace; + long n_append; + long n_get_stat; + long n_put_stat; +} + DB_stat; + +/* Dba defines the structure of a database administrator */ + +typedef struct { + char name[ANAME_SZ]; + char instance[INST_SZ]; + unsigned short attributes; + unsigned long exp_date; + char exp_date_txt[DATE_SZ]; + char *old; /* + * cast to (Dba *); not in db, ptr to + * old vals + */ +} + Dba; + +extern int kerb_get_principal(); +extern int kerb_put_principal(); +extern int kerb_db_get_stat(); +extern int kerb_db_put_stat(); +extern int kerb_get_dba(); +extern int kerb_db_get_dba(); + +#endif /* KRB_DB_DEFS */ diff --git a/eBones/include/lsb_addr_comp.h b/eBones/include/lsb_addr_comp.h new file mode 100644 index 0000000..fe7dc94 --- /dev/null +++ b/eBones/include/lsb_addr_comp.h @@ -0,0 +1,40 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Comparison macros to emulate LSBFIRST comparison results of network + * byte-order quantities + * + * from: lsb_addr_comp.h,v 4.0 89/01/23 15:44:46 jtkohl Exp $ + * $Id: lsb_addr_comp.h,v 1.2 1994/07/19 19:23:21 g89r4222 Exp $ + */ + +#ifndef LSB_ADDR_COMP_DEFS +#define LSB_ADDR_COMP_DEFS + +#include "osconf.h" + +#ifdef LSBFIRST +#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)) +#else +/* MSBFIRST */ +#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]))) + +#endif /* LSBFIRST */ + +#endif /* LSB_ADDR_COMP_DEFS */ diff --git a/eBones/include/osconf.h b/eBones/include/osconf.h new file mode 100644 index 0000000..d3d4861 --- /dev/null +++ b/eBones/include/osconf.h @@ -0,0 +1,51 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Athena configuration. + * + * from: osconf.h,v 4.4 89/12/19 13:26:27 jtkohl Exp $ + * $Id: osconf.h,v 1.2 1994/07/19 19:23:22 g89r4222 Exp $ + */ + +#ifdef tahoe +#include "conf-bsdtahoe.h" +#else /* !tahoe */ +#ifdef vax +#include "conf-bsdvax.h" +#else /* !vax */ +#if defined(mips) && defined(ultrix) +#include "conf-ultmips2.h" +#else /* !Ultrix MIPS-2 */ +#ifdef ibm032 +#include "conf-bsdibm032.h" +#else /* !ibm032 */ +#ifdef apollo +#include "conf-bsdapollo.h" +#else /* !apollo */ +#ifdef sun +#ifdef sparc +#include "conf-bsdsparc.h" +#else /* sun but not sparc */ +#ifdef i386 +#include "conf-bsd386i.h" +#else /* sun but not (sparc or 386i) */ +#include "conf-bsdm68k.h" +#endif /* i386 */ +#endif /* sparc */ +#else /* !sun */ +#ifdef pyr +#include "conf-pyr.h" +#endif /* pyr */ +#endif /* sun */ +#endif /* apollo */ +#endif /* ibm032 */ +#endif /* mips */ +#endif /* vax */ +#endif /* tahoe */ + +#if defined(__FreeBSD__) && defined(i386) +#include "conf-bsd386i.h" +#endif + diff --git a/eBones/include/passwd_server.h b/eBones/include/passwd_server.h new file mode 100644 index 0000000..cb8eb08 --- /dev/null +++ b/eBones/include/passwd_server.h @@ -0,0 +1,28 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file for password server + * + * from: passwd_server.h,v 4.6 89/01/11 15:12:22 steiner Exp $ + * $Id: passwd_server.h,v 1.2 1994/07/19 19:23:24 g89r4222 Exp $ + */ + +#ifndef PASSWD_SERVER_DEFS +#define PASSWD_SERVER_DEFS + +#define PW_SRV_VERSION 2 /* version number */ +#define RETRY_LIMIT 1 +#define TIME_OUT 30 +#define USER_TIMEOUT 90 +#define MAX_KPW_LEN 40 /* hey, seems like a good number */ + +#define INSTALL_NEW_PW (1<<0) /* + * ver, cmd, name, password, old_pass, + * crypt_pass, uid + */ + +#define INSTALL_REPLY (1<<1) /* ver, cmd, name, password */ + +#endif /* PASSWD_SERVER_DEFS */ diff --git a/eBones/include/principal.h b/eBones/include/principal.h new file mode 100644 index 0000000..4590116 --- /dev/null +++ b/eBones/include/principal.h @@ -0,0 +1,18 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Definitions for principal names. + * + * from: principal.h,v 4.5 89/01/11 15:15:01 steiner Exp $ + * $Id: principal.h,v 1.2 1994/07/19 19:23:25 g89r4222 Exp $ + */ + +#ifndef PRINCIPAL_DEFS +#define PRINCIPAL_DEFS + +#define NAME_LEN 39 +#define INSTANCE_LEN 39 + +#endif /* PRINCIPAL_DEFS */ diff --git a/eBones/include/prot.h b/eBones/include/prot.h new file mode 100644 index 0000000..7865607 --- /dev/null +++ b/eBones/include/prot.h @@ -0,0 +1,92 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Include file with authentication protocol information. + * + * from: prot.h,v 4.13 89/01/24 14:27:22 jtkohl Exp $ + * $Id: prot.h,v 1.2 1994/07/19 19:23:27 g89r4222 Exp $ + */ + +#include <krb_conf.h> + +#ifndef PROT_DEFS +#define PROT_DEFS + +#define KRB_PORT 750 /* PC's don't have + * /etc/services */ +#define KRB_PROT_VERSION 4 +#define MAX_PKT_LEN 1000 +#define MAX_TXT_LEN 1000 +#define TICKET_GRANTING_TICKET "krbtgt" + +/* Macro's to obtain various fields from a packet */ + +#define pkt_version(packet) (unsigned int) *(packet->dat) +#define pkt_msg_type(packet) (unsigned int) *(packet->dat+1) +#define pkt_a_name(packet) (packet->dat+2) +#define pkt_a_inst(packet) \ + (packet->dat+3+strlen((char *)pkt_a_name(packet))) +#define pkt_a_realm(packet) \ + (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet))) + +/* Macro to obtain realm from application request */ +#define apreq_realm(auth) (auth->dat + 3) + +#define pkt_time_ws(packet) (char *) \ + (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \ + strlen((char *)pkt_a_inst(packet)) + \ + strlen((char *)pkt_a_realm(packet))) + +#define pkt_no_req(packet) (unsigned short) \ + *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \ + strlen((char *)pkt_a_inst(packet)) + \ + strlen((char *)pkt_a_realm(packet))) +#define pkt_x_date(packet) (char *) \ + (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \ + strlen((char *)pkt_a_inst(packet)) + \ + strlen((char *)pkt_a_realm(packet))) +#define pkt_err_code(packet) ( (char *) \ + (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \ + strlen((char *)pkt_a_inst(packet)) + \ + strlen((char *)pkt_a_realm(packet)))) +#define pkt_err_text(packet) \ + (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \ + strlen((char *)pkt_a_inst(packet)) + \ + strlen((char *)pkt_a_realm(packet))) + +/* Routines to create and read packets may be found in prot.c */ + +KTEXT create_auth_reply(); +KTEXT create_death_packet(); +KTEXT pkt_cipher(); + +/* Message types , always leave lsb for byte order */ + +#define AUTH_MSG_KDC_REQUEST 1<<1 +#define AUTH_MSG_KDC_REPLY 2<<1 +#define AUTH_MSG_APPL_REQUEST 3<<1 +#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 +#define AUTH_MSG_ERR_REPLY 5<<1 +#define AUTH_MSG_PRIVATE 6<<1 +#define AUTH_MSG_SAFE 7<<1 +#define AUTH_MSG_APPL_ERR 8<<1 +#define AUTH_MSG_DIE 63<<1 + +/* values for kerb error codes */ + +#define KERB_ERR_OK 0 +#define KERB_ERR_NAME_EXP 1 +#define KERB_ERR_SERVICE_EXP 2 +#define KERB_ERR_AUTH_EXP 3 +#define KERB_ERR_PKT_VER 4 +#define KERB_ERR_NAME_MAST_KEY_VER 5 +#define KERB_ERR_SERV_MAST_KEY_VER 6 +#define KERB_ERR_BYTE_ORDER 7 +#define KERB_ERR_PRINCIPAL_UNKNOWN 8 +#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 +#define KERB_ERR_NULL_KEY 10 + +#endif /* PROT_DEFS */ diff --git a/eBones/kadmin/kadmin.8 b/eBones/kadmin/kadmin.8 new file mode 100644 index 0000000..6e15015 --- /dev/null +++ b/eBones/kadmin/kadmin.8 @@ -0,0 +1,158 @@ +.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $ +.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmin \- network utility for Kerberos database administration +.SH SYNOPSIS +.B kadmin [-u user] [-r default_realm] [-m] +.SH DESCRIPTION +This utility provides a unified administration interface to +the +Kerberos +master database. +Kerberos +administrators +use +.I kadmin +to register new users and services to the master database, +and to change information about existing database entries. +For instance, an administrator can use +.I kadmin +to change a user's +Kerberos +password. +A Kerberos administrator is a user with an ``admin'' instance +whose name appears on one of the Kerberos administration access control +lists. If the \-u option is used, +.I user +will be used as the administrator instead of the local user. +If the \-r option is used, +.I default_realm +will be used as the default realm for transactions. Otherwise, +the local realm will be used by default. +If the \-m option is used, multiple requests will be permitted +on only one entry of the admin password. Some sites won't +support this option. + +The +.I kadmin +program communicates over the network with the +.I kadmind +program, which runs on the machine housing the Kerberos master +database. +The +.I kadmind +creates new entries and makes modifications to the database. + +When you enter the +.I kadmin +command, +the program displays a message that welcomes you and explains +how to ask for help. +Then +.I kadmin +waits for you to enter commands (which are described below). +It then asks you for your +.I admin +password before accessing the database. + +Use the +.I add_new_key +(or +.I ank +for short) +command to register a new principal +with the master database. +The command requires one argument, +the principal's name. The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's +new password. If no realm is specified, +the local realm is used unless another was +given on the commandline with the \-r flag. +If no instance is +specified, a null instance is used. If +a realm other than the default realm is specified, +you will need to supply your admin password for +the other realm. + +Use the +.I change_password (cpw) +to change a principal's +Kerberos +password. +The command requires one argument, +the principal's +name. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's new password. +The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. + +Use the +.I change_admin_password (cap) +to change your +.I admin +instance password. +This command requires no arguments. +It prompts you for your old +.I admin +password, then prompts you twice to enter the new +.I admin +password. If this is your first command, +the default realm is used. Otherwise, the realm +used in the last command is used. + +Use the +.I destroy_tickets (dest) +command to destroy your admin tickets explicitly. + +Use the +.I list_requests (lr) +command to get a list of possible commands. + +Use the +.I help +command to display +.IR kadmin's +various help messages. +If entered without an argument, +.I help +displays a general help message. +You can get detailed information on specific +.I kadmin +commands +by entering +.I help +.IR command_name . + +To quit the program, type +.IR quit . + +.SH BUGS +The user interface is primitive, and the command names could be better. + +.SH "SEE ALSO" +kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8) +.br +``A Subsystem Utilities Package for UNIX'' by Ken Raeburn +.SH AUTHORS +Jeffrey I. Schiller, MIT Project Athena +.br +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/kadmind/kadmind.8 b/eBones/kadmind/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/kadmind/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/kdb/Makefile b/eBones/kdb/Makefile new file mode 100644 index 0000000..b69c0d9 --- /dev/null +++ b/eBones/kdb/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.3 1994/09/09 21:43:41 g89r4222 Exp $ + +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 + +LIB= kdb +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c + +.include <bsd.lib.mk> diff --git a/eBones/kdb/krb_cache.c b/eBones/kdb/krb_cache.c new file mode 100644 index 0000000..4d8c594 --- /dev/null +++ b/eBones/kdb/krb_cache.c @@ -0,0 +1,193 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This is where a cache would be implemented, if it were necessary. + * + * from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $ + * $Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +extern char *strncpy(); + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +#endif +static init = 0; + +/* + * initialization routine for cache + */ + +int +kerb_cache_init() +{ + init = 1; + return (0); +} + +/* + * look up a principal in the cache returns number of principals found + */ + +int +kerb_cache_get_principal(serv, inst, principal, max) + char *serv; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + +{ + int found = 0; + u_long i; + + if (!init) + kerb_cache_init(); +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "cache_get_principal for %s %s max = %d\n", + serv, inst, max); +#endif DEBUG + +#ifdef DEBUG + if (kerb_debug & 2) { + if (found) { + fprintf(stderr, "cache get %s %s found %s %s sid = %d\n", + serv, inst, principal->name, principal->instance); + } else { + fprintf(stderr, "cache %s %s not found\n", serv, + inst); + } + } +#endif + return (found); +} + +/* + * insert/replace a principal in the cache returns number of principals + * inserted + */ + +int +kerb_cache_put_principal(principal, max) + Principal *principal; + unsigned int max; /* max number of principal structs to + * insert */ + +{ + int found = 0; + u_long i; + int count = 0; + + if (!init) + kerb_cache_init(); + +#ifdef DEBUG + if (kerb_debug & 2) { + fprintf(stderr, "kerb_cache_put_principal max = %d", + max); + } +#endif + + for (i = 0; i < max; i++) { +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "\n %s %s", + principal->name, principal->instance); +#endif + /* DO IT */ + count++; + principal++; + } + return count; +} + +/* + * look up a dba in the cache returns number of dbas found + */ + +int +kerb_cache_get_dba(serv, inst, dba, max) + char *serv; /* could have wild card */ + char *inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + +{ + int found = 0; + u_long i; + + if (!init) + kerb_cache_init(); + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "cache_get_dba for %s %s max = %d\n", + serv, inst, max); +#endif + +#ifdef DEBUG + if (kerb_debug & 2) { + if (found) { + fprintf(stderr, "cache get %s %s found %s %s sid = %d\n", + serv, inst, dba->name, dba->instance); + } else { + fprintf(stderr, "cache %s %s not found\n", serv, inst); + } + } +#endif + return (found); +} + +/* + * insert/replace a dba in the cache returns number of dbas inserted + */ + +int +kerb_cache_put_dba(dba, max) + Dba *dba; + unsigned int max; /* max number of dba structs to insert */ + +{ + int found = 0; + u_long i; + int count = 0; + + if (!init) + kerb_cache_init(); +#ifdef DEBUG + if (kerb_debug & 2) { + fprintf(stderr, "kerb_cache_put_dba max = %d", max); + } +#endif + for (i = 0; i < max; i++) { +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "\n %s %s", + dba->name, dba->instance); +#endif + /* DO IT */ + count++; + dba++; + } + return count; +} + diff --git a/eBones/kdb/krb_dbl.c b/eBones/kdb/krb_dbl.c new file mode 100644 index 0000000..7776298 --- /dev/null +++ b/eBones/kdb/krb_dbl.c @@ -0,0 +1 @@ +This file is now obsolete. diff --git a/eBones/kdb/krb_dbm.c b/eBones/kdb/krb_dbm.c new file mode 100644 index 0000000..754dd68 --- /dev/null +++ b/eBones/kdb/krb_dbm.c @@ -0,0 +1,741 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $ + * $Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $"; +#endif lint + +#if defined(__FreeBSD__) +#define NDBM +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/resource.h> +#include <sys/errno.h> +#include <strings.h> +#include <des.h> +#include <sys/file.h> +#ifdef NDBM +#include <ndbm.h> +#else /*NDBM*/ +#include <dbm.h> +#endif /*NDBM*/ +/* before krb_db.h */ +#include <krb.h> +#include <krb_db.h> + +#define KERB_DB_MAX_RETRY 5 + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +extern char *progname; +#endif +extern char *malloc(); +extern int errno; + +static init = 0; +static char default_db_name[] = DBM_FILE; +static char *current_db_name = default_db_name; +static void encode_princ_key(), decode_princ_key(); +static void encode_princ_contents(), decode_princ_contents(); +static void kerb_dbl_fini(); +static int kerb_dbl_lock(); +static void kerb_dbl_unlock(); + +static struct timeval timestamp;/* current time of request */ +static int non_blocking = 0; + +/* + * This module contains all of the code which directly interfaces to + * the underlying representation of the Kerberos database; this + * implementation uses a DBM or NDBM indexed "file" (actually + * implemented as two separate files) to store the relations, plus a + * third file as a semaphore to allow the database to be replaced out + * from underneath the KDC server. + */ + +/* + * Locking: + * + * There are two distinct locking protocols used. One is designed to + * lock against processes (the admin_server, for one) which make + * incremental changes to the database; the other is designed to lock + * against utilities (kdb_util, kpropd) which replace the entire + * database in one fell swoop. + * + * The first locking protocol is implemented using flock() in the + * krb_dbl_lock() and krb_dbl_unlock routines. + * + * The second locking protocol is necessary because DBM "files" are + * actually implemented as two separate files, and it is impossible to + * atomically rename two files simultaneously. It assumes that the + * database is replaced only very infrequently in comparison to the time + * needed to do a database read operation. + * + * A third file is used as a "version" semaphore; the modification + * time of this file is the "version number" of the database. + * At the start of a read operation, the reader checks the version + * number; at the end of the read operation, it checks again. If the + * version number changed, or if the semaphore was nonexistant at + * either time, the reader sleeps for a second to let things + * stabilize, and then tries again; if it does not succeed after + * KERB_DB_MAX_RETRY attempts, it gives up. + * + * On update, the semaphore file is deleted (if it exists) before any + * update takes place; at the end of the update, it is replaced, with + * a version number strictly greater than the version number which + * existed at the start of the update. + * + * If the system crashes in the middle of an update, the semaphore + * file is not automatically created on reboot; this is a feature, not + * a bug, since the database may be inconsistant. Note that the + * absence of a semaphore file does not prevent another _update_ from + * taking place later. Database replacements take place automatically + * only on slave servers; a crash in the middle of an update will be + * fixed by the next slave propagation. A crash in the middle of an + * update on the master would be somewhat more serious, but this would + * likely be noticed by an administrator, who could fix the problem and + * retry the operation. + */ + +/* Macros to convert ndbm names to dbm names. + * Note that dbm_nextkey() cannot be simply converted using a macro, since + * it is invoked giving the database, and nextkey() needs the previous key. + * + * Instead, all routines call "dbm_next" instead. + */ + +#ifndef NDBM +typedef char DBM; + +#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0)) +#define dbm_fetch(db, key) fetch(key) +#define dbm_store(db, key, content, flag) store(key, content) +#define dbm_firstkey(db) firstkey() +#define dbm_next(db,key) nextkey(key) +#define dbm_close(db) dbmclose() +#else +#define dbm_next(db,key) dbm_nextkey(db) +#endif + +/* + * Utility routine: generate name of database file. + */ + +static char *gen_dbsuffix(db_name, sfx) + char *db_name; + char *sfx; +{ + char *dbsuffix; + + if (sfx == NULL) + sfx = ".ok"; + + dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1); + strcpy(dbsuffix, db_name); + strcat(dbsuffix, sfx); + return dbsuffix; +} + +/* + * initialization for data base routines. + */ + +kerb_db_init() +{ + init = 1; + return (0); +} + +/* + * gracefully shut down database--must be called by ANY program that does + * a kerb_db_init + */ + +kerb_db_fini() +{ +} + +/* + * Set the "name" of the current database to some alternate value. + * + * Passing a null pointer as "name" will set back to the default. + * If the alternate database doesn't exist, nothing is changed. + */ + +kerb_db_set_name(name) + char *name; +{ + DBM *db; + + if (name == NULL) + name = default_db_name; + db = dbm_open(name, 0, 0); + if (db == NULL) + return errno; + dbm_close(db); + kerb_dbl_fini(); + current_db_name = name; + return 0; +} + +/* + * Return the last modification time of the database. + */ + +long kerb_get_db_age() +{ + struct stat st; + char *okname; + long age; + + okname = gen_dbsuffix(current_db_name, ".ok"); + + if (stat (okname, &st) < 0) + age = 0; + else + age = st.st_mtime; + + free (okname); + return age; +} + +/* + * Remove the semaphore file; indicates that database is currently + * under renovation. + * + * This is only for use when moving the database out from underneath + * the server (for example, during slave updates). + */ + +static long kerb_start_update(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + long age = kerb_get_db_age(); + + if (unlink(okname) < 0 + && errno != ENOENT) { + age = -1; + } + free (okname); + return age; +} + +static long kerb_end_update(db_name, age) + char *db_name; + long age; +{ + int fd; + int retval = 0; + char *new_okname = gen_dbsuffix(db_name, ".ok#"); + char *okname = gen_dbsuffix(db_name, ".ok"); + + fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + retval = errno; + else { + struct stat st; + struct timeval tv[2]; + /* make sure that semaphore is "after" previous value. */ + if (fstat (fd, &st) == 0 + && st.st_mtime <= age) { + tv[0].tv_sec = st.st_atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = age; + tv[1].tv_usec = 0; + /* set times.. */ + utimes (new_okname, tv); + fsync(fd); + } + close(fd); + if (rename (new_okname, okname) < 0) + retval = errno; + } + + free (new_okname); + free (okname); + + return retval; +} + +static long kerb_start_read() +{ + return kerb_get_db_age(); +} + +static long kerb_end_read(age) + u_long age; +{ + if (kerb_get_db_age() != age || age == -1) { + return -1; + } + return 0; +} + +/* + * Create the database, assuming it's not there. + */ + +kerb_db_create(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + int fd; + register int ret = 0; +#ifdef NDBM + DBM *db; + + db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (db == NULL) + ret = errno; + else + dbm_close(db); +#else + char *dirname = gen_dbsuffix(db_name, ".dir"); + char *pagname = gen_dbsuffix(db_name, ".pag"); + + fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else { + close(fd); + fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else + close(fd); + } + if (dbminit(db_name) < 0) + ret = errno; +#endif + if (ret == 0) { + fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + ret = errno; + close(fd); + } + return ret; +} + +/* + * "Atomically" rename the database in a way that locks out read + * access in the middle of the rename. + * + * Not perfect; if we crash in the middle of an update, we don't + * necessarily know to complete the transaction the rename, but... + */ + +kerb_db_rename(from, to) + char *from; + char *to; +{ + char *fromdir = gen_dbsuffix (from, ".dir"); + char *todir = gen_dbsuffix (to, ".dir"); + char *frompag = gen_dbsuffix (from , ".pag"); + char *topag = gen_dbsuffix (to, ".pag"); + char *fromok = gen_dbsuffix(from, ".ok"); + long trans = kerb_start_update(to); + int ok; + + if ((rename (fromdir, todir) == 0) + && (rename (frompag, topag) == 0)) { + (void) unlink (fromok); + ok = 1; + } + + free (fromok); + free (fromdir); + free (todir); + free (frompag); + free (topag); + if (ok) + return kerb_end_update(to, trans); + else + return -1; +} + +/* + * look up a principal in the data base returns number of principals + * found , and whether there were more than requested. + */ + +kerb_db_get_principal(name, inst, principal, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + int *more; /* where there more than 'max' tuples? */ + +{ + int found = 0, code; + extern int errorproc(); + int wildp, wildi; + datum key, contents; + char testname[ANAME_SZ], testinst[INST_SZ]; + u_long trans; + int try; + DBM *db; + + if (!init) + kerb_db_init(); /* initialize database routines */ + + for (try = 0; try < KERB_DB_MAX_RETRY; try++) { + trans = kerb_start_read(); + + if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0) + return -1; + + db = dbm_open(current_db_name, O_RDONLY, 0600); + + *more = 0; + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, + "%s: db_get_principal for %s %s max = %d", + progname, name, inst, max); +#endif + + wildp = !strcmp(name, "*"); + wildi = !strcmp(inst, "*"); + + if (!wildi && !wildp) { /* nothing's wild */ + encode_princ_key(&key, name, inst); + contents = dbm_fetch(db, key); + if (contents.dptr == NULL) { + found = 0; + goto done; + } + decode_princ_contents(&contents, principal); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n", + principal->name, principal->instance, + strlen(principal->name), + strlen(principal->instance)); + } +#endif + found = 1; + goto done; + } + /* process wild cards by looping through entire database */ + + for (key = dbm_firstkey(db); key.dptr != NULL; + key = dbm_next(db, key)) { + decode_princ_key(&key, testname, testinst); + if ((wildp || !strcmp(testname, name)) && + (wildi || !strcmp(testinst, inst))) { /* have a match */ + if (found >= max) { + *more = 1; + goto done; + } else { + found++; + contents = dbm_fetch(db, key); + decode_princ_contents(&contents, principal); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, + "\tfound %s %s p_n length %d t_n length %d\n", + principal->name, principal->instance, + strlen(principal->name), + strlen(principal->instance)); + } +#endif + principal++; /* point to next */ + } + } + } + + done: + kerb_dbl_unlock(); /* unlock read lock */ + dbm_close(db); + if (kerb_end_read(trans) == 0) + break; + found = -1; + if (!non_blocking) + sleep(1); + } + return (found); +} + +/* + * Update a name in the data base. Returns number of names + * successfully updated. + */ + +kerb_db_put_principal(principal, max) + Principal *principal; + unsigned int max; /* number of principal structs to + * update */ + +{ + int found = 0, code; + u_long i; + extern int errorproc(); + datum key, contents; + DBM *db; + + gettimeofday(×tamp, NULL); + + if (!init) + kerb_db_init(); + + if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0) + return -1; + + db = dbm_open(current_db_name, O_RDWR, 0600); + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "%s: kerb_db_put_principal max = %d", + progname, max); +#endif + + /* for each one, stuff temps, and do replace/append */ + for (i = 0; i < max; i++) { + encode_princ_contents(&contents, principal); + encode_princ_key(&key, principal->name, principal->instance); + dbm_store(db, key, contents, DBM_REPLACE); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, "\n put %s %s\n", + principal->name, principal->instance); + } +#endif + found++; + principal++; /* bump to next struct */ + } + + dbm_close(db); + kerb_dbl_unlock(); /* unlock database */ + return (found); +} + +static void +encode_princ_key(key, name, instance) + datum *key; + char *name, *instance; +{ + static char keystring[ANAME_SZ + INST_SZ]; + + bzero(keystring, ANAME_SZ + INST_SZ); + strncpy(keystring, name, ANAME_SZ); + strncpy(&keystring[ANAME_SZ], instance, INST_SZ); + key->dptr = keystring; + key->dsize = ANAME_SZ + INST_SZ; +} + +static void +decode_princ_key(key, name, instance) + datum *key; + char *name, *instance; +{ + strncpy(name, key->dptr, ANAME_SZ); + strncpy(instance, key->dptr + ANAME_SZ, INST_SZ); + name[ANAME_SZ - 1] = '\0'; + instance[INST_SZ - 1] = '\0'; +} + +static void +encode_princ_contents(contents, principal) + datum *contents; + Principal *principal; +{ + contents->dsize = sizeof(*principal); + contents->dptr = (char *) principal; +} + +static void +decode_princ_contents(contents, principal) + datum *contents; + Principal *principal; +{ + bcopy(contents->dptr, (char *) principal, sizeof(*principal)); +} + +kerb_db_get_stat(s) + DB_stat *s; +{ + gettimeofday(×tamp, NULL); + + + s->cpu = 0; + s->elapsed = 0; + s->dio = 0; + s->pfault = 0; + s->t_stamp = timestamp.tv_sec; + s->n_retrieve = 0; + s->n_replace = 0; + s->n_append = 0; + s->n_get_stat = 0; + s->n_put_stat = 0; + /* update local copy too */ +} + +kerb_db_put_stat(s) + DB_stat *s; +{ +} + +delta_stat(a, b, c) + DB_stat *a, *b, *c; +{ + /* c = a - b then b = a for the next time */ + + c->cpu = a->cpu - b->cpu; + c->elapsed = a->elapsed - b->elapsed; + c->dio = a->dio - b->dio; + c->pfault = a->pfault - b->pfault; + c->t_stamp = a->t_stamp - b->t_stamp; + c->n_retrieve = a->n_retrieve - b->n_retrieve; + c->n_replace = a->n_replace - b->n_replace; + c->n_append = a->n_append - b->n_append; + c->n_get_stat = a->n_get_stat - b->n_get_stat; + c->n_put_stat = a->n_put_stat - b->n_put_stat; + + bcopy(a, b, sizeof(DB_stat)); + return; +} + +/* + * look up a dba in the data base returns number of dbas found , and + * whether there were more than requested. + */ + +kerb_db_get_dba(dba_name, dba_inst, dba, max, more) + char *dba_name; /* could have wild card */ + char *dba_inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + int *more; /* where there more than 'max' tuples? */ + +{ + *more = 0; + return (0); +} + +kerb_db_iterate (func, arg) + int (*func)(); + char *arg; /* void *, really */ +{ + datum key, contents; + Principal *principal; + int code; + DBM *db; + + kerb_db_init(); /* initialize and open the database */ + if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0) + return code; + + db = dbm_open(current_db_name, O_RDONLY, 0600); + + for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) { + contents = dbm_fetch (db, key); + /* XXX may not be properly aligned */ + principal = (Principal *) contents.dptr; + if ((code = (*func)(arg, principal)) != 0) + return code; + } + dbm_close(db); + kerb_dbl_unlock(); + return 0; +} + +static int dblfd = -1; +static int mylock = 0; +static int inited = 0; + +static kerb_dbl_init() +{ + if (!inited) { + char *filename = gen_dbsuffix (current_db_name, ".ok"); + if ((dblfd = open(filename, 0)) < 0) { + fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename); + fflush(stderr); + perror("open"); + exit(1); + } + free(filename); + inited++; + } + return (0); +} + +static void kerb_dbl_fini() +{ + close(dblfd); + dblfd = -1; + inited = 0; + mylock = 0; +} + +static int kerb_dbl_lock(mode) + int mode; +{ + int flock_mode; + + if (!inited) + kerb_dbl_init(); + if (mylock) { /* Detect lock call when lock already + * locked */ + fprintf(stderr, "Kerberos locking error (mylock)\n"); + fflush(stderr); + exit(1); + } + switch (mode) { + case KERB_DBL_EXCLUSIVE: + flock_mode = LOCK_EX; + break; + case KERB_DBL_SHARED: + flock_mode = LOCK_SH; + break; + default: + fprintf(stderr, "invalid lock mode %d\n", mode); + abort(); + } + if (non_blocking) + flock_mode |= LOCK_NB; + + if (flock(dblfd, flock_mode) < 0) + return errno; + mylock++; + return 0; +} + +static void kerb_dbl_unlock() +{ + if (!mylock) { /* lock already unlocked */ + fprintf(stderr, "Kerberos database lock not locked when unlocking.\n"); + fflush(stderr); + exit(1); + } + if (flock(dblfd, LOCK_UN) < 0) { + fprintf(stderr, "Kerberos database lock error. (unlocking)\n"); + fflush(stderr); + perror("flock"); + exit(1); + } + mylock = 0; +} + +int kerb_db_set_lockmode(mode) + int mode; +{ + int old = non_blocking; + non_blocking = mode; + return old; +} diff --git a/eBones/kdb/krb_kdb_utils.c b/eBones/kdb/krb_kdb_utils.c new file mode 100644 index 0000000..5fccc53 --- /dev/null +++ b/eBones/kdb/krb_kdb_utils.c @@ -0,0 +1,141 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Utility routines for Kerberos programs which directly access + * the database. This code was duplicated in too many places + * before I gathered it here. + * + * Jon Rochlis, MIT Telecom, March 1988 + * + * from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $ + * $Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $"; +#endif lint + +#include <des.h> +#include <krb.h> +#include <krb_db.h> +#include <kdc.h> +#include <stdio.h> +#include <sys/file.h> + +long kdb_get_master_key(prompt, master_key, master_key_sched) + int prompt; + C_Block master_key; + Key_schedule master_key_sched; +{ + int kfile; + + if (prompt) { +#ifdef NOENCRYPTION + placebo_read_password(master_key, + "\nEnter Kerberos master key: ", 0); +#else + des_read_password(master_key, + "\nEnter Kerberos master key: ", 0); +#endif + printf ("\n"); + } + else { + kfile = open(MKEYFILE, O_RDONLY, 0600); + if (kfile < 0) { + /* oh, for com_err_ */ + return (-1); + } + if (read(kfile, (char *) master_key, 8) != 8) { + return (-1); + } + close(kfile); + } + +#ifndef NOENCRYPTION + key_sched(master_key,master_key_sched); +#endif + return (0); +} + +/* The caller is reasponsible for cleaning up the master key and sched, + even if we can't verify the master key */ + +/* Returns master key version if successful, otherwise -1 */ + +long kdb_verify_master_key (master_key, master_key_sched, out) + C_Block master_key; + Key_schedule master_key_sched; + FILE *out; /* setting this to non-null be do output */ +{ + C_Block key_from_db; + Principal principal_data[1]; + int n, more = 0; + long master_key_version; + + /* lookup the master key version */ + n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data, + 1 /* only one please */, &more); + if ((n != 1) || more) { + if (out != (FILE *) NULL) + fprintf(out, + "verify_master_key: %s, %d found.\n", + "Kerberos error on master key version lookup", + n); + return (-1); + } + + master_key_version = (long) principal_data[0].key_version; + + /* set up the master key */ + if (out != (FILE *) NULL) /* should we punt this? */ + fprintf(out, "Current Kerberos master key version is %d.\n", + principal_data[0].kdc_key_ver); + + /* + * now use the master key to decrypt the key in the db, had better + * be the same! + */ + bcopy(&principal_data[0].key_low, key_from_db, 4); + bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4); + kdb_encrypt_key (key_from_db, key_from_db, + master_key, master_key_sched, DECRYPT); + + /* the decrypted database key had better equal the master key */ + n = bcmp((char *) master_key, (char *) key_from_db, + sizeof(master_key)); + /* this used to zero the master key here! */ + bzero(key_from_db, sizeof(key_from_db)); + bzero(principal_data, sizeof (principal_data)); + + if (n && (out != (FILE *) NULL)) { + fprintf(out, "\n\07\07verify_master_key: Invalid master key; "); + fprintf(out, "does not match database.\n"); + return (-1); + } + if (out != (FILE *) NULL) { + fprintf(out, "\nMaster key entered. BEWARE!\07\07\n"); + fflush(out); + } + + return (master_key_version); +} + +/* The old algorithm used the key schedule as the initial vector which + was byte order depedent ... */ + +kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag) + C_Block in, out, master_key; + Key_schedule master_key_sched; + int e_d_flag; +{ + +#ifdef NOENCRYPTION + bcopy(in, out, sizeof(C_Block)); +#else + pcbc_encrypt(in,out,(long)sizeof(C_Block),master_key_sched,master_key, + e_d_flag); +#endif +} diff --git a/eBones/kdb/krb_lib.c b/eBones/kdb/krb_lib.c new file mode 100644 index 0000000..f0f1f6f --- /dev/null +++ b/eBones/kdb/krb_lib.c @@ -0,0 +1,242 @@ +/* + * $Source: /home/CVS/src/eBones/kdb/krb_lib.c,v $ + * $Author: g89r4222 $ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_lib.c,v 1.2 1994/07/19 19:23:39 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +#ifdef DEBUG +extern int debug; +extern char *progname; +long kerb_debug; +#endif + +extern char *strncpy(); +extern char *ctime(); +extern char *getenv(); + +static init = 0; + +/* + * initialization routine for data base + */ + +int +kerb_init() +{ +#ifdef DEBUG + if (!init) { + char *dbg = getenv("KERB_DBG"); + if (dbg) + sscanf(dbg, "%d", &kerb_debug); + init = 1; + } +#endif + kerb_db_init(); + +#ifdef CACHE + kerb_cache_init(); +#endif + + /* successful init, return 0, else errcode */ + return (0); +} + +/* + * finalization routine for database -- NOTE: MUST be called by any + * program using kerb_init. ALSO will have to be modified to finalize + * caches, if they're ever really implemented. + */ + +int +kerb_fini() +{ + kerb_db_fini(); +} + +/* + * look up a principal in the cache or data base returns number of + * principals found + */ + +int +kerb_get_principal(name, inst, principal, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + int *more; /* more tuples than room for */ + +{ + int found = 0; +#ifdef CACHE + static int wild = 0; +#endif + if (!init) + kerb_init(); + +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n", + progname, name, inst, max); +#endif + + /* + * if this is a request including a wild card, have to go to db + * since the cache may not be exhaustive. + */ + + /* clear the principal area */ + bzero((char *) principal, max * sizeof(Principal)); + +#ifdef CACHE + /* + * so check to see if the name contains a wildcard "*" or "?", not + * preceeded by a backslash. + */ + wild = 0; + if (index(name, '*') || index(name, '?') || + index(inst, '*') || index(inst, '?')) + wild = 1; + + if (!wild) { + /* try the cache first */ + found = kerb_cache_get_principal(name, inst, principal, max, more); + if (found) + return (found); + } +#endif + /* If we didn't try cache, or it wasn't there, try db */ + found = kerb_db_get_principal(name, inst, principal, max, more); + /* try to insert principal(s) into cache if it was found */ +#ifdef CACHE + if (found) { + kerb_cache_put_principal(principal, found); + } +#endif + return (found); +} + +/* principals */ +kerb_put_principal(principal, n) + Principal *principal; + unsigned int n; /* number of principal structs to write */ +{ + long time(); + struct tm *tp, *localtime(); + + /* set mod date */ + principal->mod_date = time((long *)0); + /* and mod date string */ + + tp = localtime(&principal->mod_date); + (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d", + tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900, + tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */ +#ifdef DEBUG + if (kerb_debug & 1) { + int i; + fprintf(stderr, "\nkerb_put_principal..."); + for (i = 0; i < n; i++) { + krb_print_principal(&principal[i]); + } + } +#endif + /* write database */ + if (kerb_db_put_principal(principal, n) < 0) { +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_db_put_principal err", progname); + /* watch out for cache */ +#endif + return -1; + } +#ifdef CACHE + /* write cache */ + if (!kerb_cache_put_principal(principal, n)) { +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname); +#endif + return -1; + } +#endif + return 0; +} + +int +kerb_get_dba(name, inst, dba, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + int *more; /* more tuples than room for */ + +{ + int found = 0; +#ifdef CACHE + static int wild = 0; +#endif + if (!init) + kerb_init(); + +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n", + progname, name, inst, max); +#endif + /* + * if this is a request including a wild card, have to go to db + * since the cache may not be exhaustive. + */ + + /* clear the dba area */ + bzero((char *) dba, max * sizeof(Dba)); + +#ifdef CACHE + /* + * so check to see if the name contains a wildcard "*" or "?", not + * preceeded by a backslash. + */ + + wild = 0; + if (index(name, '*') || index(name, '?') || + index(inst, '*') || index(inst, '?')) + wild = 1; + + if (!wild) { + /* try the cache first */ + found = kerb_cache_get_dba(name, inst, dba, max, more); + if (found) + return (found); + } +#endif + /* If we didn't try cache, or it wasn't there, try db */ + found = kerb_db_get_dba(name, inst, dba, max, more); +#ifdef CACHE + /* try to insert dba(s) into cache if it was found */ + if (found) { + kerb_cache_put_dba(dba, found); + } +#endif + return (found); +} diff --git a/eBones/kdb/print_princ.c b/eBones/kdb/print_princ.c new file mode 100644 index 0000000..730cfb7 --- /dev/null +++ b/eBones/kdb/print_princ.c @@ -0,0 +1,50 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: $Header: /home/CVS/src/eBones/kdb/print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $ + * $Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <strings.h> +#include <krb.h> +#include <krb_db.h> + +extern int debug; +extern char *strncpy(); +extern char *ctime(); +extern struct tm *localtime(); +struct tm *time_p; + +long kerb_debug; + +krb_print_principal(a_n) + Principal *a_n; +{ + /* run-time database does not contain string versions */ + time_p = localtime(&(a_n->exp_date)); + + fprintf(stderr, + "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x", + a_n->name, a_n->instance, + time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900, + time_p->tm_mon + 1, time_p->tm_mday, + time_p->tm_hour, time_p->tm_min, + a_n->max_life, 5 * a_n->max_life, a_n->attributes); + + fprintf(stderr, + "\n\tkey_ver %d k_low 0x%08x k_high 0x%08x akv %d exists %d\n", + a_n->key_version, a_n->key_low, a_n->key_high, + a_n->kdc_key_ver, a_n->old); + + fflush(stderr); +} diff --git a/eBones/kdb_destroy/Makefile b/eBones/kdb_destroy/Makefile new file mode 100644 index 0000000..a48805b --- /dev/null +++ b/eBones/kdb_destroy/Makefile @@ -0,0 +1,8 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:23:46 g89r4222 Exp $ + +PROG= kdb_destroy +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kdb_destroy/kdb_destroy.8 b/eBones/kdb_destroy/kdb_destroy.8 new file mode 100644 index 0000000..93db466 --- /dev/null +++ b/eBones/kdb_destroy/kdb_destroy.8 @@ -0,0 +1,33 @@ +.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $ +.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_destroy \- destroy Kerberos key distribution center database +.SH SYNOPSIS +kdb_destroy +.SH DESCRIPTION +.I kdb_destroy +deletes a Kerberos key distribution center database. +.PP +The user is prompted to verify that the database should be destroyed. A +response beginning with `y' or `Y' confirms deletion. +Any other response aborts deletion. +.SH DIAGNOSTICS +.TP 20n +"Database cannot be deleted at /kerberos/principal" +The attempt to delete the database failed (probably due to a system or +access permission error). +.TP +"Database not deleted." +The user aborted the deletion. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.SH SEE ALSO +kdb_init(8) diff --git a/eBones/kdb_destroy/kdb_destroy.c b/eBones/kdb_destroy/kdb_destroy.c new file mode 100644 index 0000000..0c45896 --- /dev/null +++ b/eBones/kdb_destroy/kdb_destroy.c @@ -0,0 +1,45 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $ + * $Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $"; +#endif lint + +#include <strings.h> +#include <stdio.h> +#include "krb.h" +#include "krb_db.h" + +main() +{ + char answer[10]; /* user input */ + char dbm[256]; /* database path and name */ + char dbm1[256]; /* database path and name */ + char *file1, *file2; /* database file names */ + + strcpy(dbm, DBM_FILE); + strcpy(dbm1, DBM_FILE); + file1 = strcat(dbm, ".dir"); + file2 = strcat(dbm1, ".pag"); + + printf("You are about to destroy the Kerberos database "); + printf("on this machine.\n"); + printf("Are you sure you want to do this (y/n)? "); + fgets(answer, sizeof(answer), stdin); + + if (answer[0] == 'y' || answer[0] == 'Y') { + if (unlink(file1) == 0 && unlink(file2) == 0) + fprintf(stderr, "Database deleted at %s\n", DBM_FILE); + else + fprintf(stderr, "Database cannot be deleted at %s\n", + DBM_FILE); + } else + fprintf(stderr, "Database not deleted.\n"); +} diff --git a/eBones/kdb_edit/Makefile b/eBones/kdb_edit/Makefile new file mode 100644 index 0000000..65a5e5a --- /dev/null +++ b/eBones/kdb_edit/Makefile @@ -0,0 +1,12 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $ + +PROG= kdb_edit +CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include +SRCS= kdb_edit.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kdb_edit/kdb_edit.8 b/eBones/kdb_edit/kdb_edit.8 new file mode 100644 index 0000000..1cfd6ed --- /dev/null +++ b/eBones/kdb_edit/kdb_edit.8 @@ -0,0 +1,55 @@ +.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $ +.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_edit \- Kerberos key distribution center database editing utility +.SH SYNOPSIS +kdb_edit [ +.B \-n +] +.SH DESCRIPTION +.I kdb_edit +is used to create or change principals stored in the Kerberos key +distribution center (KDC) database. +.PP +When executed, +.I kdb_edit +prompts for the master key string and verifies that it matches the +master key stored in the database. +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +Once the master key has been verified, +.I kdb_edit +begins a prompt loop. The user is prompted for the principal and +instance to be modified. If the entry is not found the user may create +it. +Once an entry is found or created, the user may set the password, +expiration date, maximum ticket lifetime, and attributes. +Default expiration dates, maximum ticket lifetimes, and attributes are +presented in brackets; if the user presses return the default is selected. +There is no default password. +The password RANDOM is interpreted specially, and if entered +the user may have the program select a random DES key for the +principal. +.PP +Upon successfully creating or changing the entry, ``Edit O.K.'' is +printed. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/kdb_edit/kdb_edit.c b/eBones/kdb_edit/kdb_edit.c new file mode 100644 index 0000000..4c02db6 --- /dev/null +++ b/eBones/kdb_edit/kdb_edit.c @@ -0,0 +1,470 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine changes the Kerberos encryption keys for principals, + * i.e., users or services. + * + * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $ + * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $ + */ + +/* + * exit returns 0 ==> success -1 ==> error + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#include <strings.h> +#include <sys/ioctl.h> +#include <sys/file.h> +#include "time.h" +#include <des.h> +#include <krb.h> +#include <krb_db.h> +/* MKEYFILE is now defined in kdc.h */ +#include <kdc.h> + +extern char *errmsg(); +extern int errno; +extern char *strcpy(); + +void sig_exit(); + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +char prog[32]; +char *progname = prog; +int nflag = 0; +int cflag; +int lflag; +int uflag; +int debug; +extern kerb_debug; + +Key_schedule KS; +C_Block new_key; +unsigned char *input; + +unsigned char *ivec; +int i, j; +int more; + +char *in_ptr; +char input_name[ANAME_SZ]; +char input_instance[INST_SZ]; +char input_string[ANAME_SZ]; + +#define MAX_PRINCIPAL 10 +Principal principal_data[MAX_PRINCIPAL]; + +static Principal old_principal; +static Principal default_princ; + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +static char pw_str[255]; +static long master_key_version; + +/* + * gets replacement + */ +static char * s_gets(char * str, int len) +{ + int i; + char *s; + + if((s = fgets(str, len, stdin)) == NULL) + return(s); + if(str[i = (strlen(str)-1)] == '\n') + str[i] = '\0'; + return(s); +} + +main(argc, argv) + int argc; + char *argv[]; + +{ + /* Local Declarations */ + + long n; + + prog[sizeof prog - 1] = '\0'; /* make sure terminated */ + strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking + * program */ + + /* Assume a long is four bytes */ + if (sizeof(long) != 4) { + fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog); + exit(-1); + } + /* Assume <=32 signals */ + if (NSIG > 32) { + fprintf(stderr, "%s: more than 32 signals defined.\n", prog); + exit(-1); + } + while (--argc > 0 && (*++argv)[0] == '-') + for (i = 1; argv[0][i] != '\0'; i++) { + switch (argv[0][i]) { + + /* debug flag */ + case 'd': + debug = 1; + continue; + + /* debug flag */ + case 'l': + kerb_debug |= 1; + continue; + + case 'n': /* read MKEYFILE for master key */ + nflag = 1; + continue; + + default: + fprintf(stderr, "%s: illegal flag \"%c\"\n", + progname, argv[0][i]); + Usage(); /* Give message and die */ + } + }; + + fprintf(stdout, "Opening database...\n"); + fflush(stdout); + kerb_init(); + if (argc > 0) { + if (kerb_db_set_name(*argv) != 0) { + fprintf(stderr, "Could not open altername database name\n"); + exit(1); + } + } + +#ifdef notdef + no_core_dumps(); /* diddle signals to avoid core dumps! */ + + /* ignore whatever is reasonable */ + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + +#endif + + if (kdb_get_master_key ((nflag == 0), + master_key, master_key_schedule) != 0) { + fprintf (stdout, "Couldn't read master key.\n"); + fflush (stdout); + exit (-1); + } + + if ((master_key_version = kdb_verify_master_key(master_key, + master_key_schedule, + stdout)) < 0) + exit (-1); + + /* lookup the default values */ + n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + if (n != 1) { + fprintf(stderr, + "%s: Kerberos error on default value lookup, %d found.\n", + progname, n); + exit(-1); + } + fprintf(stdout, "Previous or default values are in [brackets] ,\n"); + fprintf(stdout, "enter return to leave the same, or new value.\n"); + + while (change_principal()) { + } + + cleanup(); +} + +change_principal() +{ + static char temp[255]; + int creating = 0; + int editpw = 0; + int changed = 0; + long temp_long; + int n; + struct tm *tp, edate, *localtime(); + long maketime(); + + fprintf(stdout, "\nPrincipal name: "); + fflush(stdout); + if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0') + return 0; + fprintf(stdout, "Instance: "); + fflush(stdout); + /* instance can be null */ + s_gets(input_instance, INST_SZ-1); + j = kerb_get_principal(input_name, input_instance, principal_data, + MAX_PRINCIPAL, &more); + if (!j) { + fprintf(stdout, "\n\07\07<Not found>, Create [y] ? "); + s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */ + if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0') + return -1; + /* make a new principal, fill in defaults */ + j = 1; + creating = 1; + strcpy(principal_data[0].name, input_name); + strcpy(principal_data[0].instance, input_instance); + principal_data[0].old = NULL; + principal_data[0].exp_date = default_princ.exp_date; + principal_data[0].max_life = default_princ.max_life; + principal_data[0].attributes = default_princ.attributes; + principal_data[0].kdc_key_ver = (unsigned char) master_key_version; + principal_data[0].key_version = 0; /* bumped up later */ + } + tp = localtime(&principal_data[0].exp_date); + (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d", + tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900, + tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */ + for (i = 0; i < j; i++) { + for (;;) { + fprintf(stdout, + "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d", + principal_data[i].name, principal_data[i].instance, + principal_data[i].kdc_key_ver); + editpw = 1; + changed = 0; + if (!creating) { + /* + * copy the existing data so we can use the old values + * for the qualifier clause of the replace + */ + principal_data[i].old = (char *) &old_principal; + bcopy(&principal_data[i], &old_principal, + sizeof(old_principal)); + printf("\nChange password [n] ? "); + s_gets(temp, sizeof(temp)-1); + if (strcmp("y", temp) && strcmp("Y", temp)) + editpw = 0; + } + /* password */ + if (editpw) { +#ifdef NOENCRYPTION + placebo_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#else + des_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#endif + if (!strcmp(pw_str, "RANDOM")) { + printf("\nRandom password [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "RANDOM" */ + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + } else if (!strcmp(pw_str, "NULL")) { + printf("\nNull Key [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "NULL" */ + } else { + + principal_data[i].key_low = 0; + principal_data[i].key_high = 0; + goto null_key; + } + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str,new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + + /* seal it under the kerberos master key */ + kdb_encrypt_key (new_key, new_key, + master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal_data[i].key_low, 4); + bcopy(((long *) new_key) + 1, + &principal_data[i].key_high, 4); + bzero(new_key, sizeof(new_key)); + null_key: + /* set master key version */ + principal_data[i].kdc_key_ver = + (unsigned char) master_key_version; + /* bump key version # */ + principal_data[i].key_version++; + fprintf(stdout, + "\nPrincipal's new key version = %d\n", + principal_data[i].key_version); + fflush(stdout); + changed = 1; + } + /* expiration date */ + fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) > + sizeof(principal_data[0].exp_date_txt))) { + bad_date: + fprintf(stdout, "\07\07Date Invalid\n"); + fprintf(stdout, + "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + } + + if (*temp) { + if (sscanf(temp, "%d-%d-%d", &edate.tm_year, + &edate.tm_mon, &edate.tm_mday) != 3) + goto bad_date; + (void) strcpy(principal_data[i].exp_date_txt, temp); + edate.tm_mon--; /* January is 0, not 1 */ + edate.tm_hour = 23; /* nearly midnight at the end of the */ + edate.tm_min = 59; /* specified day */ + if (!(principal_data[i].exp_date = maketime(&edate, 1))) + goto bad_date; + changed = 1; + } + + /* maximum lifetime */ + fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_life; + if (temp_long > 255 || (temp_long < 0)) { + bad_life: + fprintf(stdout, "\07\07Invalid, choose 0-255\n"); + fprintf(stdout, + "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].max_life = (unsigned short) temp_long; + break; + } + + /* attributes */ + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_att; + if (temp_long > 65535 || (temp_long < 0)) { + bad_att: + fprintf(stdout, "\07\07Invalid, choose 0-65535\n"); + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].attributes = + (unsigned short) temp_long; + break; + } + + /* + * remaining fields -- key versions and mod info, should + * not be directly manipulated + */ + if (changed) { + if (kerb_put_principal(&principal_data[i], 1)) { + fprintf(stdout, + "\nError updating Kerberos database"); + } else { + fprintf(stdout, "Edit O.K."); + } + } else { + fprintf(stdout, "Unchanged"); + } + + + bzero(&principal_data[i].key_low, 4); + bzero(&principal_data[i].key_high, 4); + fflush(stdout); + break; + } + } + if (more) { + fprintf(stdout, "\nThere were more tuples found "); + fprintf(stdout, "than there were space for"); + } + return 1; +} + + +no_core_dumps() +{ + + signal(SIGQUIT, sig_exit); + signal(SIGILL, sig_exit); + signal(SIGTRAP, sig_exit); + signal(SIGIOT, sig_exit); + signal(SIGEMT, sig_exit); + signal(SIGFPE, sig_exit); + signal(SIGBUS, sig_exit); + signal(SIGSEGV, sig_exit); + signal(SIGSYS, sig_exit); +} + +void +sig_exit(sig, code, scp) + int sig, code; + struct sigcontext *scp; +{ + cleanup(); + fprintf(stderr, + "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting", + sig, code, scp->sc_pc); + exit(-1); +} + + +cleanup() +{ + + bzero(master_key, sizeof(master_key)); + bzero(session_key, sizeof(session_key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(principal_data, sizeof(principal_data)); + bzero(new_key, sizeof(new_key)); + bzero(pw_str, sizeof(pw_str)); +} +Usage() +{ + fprintf(stderr, "Usage: %s [-n]\n", progname); + exit(1); +} diff --git a/eBones/kdb_edit/maketime.c b/eBones/kdb_edit/maketime.c new file mode 100644 index 0000000..057ecc3 --- /dev/null +++ b/eBones/kdb_edit/maketime.c @@ -0,0 +1,83 @@ +/* + * Copyright 1990 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Convert a struct tm * to a UNIX time. + * + * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $ + * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp "; +#endif lint + +#include <sys/time.h> + +#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) + +#define SECSPERDAY 24*60*60 +#define SECSPERHOUR 60*60 +#define SECSPERMIN 60 + +static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, + 365}; + +static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +long +maketime(tp, local) +register struct tm *tp; +int local; +{ + register long retval; + int foo; + int *marray; + + if (tp->tm_mon < 0 || tp->tm_mon > 11 || + tp->tm_hour < 0 || tp->tm_hour > 23 || + tp->tm_min < 0 || tp->tm_min > 59 || + tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */ + return 0; + + retval = 0; + if (tp->tm_year < 1900) + foo = tp->tm_year + 1900; + else + foo = tp->tm_year; + + if (foo < 1901 || foo > 2038) /* year is too small/large */ + return 0; + + if (daysinyear(foo) == 366) { + if (tp->tm_mon > 1) + retval+= SECSPERDAY; /* add leap day */ + marray = leapyear; + } else + marray = nonleapyear; + + if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon]) + return 0; /* out of range */ + + while (--foo >= 1970) + retval += daysinyear(foo) * SECSPERDAY; + + retval += cumdays[tp->tm_mon] * SECSPERDAY; + retval += (tp->tm_mday-1) * SECSPERDAY; + retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec; + + if (local) { + /* need to use local time, so we retrieve timezone info */ + struct timezone tz; + struct timeval tv; + if (gettimeofday(&tv, &tz) < 0) { + /* some error--give up? */ + return(retval); + } + retval += tz.tz_minuteswest * SECSPERMIN; + } + return(retval); +} diff --git a/eBones/kdb_edit/time.h b/eBones/kdb_edit/time.h new file mode 100644 index 0000000..ed128d8 --- /dev/null +++ b/eBones/kdb_edit/time.h @@ -0,0 +1,45 @@ +/* Structure for use by time manipulating subroutines. + * The following library routines use it: + * libc: ctime, localtime, gmtime, asctime + * libcx: partime, maketime (may not be installed yet) + */ + +/* + * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $ + * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $ + */ + +struct tm { /* See defines below for allowable ranges */ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + int tm_zon; /* NEW: mins westward of Greenwich */ + int tm_ampm; /* NEW: 1 if AM, 2 if PM */ +}; + +#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/ +#define TMNULL (-1) /* Items not specified are given this value + * in order to distinguish null specs from zero + * specs. This is only used by partime and + * maketime. */ + + /* Indices into TM structure */ +#define TM_SEC 0 /* 0-59 */ +#define TM_MIN 1 /* 0-59 */ +#define TM_HOUR 2 /* 0-23 */ +#define TM_MDAY 3 /* 1-31 day of month */ +#define TM_DAY TM_MDAY /* " synonym */ +#define TM_MON 4 /* 0-11 */ +#define TM_YEAR 5 /* (year-1900) (year) */ +#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */ +#define TM_YDAY 7 /* 0-365 day of year */ +#define TM_ISDST 8 /* 0 Std, 1 DST */ + /* New stuff */ +#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */ +#define TM_AMPM 10 /* 1 AM, 2 PM */ diff --git a/eBones/kdb_init/Makefile b/eBones/kdb_init/Makefile new file mode 100644 index 0000000..ce51a9f --- /dev/null +++ b/eBones/kdb_init/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:03 g89r4222 Exp $ + +PROG= kdb_init +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kdb_init/kdb_init.8 b/eBones/kdb_init/kdb_init.8 new file mode 100644 index 0000000..54537ad --- /dev/null +++ b/eBones/kdb_init/kdb_init.8 @@ -0,0 +1,41 @@ +.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $ +.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_init \- Initialize Kerberos key distribution center database +.SH SYNOPSIS +kdb_init [ +.B realm +] +.SH DESCRIPTION +.I kdb_init +initializes a Kerberos key distribution center database, creating the +necessary principals. +.PP +If the optional +.I realm +argument is not present, +.I kdb_init +prompts for a realm name (defaulting to the definition in /usr/include/krb.h). +After determining the realm to be created, it prompts for +a master key password. The master key password is used to encrypt +every encryption key stored in the database. +.SH DIAGNOSTICS +.TP 20n +"/kerberos/principal: File exists" +An attempt was made to create a database on a machine which already had +an existing database. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/usr/include/krb.h +Include file defining default realm +.SH SEE ALSO +kdb_destroy(8) diff --git a/eBones/kdb_init/kdb_init.c b/eBones/kdb_init/kdb_init.c new file mode 100644 index 0000000..dc7055e --- /dev/null +++ b/eBones/kdb_init/kdb_init.c @@ -0,0 +1,178 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * program to initialize the database, reports error if database file + * already exists. + * + * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $ + * $Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/time.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> +#include <string.h> + +#define TRUE 1 + +enum ap_op { + NULL_KEY, /* setup null keys */ + MASTER_KEY, /* use master key as new key */ + RANDOM_KEY, /* choose a random key */ +}; + +int debug = 0; +char *progname, *rindex(); +C_Block master_key; +Key_schedule master_key_schedule; + +main(argc, argv) + char *argv[]; +{ + char realm[REALM_SZ]; + char *cp; + int code; + char *database; + + progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + if (argc > 3) { + fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]); + exit(1); + } + if (argc == 3) { + database = argv[2]; + --argc; + } else + database = DBM_FILE; + + /* Do this first, it'll fail if the database exists */ + if ((code = kerb_db_create(database)) != 0) { + fprintf(stderr, "Couldn't create database: %s\n", + sys_errlist[code]); + exit(1); + } + kerb_db_set_name(database); + + if (argc == 2) + strncpy(realm, argv[1], REALM_SZ); + else { + fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM); + if (fgets(realm, sizeof(realm), stdin) == NULL) { + fprintf(stderr, "\nEOF reading realm\n"); + exit(1); + } + if (cp = index(realm, '\n')) + *cp = '\0'; + if (!*realm) /* no realm given */ + strcpy(realm, KRB_REALM); + } + if (!k_isrealm(realm)) { + fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n", + progname, realm); + exit(1); + } + printf("You will be prompted for the database Master Password.\n"); + printf("It is important that you NOT FORGET this password.\n"); + fflush(stdout); + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + exit (-1); + } + + if ( + add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) || + add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) || + add_principal("krbtgt", realm, RANDOM_KEY) || + add_principal("changepw", KRB_MASTER, RANDOM_KEY) + ) { + fprintf(stderr, "\n%s: couldn't initialize database.\n", + progname); + exit(1); + } + + /* play it safe */ + bzero (master_key, sizeof (C_Block)); + bzero (master_key_schedule, sizeof (Key_schedule)); + exit(0); +} + +/* use a return code to indicate success or failure. check the return */ +/* values of the routines called by this routine. */ + +add_principal(name, instance, aap_op) + char *name, *instance; + enum ap_op aap_op; +{ + Principal principal; + char datestring[50]; + char pw_str[255]; + void read_pw_string(); + void string_to_key(); + void random_key(); + struct tm *tm, *localtime(); + C_Block new_key; + + bzero(&principal, sizeof(principal)); + strncpy(principal.name, name, ANAME_SZ); + strncpy(principal.instance, instance, INST_SZ); + switch (aap_op) { + case NULL_KEY: + principal.key_low = 0; + principal.key_high = 0; + break; + case RANDOM_KEY: +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + case MASTER_KEY: + bcopy (master_key, new_key, sizeof (C_Block)); + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + } + principal.exp_date = 946702799; /* Happy new century */ + strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ); + principal.mod_date = time(0); + + tm = localtime(&principal.mod_date); + principal.attributes = 0; + principal.max_life = 255; + + principal.kdc_key_ver = 1; + principal.key_version = 1; + + strncpy(principal.mod_name, "db_creation", ANAME_SZ); + strncpy(principal.mod_instance, "", INST_SZ); + principal.old = 0; + + kerb_db_put_principal(&principal, 1); + + /* let's play it safe */ + bzero (new_key, sizeof (C_Block)); + bzero (&principal.key_low, 4); + bzero (&principal.key_high, 4); + return 0; +} diff --git a/eBones/kdb_util/Makefile b/eBones/kdb_util/Makefile new file mode 100644 index 0000000..b3513d6 --- /dev/null +++ b/eBones/kdb_util/Makefile @@ -0,0 +1,13 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:24:09 g89r4222 Exp $ + +PROG= kdb_util +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../kdb_edit \ + -I${.CURDIR}/../include +SRCS= kdb_util.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kdb_util/kdb_util.8 b/eBones/kdb_util/kdb_util.8 new file mode 100644 index 0000000..30a3b9f --- /dev/null +++ b/eBones/kdb_util/kdb_util.8 @@ -0,0 +1,64 @@ +.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $ +.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_util \- Kerberos key distribution center database utility +.SH SYNOPSIS +kdb_util +.B operation filename +.SH DESCRIPTION +.I kdb_util +allows the Kerberos key distribution center (KDC) database administrator to +perform utility functions on the database. +.PP +.I Operation +must be one of the following: +.TP 10n +.I load +initializes the KDC database with the records described by the +text contained in the file +.IR filename . +Any existing database is overwritten. +.TP +.I dump +dumps the KDC database into a text representation in the file +.IR filename . +.TP +.I slave_dump +performs a database dump like the +.I dump +operation, and additionally creates a semaphore file signalling the +propagation software that an update is available for distribution to +slave KDC databases. +.TP +.I new_master_key +prompts for the old and new master key strings, and then dumps the KDC +database into a text representation in the file +.IR filename . +The keys in the text representation are encrypted in the new master key. +.TP +.I convert_old_db +prompts for the master key string, and then dumps the KDC database into +a text representation in the file +.IR filename . +The existing database is assumed to be encrypted using the old format +(encrypted by the key schedule of the master key); the dumped database +is encrypted using the new format (encrypted directly with master key). +.PP +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +.IR filename .ok +semaphore file created by +.IR slave_dump. diff --git a/eBones/kdb_util/kdb_util.c b/eBones/kdb_util/kdb_util.c new file mode 100644 index 0000000..8465b5b --- /dev/null +++ b/eBones/kdb_util/kdb_util.c @@ -0,0 +1,506 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Kerberos database manipulation utility. This program allows you to + * dump a kerberos database to an ascii readable file and load this + * file into the database. Read locking of the database is done during a + * dump operation. NO LOCKING is done during a load operation. Loads + * should happen with other processes shutdown. + * + * Written July 9, 1987 by Jeffrey I. Schiller + * + * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $ + * $Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "time.h" +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <sys/file.h> +#include <krb_db.h> + +#define TRUE 1 + +Principal aprinc; + +static des_cblock master_key, new_master_key; +static des_key_schedule master_key_schedule, new_master_key_schedule; + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +extern long kdb_get_master_key(), kdb_verify_master_key(); +extern char *malloc(); +extern int errno; + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + FILE *file; + enum { + OP_LOAD, + OP_DUMP, + OP_SLAVE_DUMP, + OP_NEW_MASTER, + OP_CONVERT_OLD_DB, + } op; + char *file_name; + char *prog = argv[0]; + char *db_name; + + progname = prog; + + if (argc != 3 && argc != 4) { + fprintf(stderr, "Usage: %s operation file-name [database name].\n", + argv[0]); + exit(1); + } + if (argc == 3) + db_name = DBM_FILE; + else + db_name = argv[3]; + + if (kerb_db_set_name (db_name) != 0) { + perror("Can't open database"); + exit(1); + } + + if (!strcmp(argv[1], "load")) + op = OP_LOAD; + else if (!strcmp(argv[1], "dump")) + op = OP_DUMP; + else if (!strcmp(argv[1], "slave_dump")) + op = OP_SLAVE_DUMP; + else if (!strcmp(argv[1], "new_master_key")) + op = OP_NEW_MASTER; + else if (!strcmp(argv[1], "convert_old_db")) + op = OP_CONVERT_OLD_DB; + else { + fprintf(stderr, + "%s: %s is an invalid operation.\n", prog, argv[1]); + fprintf(stderr, + "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]); + fprintf(stderr, + "\"load\", \"new_master_key\", and \"convert_old_db\".\n"); + exit(1); + } + + file_name = argv[2]; + file = fopen(file_name, op == OP_LOAD ? "r" : "w"); + if (file == NULL) { + fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]); + (void) fflush(stderr); + perror("open"); + exit(1); + } + + switch (op) { + case OP_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + break; + case OP_SLAVE_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + update_ok_file (file_name); + break; + case OP_LOAD: + load_db (db_name, file); + break; + case OP_NEW_MASTER: + convert_new_master_key (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + case OP_CONVERT_OLD_DB: + convert_old_format_db (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + } + exit(0); + } + +clear_secrets () +{ + bzero((char *)master_key, sizeof (des_cblock)); + bzero((char *)master_key_schedule, sizeof (Key_schedule)); + bzero((char *)new_master_key, sizeof (des_cblock)); + bzero((char *)new_master_key_schedule, sizeof (Key_schedule)); +} + +/* cv_key is a procedure which takes a principle and changes its key, + either for a new method of encrypting the keys, or a new master key. + if cv_key is null no transformation of key is done (other than net byte + order). */ + +struct callback_args { + void (*cv_key)(); + FILE *output_file; +}; + +static int dump_db_1(arg, principal) + char *arg; + Principal *principal; +{ /* replace null strings with "*" */ + struct callback_args *a = (struct callback_args *)arg; + + if (principal->instance[0] == '\0') { + principal->instance[0] = '*'; + principal->instance[1] = '\0'; + } + if (principal->mod_name[0] == '\0') { + principal->mod_name[0] = '*'; + principal->mod_name[1] = '\0'; + } + if (principal->mod_instance[0] == '\0') { + principal->mod_instance[0] = '*'; + principal->mod_instance[1] = '\0'; + } + if (a->cv_key != NULL) { + (*a->cv_key) (principal); + } + fprintf(a->output_file, "%s %s %d %d %d %d %x %x", + principal->name, + principal->instance, + principal->max_life, + principal->kdc_key_ver, + principal->key_version, + principal->attributes, + htonl (principal->key_low), + htonl (principal->key_high)); + print_time(a->output_file, principal->exp_date); + print_time(a->output_file, principal->mod_date); + fprintf(a->output_file, " %s %s\n", + principal->mod_name, + principal->mod_instance); + return 0; +} + +dump_db (db_file, output_file, cv_key) + char *db_file; + FILE *output_file; + void (*cv_key)(); +{ + struct callback_args a; + + a.cv_key = cv_key; + a.output_file = output_file; + + kerb_db_iterate (dump_db_1, (char *)&a); + return fflush(output_file); +} + +load_db (db_file, input_file) + char *db_file; + FILE *input_file; +{ + char exp_date_str[50]; + char mod_date_str[50]; + int temp1, temp2, temp3; + long time_explode(); + int code; + char *temp_db_file; + temp1 = strlen(db_file+2); + temp_db_file = malloc (temp1); + strcpy(temp_db_file, db_file); + strcat(temp_db_file, "~"); + + /* Create the database */ + if ((code = kerb_db_create(temp_db_file)) != 0) { + fprintf(stderr, "Couldn't create temp database %s: %s\n", + temp_db_file, sys_errlist[code]); + exit(1); + } + kerb_db_set_name(temp_db_file); + for (;;) { /* explicit break on eof from fscanf */ + bzero((char *)&aprinc, sizeof(aprinc)); + if (fscanf(input_file, + "%s %s %d %d %d %hd %x %x %s %s %s %s\n", + aprinc.name, + aprinc.instance, + &temp1, + &temp2, + &temp3, + &aprinc.attributes, + &aprinc.key_low, + &aprinc.key_high, + exp_date_str, + mod_date_str, + aprinc.mod_name, + aprinc.mod_instance) == EOF) + break; + aprinc.key_low = ntohl (aprinc.key_low); + aprinc.key_high = ntohl (aprinc.key_high); + aprinc.max_life = (unsigned char) temp1; + aprinc.kdc_key_ver = (unsigned char) temp2; + aprinc.key_version = (unsigned char) temp3; + aprinc.exp_date = time_explode(exp_date_str); + aprinc.mod_date = time_explode(mod_date_str); + if (aprinc.instance[0] == '*') + aprinc.instance[0] = '\0'; + if (aprinc.mod_name[0] == '*') + aprinc.mod_name[0] = '\0'; + if (aprinc.mod_instance[0] == '*') + aprinc.mod_instance[0] = '\0'; + if (kerb_db_put_principal(&aprinc, 1) != 1) { + fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n", + aprinc.name, aprinc.instance, + sys_errlist[errno]); + exit(1); + }; + } + if ((code = kerb_db_rename(temp_db_file, db_file)) != 0) + perror("database rename failed"); + (void) fclose(input_file); + free(temp_db_file); +} + +print_time(file, timeval) + FILE *file; + unsigned long timeval; +{ + struct tm *tm; + struct tm *gmtime(); + tm = gmtime((long *)&timeval); + fprintf(file, " %04d%02d%02d%02d%02d", + tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min); +} + +/*ARGSUSED*/ +update_ok_file (file_name) + char *file_name; +{ + /* handle slave locking/failure stuff */ + char *file_ok; + int fd; + static char ok[]=".dump_ok"; + + if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1)) + == NULL) { + fprintf(stderr, "kdb_util: out of memory.\n"); + (void) fflush (stderr); + perror ("malloc"); + exit (1); + } + strcpy(file_ok, file_name); + strcat(file_ok, ok); + if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) { + fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok); + perror(""); + (void) fflush (stderr); + exit (1); + } + free(file_ok); + close(fd); +} + +void +convert_key_new_master (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + /* move current key to des_cblock for encryption, special case master key + since that's changing */ + if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) && + (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) { + bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock)); + (p->key_version)++; + } else { + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4); + kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT); + } + + kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ + + (p->kdc_key_ver)++; +} + +convert_new_master_key (db_file, out) + char *db_file; + FILE *out; +{ + + printf ("\n\nEnter the CURRENT master key."); + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets (); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets (); + exit (-1); + } + + printf ("\n\nNow enter the NEW master key. Do not forget it!!"); + if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get new master key.\n"); + clear_secrets (); + exit (-1); + } + + dump_db (db_file, out, convert_key_new_master); +} + +void +convert_key_old_db (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4); + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key, + (long)sizeof(des_cblock),master_key_schedule, + (des_cblock *)master_key_schedule,DECRYPT); +#endif + + /* make new key, new style */ + kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ +} + +convert_old_format_db (db_file, out) + char *db_file; + FILE *out; +{ + des_cblock key_from_db; + Principal principal_data[1]; + int n, more; + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets(); + exit (-1); + } + + /* can't call kdb_verify_master_key because this is an old style db */ + /* lookup the master key version */ + n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data, + 1 /* only one please */, &more); + if ((n != 1) || more) { + fprintf(stderr, "verify_master_key: ", + "Kerberos error on master key lookup, %d found.\n", + n); + exit (-1); + } + + /* set up the master key */ + fprintf(stderr, "Current Kerberos master key version is %d.\n", + principal_data[0].kdc_key_ver); + + /* + * now use the master key to decrypt (old style) the key in the db, had better + * be the same! + */ + bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4); + bcopy((char *)&principal_data[0].key_high, + (char *)(((long *) key_from_db) + 1), 4); +#ifndef NOENCRYPTION + des_pcbc_encrypt(key_from_db,key_from_db,(long)sizeof(key_from_db), + master_key_schedule,(des_cblock *)master_key_schedule,DECRYPT); +#endif + /* the decrypted database key had better equal the master key */ + n = bcmp((char *) master_key, (char *) key_from_db, + sizeof(master_key)); + bzero((char *)key_from_db, sizeof(key_from_db)); + + if (n) { + fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, "); + fprintf(stderr, "does not match database.\n"); + exit (-1); + } + + fprintf(stderr, "Master key verified.\n"); + (void) fflush(stderr); + + dump_db (db_file, out, convert_key_old_db); +} + +long +time_explode(cp) +register char *cp; +{ + char wbuf[5]; + struct tm tp; + long maketime(); + int local; + + zaptime(&tp); /* clear out the struct */ + + if (strlen(cp) > 10) { /* new format */ + (void) strncpy(wbuf, cp, 4); + wbuf[4] = 0; + tp.tm_year = atoi(wbuf); + cp += 4; /* step over the year */ + local = 0; /* GMT */ + } else { /* old format: local time, + year is 2 digits, assuming 19xx */ + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_year = 1900 + atoi(wbuf); + local = 1; /* local */ + } + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_mon = atoi(wbuf)-1; + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_mday = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_hour = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_min = atoi(wbuf); + + + return(maketime(&tp, local)); +} diff --git a/eBones/kdestroy/Makefile b/eBones/kdestroy/Makefile new file mode 100644 index 0000000..5947028 --- /dev/null +++ b/eBones/kdestroy/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:15 g89r4222 Exp $ + +PROG= kdestroy +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42 +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kdestroy/kdestroy.1 b/eBones/kdestroy/kdestroy.1 new file mode 100644 index 0000000..7099353 --- /dev/null +++ b/eBones/kdestroy/kdestroy.1 @@ -0,0 +1,81 @@ +.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $ +.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdestroy \- destroy Kerberos tickets +.SH SYNOPSIS +.B kdestroy +[ +.B \-f +] +[ +.B \-q +] +.SH DESCRIPTION +The +.I kdestroy +utility destroys the user's active +Kerberos +authorization tickets by writing zeros to the file that contains them. +If the ticket file does not exist, +.I kdestroy +displays a message to that effect. +.PP +After overwriting the file, +.I kdestroy +removes the file from the system. +The utility +displays a message indicating the success or failure of the +operation. +If +.I kdestroy +is unable to destroy the ticket file, +the utility will warn you by making your terminal beep. +.PP +In the Athena workstation environment, +the +.I toehold +service automatically destroys your tickets when you +end a workstation session. +If your site does not provide a similar ticket-destroying mechanism, +you can place the +.I kdestroy +command in your +.I .logout +file so that your tickets are destroyed automatically +when you logout. +.PP +The options to +.I kdestroy +are as follows: +.TP 7 +.B \-f +.I kdestroy +runs without displaying the status message. +.TP +.B \-q +.I kdestroy +will not make your terminal beep if it fails to destroy the tickets. +.SH FILES +KRBTKFILE environment variable if set, otherwise +.br +/tmp/tkt[uid] +.SH SEE ALSO +kerberos(1), kinit(1), klist(1) +.SH BUGS +.PP +Only the tickets in the user's current ticket file are destroyed. +Separate ticket files are used to hold root instance and password +changing tickets. These files should probably be destroyed too, or +all of a user's tickets kept in a single ticket file. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena +.br +Bill Sommerfeld, MIT Project Athena diff --git a/eBones/kdestroy/kdestroy.c b/eBones/kdestroy/kdestroy.c new file mode 100644 index 0000000..f010fcd --- /dev/null +++ b/eBones/kdestroy/kdestroy.c @@ -0,0 +1,78 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This program causes Kerberos tickets to be destroyed. + * Options are: + * + * -q[uiet] - no bell even if tickets not destroyed + * -f[orce] - no message printed at all + * + * from: kdestroy.c,v 4.5 88/03/18 15:16:02 steiner Exp $ + * $Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <krb.h> +#ifdef BSD42 +#include <strings.h> +#endif BSD42 + + +static char *pname; + +static usage() +{ + fprintf(stderr, "Usage: %s [-f] [-q]\n", pname); + exit(1); +} + +main(argc, argv) + char *argv[]; +{ + int fflag=0, qflag=0, k_errno; + register char *cp; + + cp = rindex (argv[0], '/'); + if (cp == NULL) + pname = argv[0]; + else + pname = cp+1; + + if (argc > 2) + usage(); + else if (argc == 2) { + if (!strcmp(argv[1], "-f")) + ++fflag; + else if (!strcmp(argv[1], "-q")) + ++qflag; + else usage(); + } + + k_errno = dest_tkt(); + + if (fflag) { + if (k_errno != 0 && k_errno != RET_TKFIL) + exit(1); + else + exit(0); + } else { + if (k_errno == 0) + printf("Tickets destroyed.\n"); + else if (k_errno == RET_TKFIL) + fprintf(stderr, "No tickets to destroy.\n"); + else { + fprintf(stderr, "Tickets NOT destroyed.\n"); + if (!qflag) + fprintf(stderr, "\007"); + exit(1); + } + } + exit(0); +} diff --git a/eBones/kerberos/Makefile b/eBones/kerberos/Makefile new file mode 100644 index 0000000..7f36cf7 --- /dev/null +++ b/eBones/kerberos/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:22 g89r4222 Exp $ + +PROG= kerberos +SRCS= kerberos.c cr_err_reply.c +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kerberos/cr_err_reply.c b/eBones/kerberos/cr_err_reply.c new file mode 100644 index 0000000..585fd03 --- /dev/null +++ b/eBones/kerberos/cr_err_reply.c @@ -0,0 +1,95 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $ + * $Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/types.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +extern int req_act_vno; /* this is defined in the kerberos + * server code */ + +/* + * 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_long time_ws; /* Workstation time */ + u_long 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) req_act_vno; /* KRB_PROT_VERSION; */ + *t = (unsigned char) AUTH_MSG_ERR_REPLY; + *t |= HOST_BYTE_ORDER; + + /* 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/eBones/kerberos/kerberos.c b/eBones/kerberos/kerberos.c new file mode 100644 index 0000000..b980577 --- /dev/null +++ b/eBones/kerberos/kerberos.c @@ -0,0 +1,810 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $ + * $Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> +#include <ctype.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +struct sockaddr_in s_in = {AF_INET}; +int f; + +/* XXX several files in libkdb know about this */ +char *progname; + +static Key_schedule master_key_schedule; +static C_Block master_key; + +static struct timeval kerb_time; +static Principal a_name_data; /* for requesting user */ +static Principal s_name_data; /* for services requested */ +static C_Block session_key; +static C_Block user_key; +static C_Block service_key; +static u_char master_key_version; +static char k_instance[INST_SZ]; +static char log_text[128]; +static char *lt; +static int more; + +static int mflag; /* Are we invoked manually? */ +static int lflag; /* Have we set an alterate log file? */ +static char *log_file; /* name of alt. log file */ +static int nflag; /* don't check max age */ +static int rflag; /* alternate realm specified */ + +/* fields within the received request packet */ +static u_char req_msg_type; +static u_char req_version; +static char *req_name_ptr; +static char *req_inst_ptr; +static char *req_realm_ptr; +static u_char req_no_req; +static u_long req_time_ws; + +int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */ + +static char local_realm[REALM_SZ]; + +/* statistics */ +static long q_bytes; /* current bytes remaining in queue */ +static long q_n; /* how many consecutive non-zero + * q_bytes */ +static long max_q_bytes; +static long max_q_n; +static long n_auth_req; +static long n_appl_req; +static long n_packets; +static long n_user; +static long n_server; + +static long max_age = -1; +static long pause_int = -1; + +static void check_db_age(); +static void hang(); + +/* + * Print usage message and exit. + */ +static void usage() +{ + fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname, + " [-a max_age] [-l log_file] [-r realm]" + ," [database_pathname]" + ); + exit(1); +} + + +main(argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in from; + register int n; + int on = 1; + int child; + struct servent *sp; + int fromlen; + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + Principal *p; + int more, kerror; + C_Block key; + int c; + extern char *optarg; + extern int optind; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) { + switch(c) { + case 's': + /* + * Set parameters to slave server defaults. + */ + if (max_age == -1 && !nflag) + max_age = ONE_DAY; /* 24 hours */ + if (pause_int == -1) + pause_int = FIVE_MINUTES; /* 5 minutes */ + if (lflag == 0) { + log_file = KRBSLAVELOG; + lflag++; + } + break; + case 'n': + max_age = -1; /* don't check max age. */ + nflag++; + break; + case 'm': + mflag++; /* running manually; prompt for master key */ + break; + case 'p': + /* Set pause interval. */ + if (!isdigit(optarg[0])) + usage(); + pause_int = atoi(optarg); + if ((pause_int < 5) || (pause_int > ONE_HOUR)) { + fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n"); + usage(); + } + break; + case 'a': + /* Set max age. */ + if (!isdigit(optarg[0])) + usage(); + max_age = atoi(optarg); + if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) { + fprintf(stderr, "max_age must be between one hour and three days, in seconds\n"); + usage(); + } + break; + case 'l': + /* Set alternate log file */ + lflag++; + log_file = optarg; + break; + case 'r': + /* Set realm name */ + rflag++; + strcpy(local_realm, optarg); + break; + default: + usage(); + break; + } + } + + if (optind == (argc-1)) { + if (kerb_db_set_name(argv[optind]) != 0) { + fprintf(stderr, "Could not set alternate database name\n"); + exit(1); + } + optind++; + } + + if (optind != argc) + usage(); + + printf("Kerberos server starting\n"); + + if ((!nflag) && (max_age != -1)) + printf("\tMaximum database age: %d seconds\n", max_age); + if (pause_int != -1) + printf("\tSleep for %d seconds on error\n", pause_int); + else + printf("\tSleep forever on error\n"); + if (mflag) + printf("\tMaster key will be entered manually\n"); + + printf("\tLog file is %s\n", lflag ? log_file : KRBLOG); + + if (lflag) + kset_logfile(log_file); + + /* find our hostname, and use it as the instance */ + if (gethostname(k_instance, INST_SZ)) { + fprintf(stderr, "%s: gethostname error\n", progname); + exit(1); + } + + if ((sp = getservbyname("kerberos", "udp")) == 0) { + fprintf(stderr, "%s: udp/kerberos unknown service\n", progname); + exit(1); + } + s_in.sin_port = sp->s_port; + + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "%s: Can't open socket\n", progname); + exit(1); + } + if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname); + + if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) { + fprintf(stderr, "%s: Can't bind socket\n", progname); + exit(1); + } + /* do all the database and cache inits */ + if (n = kerb_init()) { + if (mflag) { + printf("Kerberos db and cache init "); + printf("failed = %d ...exiting\n", n); + exit(-1); + } else { + klog(L_KRB_PERR, + "Kerberos db and cache init failed = %d ...exiting", n); + hang(); + } + } + + /* Make sure database isn't stale */ + check_db_age(); + + /* setup master key */ + if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) { + klog (L_KRB_PERR, "kerberos: couldn't get master key.\n"); + exit (-1); + } + kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout); + if (kerror < 0) { + klog (L_KRB_PERR, "Can't verify master key."); + bzero (master_key, sizeof (master_key)); + bzero (master_key_schedule, sizeof (master_key_schedule)); + exit (-1); + } + + master_key_version = (u_char) kerror; + + fprintf(stdout, "\nCurrent Kerberos master key version is %d\n", + master_key_version); + + if (!rflag) { + /* Look up our local realm */ + krb_get_lrealm(local_realm, 1); + } + fprintf(stdout, "Local realm: %s\n", local_realm); + fflush(stdout); + + if (set_tgtkey(local_realm)) { + /* Ticket granting service unknown */ + klog(L_KRB_PERR, "Ticket granting ticket service unknown"); + fprintf(stderr, "Ticket granting ticket service unknown\n"); + exit(1); + } + if (mflag) { + if ((child = fork()) != 0) { + printf("Kerberos started, PID=%d\n", child); + exit(0); + } + setup_disc(); + } + /* receive loop */ + for (;;) { + fromlen = S_AD_SZ; + n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from, + &fromlen); + if (n > 0) { + pkt->length = n; + pkt->mbz = 0; /* force zeros to catch runaway strings */ + /* see what is left in the input queue */ + ioctl(f, FIONREAD, &q_bytes); + gettimeofday(&kerb_time, NULL); + q_n++; + max_q_n = max(max_q_n, q_n); + n_packets++; + klog(L_NET_INFO, + "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d", + q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0); + max_q_bytes = max(max_q_bytes, q_bytes); + if (!q_bytes) + q_n = 0; /* reset consecutive packets */ + kerberos(&from, pkt); + } else + klog(L_NET_ERR, + "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0); + } +} + + +kerberos(client, pkt) + struct sockaddr_in *client; + KTEXT pkt; +{ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; + static KTEXT_ST ciph_st; + KTEXT ciph = &ciph_st; + static KTEXT_ST tk_st; + KTEXT tk = &tk_st; + static KTEXT_ST auth_st; + KTEXT auth = &auth_st; + AUTH_DAT ad_st; + AUTH_DAT *ad = &ad_st; + + + static struct in_addr client_host; + static int msg_byte_order; + static int swap_bytes; + static u_char k_flags; + char *p_name, *instance; + u_long lifetime; + int i; + C_Block key; + Key_schedule key_s; + char *ptr; + + + + ciph->length = 0; + + client_host = client->sin_addr; + + /* eval macros and correct the byte order and alignment as needed */ + req_version = pkt_version(pkt); /* 1 byte, version */ + req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */ + + req_act_vno = req_version; + + /* check packet version */ + if (req_version != KRB_PROT_VERSION) { + lt = klog(L_KRB_PERR, + "KRB prot version mismatch: KRB =%d request = %d", + KRB_PROT_VERSION, req_version, 0); + /* send an error reply */ + kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt); + return; + } + msg_byte_order = req_msg_type & 1; + + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + klog(L_KRB_PINFO, + "Prot version: %d, Byte order: %d, Message type: %d", + req_version, msg_byte_order, req_msg_type); + + switch (req_msg_type & ~1) { + + case AUTH_MSG_KDC_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + n_auth_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + + /* set up and correct for byte order and alignment */ + req_name_ptr = (char *) pkt_a_name(pkt); + req_inst_ptr = (char *) pkt_a_inst(pkt); + req_realm_ptr = (char *) pkt_a_realm(pkt); + bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws)); + /* time has to be diddled */ + if (swap_bytes) { + swap_u_long(req_time_ws); + } + ptr = (char *) pkt_time_ws(pkt) + 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + rpkt = &rpkt_st; + klog(L_INI_REQ, + "Initial ticket request Host: %s User: \"%s\" \"%s\"", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + + if (i = check_princ(req_name_ptr, req_inst_ptr, 0, + &a_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + tk->length = 0; /* init */ + if (strcmp(service, "krbtgt")) + klog(L_NTGT_INTK, + "INITIAL request from %s.%s for %s.%s", + req_name_ptr, req_inst_ptr, service, instance, 0); + /* this does all the checking */ + if (i = check_princ(service, instance, lifetime, + &s_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, ((u_long) s_name_data.max_life)); + lifetime = min(lifetime, ((u_long) a_name_data.max_life)); + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + krb_create_ticket(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + /* + * get the user's key, unseal it from the server's key, and + * use it to seal the cipher + */ + + /* a_name_data.key_low a_name_data.key_high */ + bcopy(&a_name_data.key_low, key, 4); + bcopy(&a_name_data.key_high, ((long *) key) + 1, 4); + + /* unseal the a_name key from the master key */ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + + create_ciph(ciph, session_key, s_name_data.name, + s_name_data.instance, local_realm, lifetime, + s_name_data.key_version, tk, kerb_time.tv_sec, key); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(key, sizeof(key)); + + + + /* always send a reply packet */ + rpkt = create_auth_reply(req_name_ptr, req_inst_ptr, + req_realm_ptr, req_time_ws, 0, a_name_data.exp_date, + a_name_data.key_version, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&a_name_data, sizeof(a_name_data)); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + case AUTH_MSG_APPL_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + char tktrlm[REALM_SZ]; + + n_appl_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + auth->length = 4 + strlen(pkt->dat + 3); + auth->length += (int) *(pkt->dat + auth->length) + + (int) *(pkt->dat + auth->length + 1) + 2; + + bcopy(pkt->dat, auth->dat, auth->length); + + strncpy(tktrlm, auth->dat + 3, REALM_SZ); + if (set_tgtkey(tktrlm)) { + lt = klog(L_ERR_UNK, + "FAILED realm %s unknown. Host: %s ", + tktrlm, inet_ntoa(client_host)); + kerb_err_reply(client, pkt, kerno, lt); + return; + } + kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, + ad, 0); + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", + inet_ntoa(client_host), krb_err_txt[kerno]); + kerb_err_reply(client, pkt, kerno, "krb_rd_req failed"); + return; + } + ptr = (char *) pkt->dat + auth->length; + + bcopy(ptr, &time_ws, 4); + ptr += 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s", + ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host), + service, instance, 0); + + if (strcmp(ad->prealm, tktrlm)) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't hop realms"); + return; + } + if (!strcmp(service, "changepw")) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't authorize password changed based on TGT"); + return; + } + kerno = check_princ(service, instance, req_life, + &s_name_data); + if (kerno) { + kerb_err_reply(client, pkt, kerno, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, + (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300))); + lifetime = min(lifetime, ((u_long) s_name_data.max_life)); + + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + + krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, + ad->prealm, client_host, + session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + create_ciph(ciph, session_key, service, instance, + local_realm, + lifetime, s_name_data.key_version, tk, + kerb_time.tv_sec, ad->session); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(ad->session, sizeof(ad->session)); + + rpkt = create_auth_reply(ad->pname, ad->pinst, + ad->prealm, time_ws, + 0, 0, 0, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + + +#ifdef notdef_DIE + case AUTH_MSG_DIE: + { + lt = klog(L_DEATH_REQ, + "Host: %s User: \"%s\" \"%s\" Kerberos killed", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + exit(0); + } +#endif notdef_DIE + + default: + { + lt = klog(L_KRB_PERR, + "Unknown message type: %d from %s port %u", + req_msg_type, inet_ntoa(client_host), + ntohs(client->sin_port)); + break; + } + } +} + + +/* + * setup_disc + * + * disconnect all descriptors, remove ourself from the process + * group that spawned us. + */ + +setup_disc() +{ + + int s; + + for (s = 0; s < 3; s++) { + (void) close(s); + } + + (void) open("/dev/null", 0); + (void) dup2(0, 1); + (void) dup2(0, 2); + + s = open("/dev/tty", 2); + + if (s >= 0) { + ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); + (void) close(s); + } + (void) chdir("/tmp"); + return; +} + + +/* + * kerb_er_reply creates an error reply packet and sends it to the + * client. + */ + +kerb_err_reply(client, pkt, err, string) + struct sockaddr_in *client; + KTEXT pkt; + long err; + char *string; + +{ + static KTEXT_ST e_pkt_st; + KTEXT e_pkt = &e_pkt_st; + static char e_msg[128]; + + strcpy(e_msg, "\nKerberos error -- "); + strcat(e_msg, string); + cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, + req_time_ws, err, e_msg); + sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + +} + +/* + * Make sure that database isn't stale. + * + * Exit if it is; we don't want to tell lies. + */ + +static void check_db_age() +{ + long age; + + if (max_age != -1) { + /* Requires existance of kerb_get_db_age() */ + gettimeofday(&kerb_time, 0); + age = kerb_get_db_age(); + if (age == 0) { + klog(L_KRB_PERR, "Database currently being updated!"); + hang(); + } + if ((age + max_age) < kerb_time.tv_sec) { + klog(L_KRB_PERR, "Database out of date!"); + hang(); + /* NOTREACHED */ + } + } +} + +check_princ(p_name, instance, lifetime, p) + char *p_name; + char *instance; + unsigned lifetime; + + Principal *p; +{ + static int n; + static int more; + long trans; + + n = kerb_get_principal(p_name, instance, p, 1, &more); + klog(L_ALL_REQ, + "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", + p_name, instance, lifetime, n, 0); + + if (n < 0) { + lt = klog(L_KRB_PERR, "Database unavailable!"); + hang(); + } + + /* + * if more than one p_name, pick one, randomly create a session key, + * compute maximum lifetime, lookup authorizations if applicable, + * and stuff into cipher. + */ + if (n == 0) { + /* service unknown, log error, skip to next request */ + lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_PRINCIPAL_UNKNOWN; + } + if (more) { + /* not unique, log error */ + lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"", + p_name, instance, 0); + return KERB_ERR_PRINCIPAL_NOT_UNIQUE; + } + /* If the user's key is null, we want to return an error */ + if ((p->key_low == 0) && (p->key_high == 0)) { + /* User has a null key */ + lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_NULL_KEY; + } + if (master_key_version != p->kdc_key_ver) { + /* log error reply */ + lt = klog(L_ERR_MKV, + "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d", + master_key_version, p->name, p->instance, p->kdc_key_ver, + 0); + return KERB_ERR_NAME_MAST_KEY_VER; + } + /* make sure the service hasn't expired */ + if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) { + /* service did expire, log it */ + lt = klog(L_ERR_SEXP, + "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance, + stime(&(p->exp_date)), 0); + return KERB_ERR_NAME_EXP; + } + /* ok is zero */ + return 0; +} + + +/* Set the key for krb_rd_req so we can check tgt */ +set_tgtkey(r) + char *r; /* Realm for desired key */ +{ + int n; + static char lastrealm[REALM_SZ]; + Principal p_st; + Principal *p = &p_st; + C_Block key; + + if (!strcmp(lastrealm, r)) + return (KSUCCESS); + + log("Getting key for %s", r); + + n = kerb_get_principal("krbtgt", r, p, 1, &more); + if (n == 0) + return (KFAILURE); + + /* unseal tgt key from master key */ + bcopy(&p->key_low, key, 4); + bcopy(&p->key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + krb_set_key(key, 0); + strcpy(lastrealm, r); + return (KSUCCESS); +} + +static void +hang() +{ + if (pause_int == -1) { + klog(L_KRB_PERR, "Kerberos will pause so as not to loop init"); + for (;;) + pause(); + } else { + char buf[256]; + sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int); + klog(L_KRB_PERR, buf); + sleep(pause_int); + klog(L_KRB_PERR, "Do svedania....\n"); + exit(1); + } +} diff --git a/eBones/kinit/Makefile b/eBones/kinit/Makefile new file mode 100644 index 0000000..e616f42 --- /dev/null +++ b/eBones/kinit/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:31 g89r4222 Exp $ + +PROG= kinit +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42 +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kinit/kinit.1 b/eBones/kinit/kinit.1 new file mode 100644 index 0000000..f9a97a7 --- /dev/null +++ b/eBones/kinit/kinit.1 @@ -0,0 +1,133 @@ +.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $ +.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kinit \- Kerberos login utility +.SH SYNOPSIS +.B kinit +[ +.B \-irvl +] +.SH DESCRIPTION +The +.I kinit +command is used to login to the +Kerberos +authentication and authorization system. +Note that only registered +Kerberos +users can use the +Kerberos +system. +For information about registering as a +Kerberos +user, +see the +.I kerberos(1) +manual page. +.PP +If you are logged in to a workstation that is running the +.I toehold +service, +you do not have to use +.I kinit. +The +.I toehold +login procedure will log you into +Kerberos +automatically. +You will need to use +.I kinit +only in those situations in which +your original tickets have expired. +(Tickets expire in about a day.) +Note as well that +.I toehold +will automatically destroy your tickets when you logout from the workstation. +.PP +When you use +.I kinit +without options, +the utility +prompts for your username and Kerberos password, +and tries to authenticate your login with the local +Kerberos +server. +.PP +If +Kerberos +authenticates the login attempt, +.I kinit +retrieves your initial ticket and puts it in the ticket file specified by +your KRBTKFILE environment variable. +If this variable is undefined, +your ticket will be stored in the +.IR /tmp +directory, +in the file +.I tktuid , +where +.I uid +specifies your user identification number. +.PP +If you have logged in to +Kerberos +without the benefit of the workstation +.I toehold +system, +make sure you use the +.I kdestroy +command to destroy any active tickets before you end your login session. +You may want to put the +.I kdestroy +command in your +.I \.logout +file so that your tickets will be destroyed automatically when you logout. +.PP +The options to +.I kinit +are as follows: +.TP 7 +.B \-i +.I kinit +prompts you for a +Kerberos +instance. +.TP +.B \-r +.I kinit +prompts you for a +Kerberos +realm. +This option lets you authenticate yourself with a remote +Kerberos +server. +.TP +.B \-v +Verbose mode. +.I kinit +prints the name of the ticket file used, and +a status message indicating the success or failure of +your login attempt. +.TP +.B \-l +.I kinit +prompts you for a ticket lifetime in minutes. Due to protocol +restrictions in Kerberos Version 4, this value must be between 5 and +1275 minutes. +.SH SEE ALSO +.PP +kerberos(1), kdestroy(1), klist(1), toehold(1) +.SH BUGS +The +.B \-r +option has not been fully implemented. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena diff --git a/eBones/kinit/kinit.c b/eBones/kinit/kinit.c new file mode 100644 index 0000000..94ce0fe --- /dev/null +++ b/eBones/kinit/kinit.c @@ -0,0 +1,214 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Routine to initialize user to Kerberos. Prompts optionally for + * user, instance and realm. Authenticates user and gets a ticket + * for the Kerberos ticket-granting service for future use. + * + * Options are: + * + * -i[instance] + * -r[realm] + * -v[erbose] + * -l[ifetime] + * + * from: kinit.c,v 4.12 90/03/20 16:11:15 jon Exp $ + * $Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <pwd.h> +#include <krb.h> + +#ifndef ORGANIZATION +#define ORGANIZATION "MIT Project Athena" +#endif /*ORGANIZATION*/ + +#ifdef PC +#define LEN 64 /* just guessing */ +#endif PC + +#if defined(BSD42) || defined(__FreeBSD__) +#include <strings.h> +#include <sys/param.h> +#if defined(ultrix) || defined(sun) +#define LEN 64 +#else +#define LEN MAXHOSTNAMELEN +#endif /* defined(ultrix) || defined(sun) */ +#endif /* BSD42 */ + +#define LIFE 96 /* lifetime of ticket in 5-minute units */ + +char *progname; + +void +get_input(s, size, stream) +char *s; +int size; +FILE *stream; +{ + char *p; + + if (fgets(s, size, stream) == NULL) + exit(1); + if ((p = index(s, '\n')) != NULL) + *p = '\0'; +} + +main(argc, argv) + char *argv[]; +{ + char aname[ANAME_SZ]; + char inst[INST_SZ]; + char realm[REALM_SZ]; + char buf[LEN]; + char *username = NULL; + int iflag, rflag, vflag, lflag, lifetime, k_errno; + register char *cp; + register i; + + *inst = *realm = '\0'; + iflag = rflag = vflag = lflag = 0; + lifetime = LIFE; + progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + while (--argc) { + if ((*++argv)[0] != '-') { + if (username) + usage(); + username = *argv; + continue; + } + for (i = 1; (*argv)[i] != '\0'; i++) + switch ((*argv)[i]) { + case 'i': /* Instance */ + ++iflag; + continue; + case 'r': /* Realm */ + ++rflag; + continue; + case 'v': /* Verbose */ + ++vflag; + continue; + case 'l': + ++lflag; + continue; + default: + usage(); + exit(1); + } + } + if (username && + (k_errno = kname_parse(aname, inst, realm, username)) + != KSUCCESS) { + fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]); + iflag = rflag = 1; + username = NULL; + } + if (k_gethostname(buf, LEN)) { + fprintf(stderr, "%s: k_gethostname failed\n", progname); + exit(1); + } + printf("%s (%s)\n", ORGANIZATION, buf); + if (username) { + printf("Kerberos Initialization for \"%s", aname); + if (*inst) + printf(".%s", inst); + if (*realm) + printf("@%s", realm); + printf("\"\n"); + } else { + if (iflag) { + printf("Kerberos Initialization\n"); + printf("Kerberos name: "); + get_input(aname, sizeof(aname), stdin); + } else { + int uid = getuid(); + char *getenv(); + struct passwd *pwd; + + /* default to current user name unless running as root */ + if (uid == 0 && (username = getenv("USER")) && + strcmp(username, "root") != 0) { + strncpy(aname, username, sizeof(aname)); + strncpy(inst, "root", sizeof(inst)); + } else { + pwd = getpwuid(uid); + + if (pwd == (struct passwd *) NULL) { + fprintf(stderr, "Unknown name for your uid\n"); + printf("Kerberos name: "); + gets(aname); + } else + strncpy(aname, pwd->pw_name, sizeof(aname)); + } + } + + if (!*aname) + exit(0); + if (!k_isname(aname)) { + fprintf(stderr, "%s: bad Kerberos name format\n", + progname); + exit(1); + } + } + /* optional instance */ + if (iflag) { + printf("Kerberos instance: "); + get_input(inst, sizeof(inst), stdin); + if (!k_isinst(inst)) { + fprintf(stderr, "%s: bad Kerberos instance format\n", + progname); + exit(1); + } + } + if (rflag) { + printf("Kerberos realm: "); + get_input(realm, sizeof(realm), stdin); + if (!k_isrealm(realm)) { + fprintf(stderr, "%s: bad Kerberos realm format\n", + progname); + exit(1); + } + } + if (lflag) { + printf("Kerberos ticket lifetime (minutes): "); + get_input(buf, sizeof(buf), stdin); + lifetime = atoi(buf); + if (lifetime < 5) + lifetime = 1; + else + lifetime /= 5; + /* This should be changed if the maximum ticket lifetime */ + /* changes */ + if (lifetime > 255) + lifetime = 255; + } + if (!*realm && krb_get_lrealm(realm, 1)) { + fprintf(stderr, "%s: krb_get_lrealm failed\n", progname); + exit(1); + } + k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm, + lifetime, 0); + if (vflag) { + printf("Kerberos realm %s:\n", realm); + printf("%s\n", krb_err_txt[k_errno]); + } else if (k_errno) { + fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]); + exit(1); + } +} + +usage() +{ + fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname); + exit(1); +} diff --git a/eBones/klist/Makefile b/eBones/klist/Makefile new file mode 100644 index 0000000..aa0d720 --- /dev/null +++ b/eBones/klist/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:37 g89r4222 Exp $ + +PROG= klist +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/klist/klist.1 b/eBones/klist/klist.1 new file mode 100644 index 0000000..a66e668 --- /dev/null +++ b/eBones/klist/klist.1 @@ -0,0 +1,84 @@ +.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $ +.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +klist \- list currently held Kerberos tickets +.SH SYNOPSIS +.B klist +[ +\fB\-s \fR|\fB \-t\fR +] [ +.B \-file +name ] [ +.B \-srvtab +] +.br +.SH DESCRIPTION +.I klist +prints the name of the tickets file and the +identity of the principal the tickets are for (as listed in the +tickets file), and +lists the principal names of all Kerberos tickets currently held by +the user, along with the issue and expire time for each authenticator. +Principal names are listed in the form +.I name.instance@realm, +with the '.' omitted if the instance is null, +and the '@' omitted if the realm is null. + +If given the +.B \-s +option, +.I klist +does not print the issue and expire times, the name of the tickets file, +or the identity of the principal. + +If given the +.B \-t +option, +.B klist +checks for the existence of a non-expired ticket-granting-ticket in the +ticket file. If one is present, it exits with status 0, else it exits +with status 1. No output is generated when this option is specified. + +If given the +.B \-file +option, the following argument is used as the ticket file. +Otherwise, if the +.B KRBTKFILE +environment variable is set, it is used. +If this environment variable +is not set, the file +.B /tmp/tkt[uid] +is used, where +.B uid +is the current user-id of the user. + +If given the +.B \-srvtab +option, the file is treated as a service key file, and the names of the +keys contained therein are printed. If no file is +specified with a +.B \-file +option, the default is +.IR /etc/srvtab . +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm +.TP +/tmp/tkt[uid] +as the default ticket file ([uid] is the decimal UID of the user). +.TP +/etc/srvtab +as the default service key file +.SH SEE ALSO +.PP +kerberos(1), kinit(1), kdestroy(1) +.SH BUGS +When reading a file as a service key file, very little sanity or error +checking is performed. diff --git a/eBones/klist/klist.c b/eBones/klist/klist.c new file mode 100644 index 0000000..4a95bc0 --- /dev/null +++ b/eBones/klist/klist.c @@ -0,0 +1,275 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Lists your current Kerberos tickets. + * Written by Bill Sommerfeld, MIT Project Athena. + * + * from: klist.c,v 4.15 89/08/30 11:19:16 jtkohl Exp $ + * $Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include <krb.h> +#include <prot.h> + +char *tkt_string(); +char *short_date(); +char *whoami; /* What was I invoked as?? */ +char *getenv(); + +extern char *krb_err_txt[]; + +/* ARGSUSED */ +main(argc, argv) + int argc; + char **argv; +{ + int long_form = 1; + int tgt_test = 0; + int do_srvtab = 0; + char *tkt_file = NULL; + char *cp; + + whoami = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + while (*(++argv)) { + if (!strcmp(*argv, "-s")) { + long_form = 0; + continue; + } + if (!strcmp(*argv, "-t")) { + tgt_test = 1; + long_form = 0; + continue; + } + if (!strcmp(*argv, "-l")) { /* now default */ + continue; + } + if (!strcmp(*argv, "-file")) { + if (*(++argv)) { + tkt_file = *argv; + continue; + } else + usage(); + } + if (!strcmp(*argv, "-srvtab")) { + if (tkt_file == NULL) /* if no other file spec'ed, + set file to default srvtab */ + tkt_file = KEYFILE; + do_srvtab = 1; + continue; + } + usage(); + } + + if (do_srvtab) + display_srvtab(tkt_file); + else + display_tktfile(tkt_file, tgt_test, long_form); + exit(0); +} + + +display_tktfile(file, tgt_test, long_form) +char *file; +int tgt_test, long_form; +{ + char pname[ANAME_SZ]; + char pinst[INST_SZ]; + char prealm[REALM_SZ]; + char buf1[20], buf2[20]; + int k_errno; + CREDENTIALS c; + int header = 1; + + if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL)) + file = TKT_FILE; + + if (long_form) + printf("Ticket file: %s\n", file); + + /* + * Since krb_get_tf_realm will return a ticket_file error, + * we will call tf_init and tf_close first to filter out + * things like no ticket file. Otherwise, the error that + * the user would see would be + * klist: can't find realm of ticket file: No ticket file (tf_util) + * instead of + * klist: No ticket file (tf_util) + */ + + /* Open ticket file */ + if (k_errno = tf_init(file, R_TKT_FIL)) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + /* Close ticket file */ + (void) tf_close(); + + /* + * We must find the realm of the ticket file here before calling + * tf_init because since the realm of the ticket file is not + * really stored in the principal section of the file, the + * routine we use must itself call tf_init and tf_close. + */ + if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) { + if (!tgt_test) + fprintf(stderr, "%s: can't find realm of ticket file: %s\n", + whoami, krb_err_txt[k_errno]); + exit(1); + } + + /* Open ticket file */ + if (k_errno = tf_init(file, R_TKT_FIL)) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + /* Get principal name and instance */ + if ((k_errno = tf_get_pname(pname)) || + (k_errno = tf_get_pinst(pinst))) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + + /* + * You may think that this is the obvious place to get the + * realm of the ticket file, but it can't be done here as the + * routine to do this must open the ticket file. This is why + * it was done before tf_init. + */ + + if (!tgt_test && long_form) + printf("Principal:\t%s%s%s%s%s\n\n", pname, + (pinst[0] ? "." : ""), pinst, + (prealm[0] ? "@" : ""), prealm); + while ((k_errno = tf_get_cred(&c)) == KSUCCESS) { + if (!tgt_test && long_form && header) { + printf("%-15s %-15s %s\n", + " Issued", " Expires", " Principal"); + header = 0; + } + if (tgt_test) { + c.issue_date += ((unsigned char) c.lifetime) * 5 * 60; + if (!strcmp(c.service, TICKET_GRANTING_TICKET) && + !strcmp(c.instance, prealm)) { + if (time(0) < c.issue_date) + exit(0); /* tgt hasn't expired */ + else + exit(1); /* has expired */ + } + continue; /* not a tgt */ + } + if (long_form) { + (void) strcpy(buf1, short_date(&c.issue_date)); + c.issue_date += ((unsigned char) c.lifetime) * 5 * 60; + (void) strcpy(buf2, short_date(&c.issue_date)); + printf("%s %s ", buf1, buf2); + } + printf("%s%s%s%s%s\n", + c.service, (c.instance[0] ? "." : ""), c.instance, + (c.realm[0] ? "@" : ""), c.realm); + } + if (tgt_test) + exit(1); /* no tgt found */ + if (header && long_form && k_errno == EOF) { + printf("No tickets in file.\n"); + } +} + +char * +short_date(dp) + long *dp; +{ + register char *cp; + extern char *ctime(); + cp = ctime(dp) + 4; + cp[15] = '\0'; + return (cp); +} + +usage() +{ + fprintf(stderr, + "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami); + exit(1); +} + +display_srvtab(file) +char *file; +{ + int stab; + char serv[SNAME_SZ]; + char inst[INST_SZ]; + char rlm[REALM_SZ]; + unsigned char key[8]; + unsigned char vno; + int count; + + printf("Server key file: %s\n", file); + + if ((stab = open(file, O_RDONLY, 0400)) < 0) { + perror(file); + exit(1); + } + printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm", + "Key Version"); + printf("------------------------------------------------------\n"); + + /* argh. getst doesn't return error codes, it silently fails */ + while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0) + && ((count = ok_getst(stab, inst, INST_SZ)) > 0) + && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) { + if (((count = read(stab,(char *) &vno,1)) != 1) || + ((count = read(stab,(char *) key,8)) != 8)) { + if (count < 0) + perror("reading from key file"); + else + fprintf(stderr, "key file truncated\n"); + exit(1); + } + printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno); + } + if (count < 0) + perror(file); + (void) close(stab); +} + +/* adapted from getst() in librkb */ +/* + * ok_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. ok_getst() returns the number of characters read, including + * the null terminator. + * + * If there is a read error, it returns -1 (like the read(2) system call) + */ + +ok_getst(fd, s, n) + int fd; + register char *s; +{ + register count = n; + int err; + while ((err = read(fd, s, 1)) > 0 && --count) + if (*s++ == '\0') + return (n - count); + if (err < 0) + return(-1); + *s = '\0'; + return (n - count); +} diff --git a/eBones/krb/Makefile b/eBones/krb/Makefile new file mode 100644 index 0000000..8336132 --- /dev/null +++ b/eBones/krb/Makefile @@ -0,0 +1,31 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.4 1994/09/07 16:10:17 g89r4222 Exp $ + +LIB= krb +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 +CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42 +SRCS= create_auth_reply.c create_ciph.c \ + create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \ + des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \ + get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \ + get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \ + get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \ + k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \ + krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \ + mk_priv.c mk_req.c mk_safe.c month_sname.c \ + netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \ + rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \ + save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \ + tkt_string.c util.c + +TDIR= ${.CURDIR}/.. +krb_err.et.c: ${COMPILE_ET} + (cd ${TDIR}/compile_et; make) + ${COMPILE_ET} ${.CURDIR}/krb_err.et -n + +beforedepend: krb_err.et.c + +CLEANFILES+= krb_err.et.c krb_err.h + +.include <bsd.lib.mk> diff --git a/eBones/krb/add_ticket.c b/eBones/krb/add_ticket.c new file mode 100644 index 0000000..cb79a18 --- /dev/null +++ b/eBones/krb/add_ticket.c @@ -0,0 +1,88 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $ + * $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is now obsolete. It used to be possible to request + * more than one ticket at a time from the authentication server, and + * it looks like this routine was used by the server to package the + * tickets to be returned to the client. + */ + +/* + * This routine adds a new ticket to the ciphertext to be returned to + * the client. The routine takes the ciphertext (which doesn't get + * encrypted till later), the number of the ticket (i.e. 1st, 2nd, + * etc) the session key which goes in the ticket and is sent back to + * the user, the lifetime for the ticket, the service name, the + * instance, the realm, the key version number, and the ticket itself. + * + * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on + * failure. On failure, which occurs when there isn't enough room + * for the ticket, a 0 length ticket is added. + * + * Notes: This routine must be called with successive values of n. + * i.e. the ticket must be added in order. The corresponding routine + * on the client side is extract ticket. + */ + +/* XXX they aren't all used; to avoid incompatible changes we will + * fool lint for the moment */ +/*ARGSUSED */ +add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket) + KTEXT cipher; /* Ciphertext info for ticket */ + char *sname; /* Service name */ + char *instance; /* Instance */ + int n; /* Relative position of this ticket */ + char *session; /* Session key for this tkt */ + int lifetime; /* Lifetime of this ticket */ + char *realm; /* Realm in which ticket is valid */ + int kvno; /* Key version number of service key */ + KTEXT ticket; /* The ticket itself */ +{ + + /* Note, the 42 is a temporary hack; it will have to be changed. */ + + /* Begin check of ticket length */ + if ((cipher->length + ticket->length + 4 + 42 + + (*(cipher->dat)+1-n)*(11+strlen(realm))) > + MAX_KTXT_LEN) { + bcopy(session,(char *)(cipher->dat+cipher->length),8); + *(cipher->dat+cipher->length+8) = (char) lifetime; + *(cipher->dat+cipher->length+9) = (char) kvno; + (void) strcpy((char *)(cipher->dat+cipher->length+10),realm); + cipher->length += 11 + strlen(realm); + *(cipher->dat+n) = 0; + return(KFAILURE); + } + /* End check of ticket length */ + + /* Add the session key, lifetime, kvno, ticket to the ciphertext */ + bcopy(session,(char *)(cipher->dat+cipher->length),8); + *(cipher->dat+cipher->length+8) = (char) lifetime; + *(cipher->dat+cipher->length+9) = (char) kvno; + (void) strcpy((char *)(cipher->dat+cipher->length+10),realm); + cipher->length += 11 + strlen(realm); + bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length), + ticket->length); + cipher->length += ticket->length; + + /* Set the ticket length at beginning of ciphertext */ + *(cipher->dat+n) = ticket->length; + return(KSUCCESS); +} diff --git a/eBones/krb/create_auth_reply.c b/eBones/krb/create_auth_reply.c new file mode 100644 index 0000000..e47d4df --- /dev/null +++ b/eBones/krb/create_auth_reply.c @@ -0,0 +1,116 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $ + * $Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is called by the Kerberos authentication server + * to create a reply to an authentication request. The routine + * takes the user's name, instance, and realm, the client's + * timestamp, the number of tickets, the user's key version + * number and the ciphertext containing the tickets themselves. + * It constructs a packet and returns a pointer to it. + * + * Notes: The packet returned by this routine is static. Thus, if you + * intend to keep the result beyond the next call to this routine, you + * must copy it elsewhere. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_KDC_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned char n number of tickets + * + * unsigned long x_date expiration date + * + * unsigned char kvno master key version + * + * short w_1 cipher length + * + * --- cipher->dat cipher data + */ + +KTEXT +create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher) + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long time_ws; /* Workstation time */ + int n; /* Number of tickets */ + unsigned long x_date; /* Principal's expiration date */ + int kvno; /* Principal's key version number */ + KTEXT cipher; /* Cipher text with tickets and + * session keys */ +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + unsigned char *v = pkt->dat; /* Prot vers number */ + unsigned char *t = (pkt->dat+1); /* Prot message type */ + short w_l; /* Cipher length */ + + /* Create fixed part of packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REPLY; + *t |= HOST_BYTE_ORDER; + + if (n != 0) + *v = 3; + + /* Add the basic info */ + (void) strcpy((char *) (pkt->dat+2), pname); + pkt->length = 3 + strlen(pname); + (void) strcpy((char *) (pkt->dat+pkt->length),pinst); + pkt->length += 1 + strlen(pinst); + (void) strcpy((char *) (pkt->dat+pkt->length),prealm); + pkt->length += 1 + strlen(prealm); + /* Workstation timestamp */ + bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (unsigned char) n; + /* Expiration date */ + bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + + /* Now send the ciphertext and info to help decode it */ + *(pkt->dat+(pkt->length)++) = (unsigned char) kvno; + w_l = (short) cipher->length; + bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2); + pkt->length += 2; + bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length), + cipher->length); + pkt->length += cipher->length; + + /* And return the packet */ + return pkt; +} diff --git a/eBones/krb/create_ciph.c b/eBones/krb/create_ciph.c new file mode 100644 index 0000000..c3bc0db --- /dev/null +++ b/eBones/krb/create_ciph.c @@ -0,0 +1,109 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $ + * $Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <strings.h> + +/* + * This routine is used by the authentication server to create + * a packet for its client, containing a ticket for the requested + * service (given in "tkt"), and some information about the ticket, + * + * Returns KSUCCESS no matter what. + * + * The length of the cipher is stored in c->length; the format of + * c->dat is as follows: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * + * 8 bytes session session key for client, service + * + * string service service name + * + * string instance service instance + * + * string realm KDC realm + * + * unsigned char life ticket lifetime + * + * unsigned char kvno service key version number + * + * unsigned char tkt->length length of following ticket + * + * data tkt->dat ticket for service + * + * 4 bytes kdc_time KDC's timestamp + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +create_ciph(c, session, service, instance, realm, life, kvno, tkt, + kdc_time, key) + KTEXT c; /* Text block to hold ciphertext */ + C_Block session; /* Session key to send to user */ + char *service; /* Service name on ticket */ + char *instance; /* Instance name on ticket */ + char *realm; /* Realm of this KDC */ + unsigned long life; /* Lifetime of the ticket */ + int kvno; /* Key version number for service */ + KTEXT tkt; /* The ticket for the service */ + unsigned long kdc_time; /* KDC time */ + C_Block key; /* Key to encrypt ciphertext with */ +{ + char *ptr; + Key_schedule key_s; + + ptr = (char *) c->dat; + + bcopy((char *) session, ptr, 8); + ptr += 8; + + (void) strcpy(ptr,service); + ptr += strlen(service) + 1; + + (void) strcpy(ptr,instance); + ptr += strlen(instance) + 1; + + (void) strcpy(ptr,realm); + ptr += strlen(realm) + 1; + + *(ptr++) = (unsigned char) life; + *(ptr++) = (unsigned char) kvno; + *(ptr++) = (unsigned char) tkt->length; + + bcopy((char *)(tkt->dat),ptr,tkt->length); + ptr += tkt->length; + + bcopy((char *) &kdc_time,ptr,4); + ptr += 4; + + /* guarantee null padded encrypted data to multiple of 8 bytes */ + bzero(ptr, 7); + + c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8; + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s, + key,ENCRYPT); +#endif /* NOENCRYPTION */ + + return(KSUCCESS); +} diff --git a/eBones/krb/create_death_packet.c b/eBones/krb/create_death_packet.c new file mode 100644 index 0000000..f747d6b --- /dev/null +++ b/eBones/krb/create_death_packet.c @@ -0,0 +1,63 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $ + * $Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine creates a packet to type AUTH_MSG_DIE which is sent to + * the Kerberos server to make it shut down. It is used only in the + * development environment. + * + * It takes a string "a_name" which is sent in the packet. A pointer + * to the packet is returned. + * + * The format of the killer packet is: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_DIE message type + * + * [least significant HOST_BYTE_ORDER byte order of sender + * bit of above field] + * + * string a_name presumably, name of + * principal sending killer + * packet + */ + +#ifdef DEBUG +KTEXT +krb_create_death_packet(a_name) + char *a_name; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + + unsigned char *v = pkt->dat; + unsigned char *t = (pkt->dat+1); + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_DIE; + *t |= HOST_BYTE_ORDER; + (void) strcpy((char *) (pkt->dat+2),a_name); + pkt->length = 3 + strlen(a_name); + return pkt; +} +#endif /* DEBUG */ diff --git a/eBones/krb/create_ticket.c b/eBones/krb/create_ticket.c new file mode 100644 index 0000000..984d8e9 --- /dev/null +++ b/eBones/krb/create_ticket.c @@ -0,0 +1,130 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $ + * $Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * Create ticket takes as arguments information that should be in a + * ticket, and the KTEXT object in which the ticket should be + * constructed. It then constructs a ticket and returns, leaving the + * newly created ticket in tkt. + * The length of the ticket is a multiple of + * eight bytes and is in tkt->length. + * + * If the ticket is too long, the ticket will contain nulls. + * The return value of the routine is undefined. + * + * The corresponding routine to extract information from a ticket it + * decomp_ticket. When changes are made to this routine, the + * corresponding changes should also be made to that file. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * tkt->length length of ticket (multiple of 8 bytes) + * + * tkt->dat: + * + * unsigned char flags namely, HOST_BYTE_ORDER + * + * string pname client's name + * + * string pinstance client's instance + * + * string prealm client's realm + * + * 4 bytes paddress client's address + * + * 8 bytes session session key + * + * 1 byte life ticket lifetime + * + * 4 bytes time_sec KDC timestamp + * + * string sname service's name + * + * string sinstance service's instance + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + C_Block key; /* Service's secret key */ +{ + Key_schedule key_s; + register char *data; /* running index into ticket */ + + tkt->length = 0; /* Clear previous data */ + flags |= HOST_BYTE_ORDER; /* ticket byte order */ + bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags)); + data = ((char *)tkt->dat) + sizeof(flags); + (void) strcpy(data, pname); + data += 1 + strlen(pname); + (void) strcpy(data, pinstance); + data += 1 + strlen(pinstance); + (void) strcpy(data, prealm); + data += 1 + strlen(prealm); + bcopy((char *) &paddress, data, 4); + data += 4; + + bcopy((char *) session, data, 8); + data += 8; + *(data++) = (char) life; + /* issue time */ + bcopy((char *) &time_sec, data, 4); + data += 4; + (void) strcpy(data, sname); + data += 1 + strlen(sname); + (void) strcpy(data, sinstance); + data += 1 + strlen(sinstance); + + /* guarantee null padded ticket to multiple of 8 bytes */ + bzero(data, 7); + tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8; + + /* Check length of ticket */ + if (tkt->length > (sizeof(KTEXT_ST) - 7)) { + bzero(tkt->dat, tkt->length); + tkt->length = 0; + return KFAILURE /* XXX */; + } + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length, + key_s,key,ENCRYPT); +#endif + return 0; +} diff --git a/eBones/krb/debug_decl.c b/eBones/krb/debug_decl.c new file mode 100644 index 0000000..1a0f6df --- /dev/null +++ b/eBones/krb/debug_decl.c @@ -0,0 +1,18 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $ + * $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $"; +#endif lint + +/* Declare global debugging variables. */ + +int krb_ap_req_debug = 0; +int krb_debug = 0; diff --git a/eBones/krb/decomp_ticket.c b/eBones/krb/decomp_ticket.c new file mode 100644 index 0000000..181864c --- /dev/null +++ b/eBones/krb/decomp_ticket.c @@ -0,0 +1,123 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $ + * $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine takes a ticket and pointers to the variables that + * should be filled in based on the information in the ticket. It + * fills in values for its arguments. + * + * Note: if the client realm field in the ticket is the null string, + * then the "prealm" variable is filled in with the local realm (as + * defined by KRB_REALM). + * + * If the ticket byte order is different than the host's byte order + * (as indicated by the byte order bit of the "flags" field), then + * the KDC timestamp "time_sec" is byte-swapped. The other fields + * potentially affected by byte order, "paddress" and "session" are + * not byte-swapped. + * + * The routine returns KFAILURE if any of the "pname", "pinstance", + * or "prealm" fields is too big, otherwise it returns KSUCCESS. + * + * The corresponding routine to generate tickets is create_ticket. + * When changes are made to this routine, the corresponding changes + * should also be made to that file. + * + * See create_ticket.c for the format of the ticket packet. + */ + +decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned long *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned long *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + C_Block key; /* Service's secret key + * (to decrypt the ticket) */ + Key_schedule key_s; /* The precomputed key schedule */ +{ + static int tkt_swap_bytes; + unsigned char *uptr; + char *ptr = (char *)tkt->dat; + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length, + key_s,key,DECRYPT); +#endif /* ! NOENCRYPTION */ + + *flags = *ptr; /* get flags byte */ + ptr += sizeof(*flags); + tkt_swap_bytes = 0; + if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1)) + tkt_swap_bytes++; + + if (strlen(ptr) > ANAME_SZ) + return(KFAILURE); + (void) strcpy(pname,ptr); /* pname */ + ptr += strlen(pname) + 1; + + if (strlen(ptr) > INST_SZ) + return(KFAILURE); + (void) strcpy(pinstance,ptr); /* instance */ + ptr += strlen(pinstance) + 1; + + if (strlen(ptr) > REALM_SZ) + return(KFAILURE); + (void) strcpy(prealm,ptr); /* realm */ + ptr += strlen(prealm) + 1; + /* temporary hack until realms are dealt with properly */ + if (*prealm == 0) + (void) strcpy(prealm,KRB_REALM); + + bcopy(ptr,(char *)paddress,4); /* net address */ + ptr += 4; + + bcopy(ptr,(char *)session,8); /* session key */ + ptr+= 8; +#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */ + if (tkt_swap_bytes) + swap_C_Block(session); +#endif + + /* get lifetime, being certain we don't get negative lifetimes */ + uptr = (unsigned char *) ptr++; + *life = (int) *uptr; + + bcopy(ptr,(char *) time_sec,4); /* issue time */ + ptr += 4; + if (tkt_swap_bytes) + swap_u_long(*time_sec); + + (void) strcpy(sname,ptr); /* service name */ + ptr += 1 + strlen(sname); + + (void) strcpy(sinstance,ptr); /* instance */ + ptr += 1 + strlen(sinstance); + return(KSUCCESS); +} diff --git a/eBones/krb/des_rw.c b/eBones/krb/des_rw.c new file mode 100644 index 0000000..c958355 --- /dev/null +++ b/eBones/krb/des_rw.c @@ -0,0 +1,265 @@ +/* - + * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University + * All rights reserved. + * + * This code is derived from a specification based on software + * which forms part of the 4.4BSD-Lite distribution, which was developed + * by the University of California and its contributors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the entire comment, + * including the above copyright notice, this list of conditions + * and the following disclaimer, verbatim, at the beginning of + * the source file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Geoffrey M. Rehmet + * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $ + */ + +/* + * + * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED. + * + */ + +/* + * Routines for reading and writing DES encrypted messages onto sockets. + * (These routines will fail if non-blocking I/O is used.) + * + * When a message is written, its length is first transmitted as an int, + * in network byte order. The encrypted message is then transmitted, + * to a multiple of 8 bytes. Messages shorter than 8 bytes are right + * justified into a buffer of length 8 bytes, and the remainder of the + * buffer is filled with random garbage (before encryption): + * + * DDD -------->--+--------+ + * | | + * +--+--+--+--+--+--+--+--+ + * |x |x |x |x |x |D |D |D | + * +--+--+--+--+--+--+--+--+ + * | garbage | data | + * | | + * +-----------------------+----> des_pcbc_encrypt() --> + * + * (Note that the length field sent before the actual message specifies + * the number of data bytes, not the length of the entire padded message. + * + * When data is read, if the message received is longer than the number + * of bytes requested, then the remaining bytes are stored until the + * following call to des_read(). If the number of bytes received is + * less then the number of bytes received, then only the number of bytes + * actually received is returned. + * + * This interface corresponds with the original des_rw.c, except for the + * bugs in des_read() in the original 4.4BSD version. (One bug is + * normally not visible, due to undocumented behaviour of + * des_pcbc_encrypt() in the original MIT libdes.) + * + * XXX Todo: + * 1) Give better error returns on writes + * 2) Improve error checking on reads + * 3) Get rid of need for extern decl. of krb_net_read() + * 4) Tidy garbage generation a bit + * 5) Make the above comment more readable + */ + +#ifdef CRYPT +#ifdef KERBEROS + +#ifndef BUFFER_LEN +#define BUFFER_LEN 10240 +#endif + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/param.h> +#include <sys/types.h> + +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +extern int krb_net_read(int fd, void * data, size_t length); +extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output, + register long length, + des_key_schedule schedule, + des_cblock *ivec, + int encrypt); + +static bit_64 des_key; +static des_key_schedule key_sched; + +/* + * Buffer for storing extra data when more data is received, then was + * actually requested in des_read(). + */ +static u_char des_buff[BUFFER_LEN]; +static u_char buffer[BUFFER_LEN]; +static unsigned stored = 0; +static u_char *buff_ptr = buffer; + +/* + * Set the encryption key for des_read() and des_write(). + * inkey is the initial vector for the DES encryption, while insched is + * the DES key, in unwrapped form. + */ +void des_set_key(inkey, insched) + bit_64 *inkey; + u_char *insched; +{ + bcopy(inkey, &des_key, sizeof(bit_64)); + bcopy(insched, &key_sched, sizeof(des_key_schedule)); +} + +/* + * Clear the key schedule, and initial vector, which were previously + * stored in static vars by des_set_key(). + */ +void des_clear_key() +{ + bzero(&des_key, sizeof(des_cblock)); + bzero(&key_sched, sizeof(des_key_schedule)); +} + +int des_read(fd, buf, len) + int fd; + register char * buf; + int len; +{ + int msg_length; /* length of actual message data */ + int pad_length; /* length of padded message */ + int nread; /* number of bytes actually read */ + int nreturned = 0; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + return(len); + } else { + if (stored) { + bcopy(buff_ptr, buf, stored); + nreturned = stored; + len -= stored; + stored = 0; + buff_ptr = buffer; + } else { + nreturned = 0; + buff_ptr = buffer; + } + } + + nread = krb_net_read(fd, &msg_length, sizeof(msg_length)); + if(nread != (int)(sizeof(msg_length))) + return(0); + + msg_length = ntohl(msg_length); + pad_length = roundup(msg_length, 8); + + nread = krb_net_read(fd, des_buff, pad_length); + if(nread != pad_length) + return(0); + + des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr, + (msg_length < 8 ? 8 : msg_length), + key_sched, (des_cblock*) &des_key, DES_DECRYPT); + + + if(msg_length < 8) + buff_ptr += (8 - msg_length); + stored = msg_length; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + nreturned += len; + } else { + bcopy(buff_ptr, buf, stored); + nreturned += stored; + stored = 0; + } + + return(nreturned); +} + + +/* + * Write a message onto a file descriptor (generally a socket), using + * DES to encrypt the message. + */ +int des_write(fd, buf, len) + int fd; + char * buf; + int len; +{ + static int seeded = 0; + char garbage[8]; + long rnd; + int pad_len; + int write_len; + int nwritten = 0; + int i; + char *data; + + if(len < 8) { + /* + * Right justify the message in 8 bytes of random garbage. + */ + if(!seeded) { + seeded = 1; + srandom((unsigned)time(NULL)); + } + + for(i = 0 ; i < 8 ; i+= sizeof(long)) { + rnd = random(); + bcopy(&rnd, garbage+i, + (i <= (8 - sizeof(long)))?sizeof(long):(8-i)); + } + bcopy(buf, garbage + 8 - len, len); + data = garbage; + pad_len = 8; + } else { + data = buf; + pad_len = roundup(len, 8); + } + + des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff, + (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT); + + + write_len = htonl(len); + if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len)) + return(-1); + if(write(fd, des_buff, pad_len) != pad_len) + return(-1); + + return(len); +} + +#endif /* KERBEROS */ +#endif /* CRYPT */ diff --git a/eBones/krb/dest_tkt.c b/eBones/krb/dest_tkt.c new file mode 100644 index 0000000..17c7855 --- /dev/null +++ b/eBones/krb/dest_tkt.c @@ -0,0 +1,87 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $ + * $Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif +#include <errno.h> + +/* + * dest_tkt() is used to destroy the ticket store upon logout. + * If the ticket file does not exist, dest_tkt() returns RET_TKFIL. + * Otherwise the function returns RET_OK on success, KFAILURE on + * failure. + * + * The ticket file (TKT_FILE) is defined in "krb.h". + */ + +dest_tkt() +{ + char *file = TKT_FILE; + int i,fd; + extern int errno; + struct stat statb; + char buf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; +#endif /* TKT_SHMEM */ + + errno = 0; + if (lstat(file,&statb) < 0) + goto out; + + if (!(statb.st_mode & S_IFREG) +#ifdef notdef + || statb.st_mode & 077 +#endif + ) + goto out; + + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; + + bzero(buf, BUFSIZ); + + for (i = 0; i < statb.st_size; i += BUFSIZ) + if (write(fd, buf, BUFSIZ) != BUFSIZ) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + + (void) unlink(file); + +out: + if (errno == ENOENT) return RET_TKFIL; + else if (errno != 0) return KFAILURE; +#ifdef TKT_SHMEM + /* + * handle the shared memory case + */ + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + if ((i = krb_shm_dest(shmidname)) != KSUCCESS) + return(i); +#endif /* TKT_SHMEM */ + return(KSUCCESS); +} diff --git a/eBones/krb/extract_ticket.c b/eBones/krb/extract_ticket.c new file mode 100644 index 0000000..571d5da --- /dev/null +++ b/eBones/krb/extract_ticket.c @@ -0,0 +1,58 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $ + * $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is obsolete. + * + * This routine accepts the ciphertext returned by kerberos and + * extracts the nth ticket. It also fills in the variables passed as + * session, liftime and kvno. + */ + +extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket) + KTEXT cipher; /* The ciphertext */ + int n; /* Which ticket */ + char *session; /* The session key for this tkt */ + int *lifetime; /* The life of this ticket */ + int *kvno; /* The kvno for the service */ + char *realm; /* Realm in which tkt issued */ + KTEXT ticket; /* The ticket itself */ +{ + char *ptr; + int i; + + /* Start after the ticket lengths */ + ptr = (char *) cipher->dat; + ptr = ptr + 1 + (int) *(cipher->dat); + + /* Step through earlier tickets */ + for (i = 1; i < n; i++) + ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i); + bcopy(ptr, (char *) session, 8); /* Save the session key */ + ptr += 8; + *lifetime = *(ptr++); /* Save the life of the ticket */ + *kvno = *(ptr++); /* Save the kvno */ + (void) strcpy(realm,ptr); /* instance */ + ptr += strlen(realm) + 1; + + /* Save the ticket if its length is non zero */ + ticket->length = *(cipher->dat+n); + if (ticket->length) + bcopy(ptr, (char *) (ticket->dat), ticket->length); +} diff --git a/eBones/krb/fgetst.c b/eBones/krb/fgetst.c new file mode 100644 index 0000000..d938013 --- /dev/null +++ b/eBones/krb/fgetst.c @@ -0,0 +1,39 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $ + * $Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> + +/* + * fgetst takes a file descriptor, a character pointer, and a count. + * It reads from the file it has either read "count" characters, or + * until it reads a null byte. When finished, what has been read exists + * in "s". If "count" characters were actually read, the last is changed + * to a null, so the returned string is always null-terminated. fgetst + * returns the number of characters read, including the null terminator. + */ + +fgetst(f, s, n) + FILE *f; + register char *s; + int n; +{ + register count = n; + int ch; /* NOT char; otherwise you don't see EOF */ + + while ((ch = getc(f)) != EOF && ch && --count) { + *s++ = ch; + } + *s = '\0'; + return (n - count); +} diff --git a/eBones/krb/get_ad_tkt.c b/eBones/krb/get_ad_tkt.c new file mode 100644 index 0000000..d8e1283 --- /dev/null +++ b/eBones/krb/get_ad_tkt.c @@ -0,0 +1,234 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $ + * $Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <prot.h> +#include <strings.h> + +#include <stdio.h> +#include <errno.h> + +/* use the bsd time.h struct defs for PC too! */ +#include <sys/time.h> +#include <sys/types.h> + +extern int krb_debug; + +struct timeval tt_local = { 0, 0 }; + +int swap_bytes; +unsigned long rep_err_code; + +/* + * get_ad_tkt obtains a new service ticket from Kerberos, using + * the ticket-granting ticket which must be in the ticket file. + * It is typically called by krb_mk_req() when the client side + * of an application is creating authentication information to be + * sent to the server side. + * + * get_ad_tkt takes four arguments: three pointers to strings which + * contain the name, instance, and realm of the service for which the + * ticket is to be obtained; and an integer indicating the desired + * lifetime of the ticket. + * + * It returns an error status if the ticket couldn't be obtained, + * or AD_OK if all went well. The ticket is stored in the ticket + * cache. + * + * The request sent to the Kerberos ticket-granting service looks + * like this: + * + * pkt->dat + * + * TEXT original contents of authenticator+ticket + * pkt->dat built in krb_mk_req call + * + * 4 bytes time_ws always 0 (?) + * char lifetime lifetime argument passed + * string service service name argument + * string sinstance service instance arg. + * + * See "prot.h" for the reply packet layout and definitions of the + * extraction macros like pkt_version(), pkt_msg_type(), etc. + */ + +get_ad_tkt(service,sinstance,realm,lifetime) + char *service; + char *sinstance; + char *realm; + int lifetime; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = & pkt_st; /* Packet to KDC */ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + static KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + static KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + C_Block ses; /* Session key for tkt */ + CREDENTIALS cr; + int kvno; /* Kvno for session key */ + char lrealm[REALM_SZ]; + C_Block key; /* Key for decrypting cipher */ + Key_schedule key_s; + long time_ws = 0; + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + int msg_byte_order; + int kerror; + char rlm[REALM_SZ]; + char *ptr; + + unsigned long kdc_time; /* KDC time */ + + if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS) + return(kerror); + + /* Create skeleton of packet to be sent */ + (void) gettimeofday(&tt_local,(struct timezone *) 0); + + pkt->length = 0; + + /* + * Look for the session key (and other stuff we don't need) + * in the ticket file for krbtgt.realm@lrealm where "realm" + * is the service's realm (passed in "realm" argument) and + * lrealm is the realm of our initial ticket. If we don't + * have this, we will try to get it. + */ + + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) { + /* + * If realm == lrealm, we have no hope, so let's not even try. + */ + if ((strncmp(realm, lrealm, REALM_SZ)) == 0) + return(AD_NOTGT); + else{ + if ((kerror = + get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS) + return(kerror); + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) + return(kerror); + } + } + + /* + * Make up a request packet to the "krbtgt.realm@lrealm". + * Start by calling krb_mk_req() which puts ticket+authenticator + * into "pkt". Then tack other stuff on the end. + */ + + kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L); + + if (kerror) + return(AD_NOTGT); + + /* timestamp */ + bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (char) lifetime; + (void) strcpy((char *) (pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* Send the request to the local ticket-granting server */ + if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION ) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) + swap_bytes++; + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4); + if (swap_bytes) + swap_u_long(rep_err_code); + return(rep_err_code); + + default: + return(INTK_PROT); + } + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length); + +#ifndef NOENCRYPTION + key_sched(cr.session,key_s); + pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length, + key_s,cr.session,DECRYPT); +#endif + /* Get rid of all traces of key */ + bzero((char *) cr.session, sizeof(key)); + bzero((char *) key_s, sizeof(key_s)); + + ptr = (char *) cip->dat; + + bcopy(ptr,(char *)ses,8); + ptr += 8; + + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + lifetime = (unsigned long) ptr[0]; + kvno = (unsigned long) ptr[1]; + tkt->length = (int) ptr[2]; + ptr += 3; + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&tt_local,(struct timezone *) 0); + if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime, + kvno,tkt,tt_local.tv_sec)) + return(kerror); + + return(AD_OK); +} diff --git a/eBones/krb/get_admhst.c b/eBones/krb/get_admhst.c new file mode 100644 index 0000000..c36e997 --- /dev/null +++ b/eBones/krb/get_admhst.c @@ -0,0 +1,79 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $ + * $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <string.h> + +/* + * Given a Kerberos realm, find a host on which the Kerberos database + * administration server can be found. + * + * krb_get_admhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer n, and + * returns (in h) the nth administrative host entry from the configuration + * file (KRB_CONF, defined in "krb.h") associated with the specified realm. + * + * On error, get_admhst returns KFAILURE. If all goes well, the routine + * returns KSUCCESS. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + * + * This is a temporary hack to allow us to find the nearest system running + * a Kerberos admin server. In the long run, this functionality will be + * provided by a nameserver. + */ + +krb_get_admhst(h, r, n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + char scratch[64]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + return(KFAILURE); + } + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + /* error reading */ + (void) fclose(cnffile); + return(KFAILURE); + } + if (!index(linebuf, '\n')) { + /* didn't all fit into buffer, punt */ + (void) fclose(cnffile); + return(KFAILURE); + } + for (i = 0; i < n; ) { + /* run through the file, looking for admin host */ + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + /* need to scan for a token after 'admin' to make sure that + admin matched correctly */ + if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/krb/get_cred.c b/eBones/krb/get_cred.c new file mode 100644 index 0000000..baf7ae2 --- /dev/null +++ b/eBones/krb/get_cred.c @@ -0,0 +1,60 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $ + * $Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> + +/* + * krb_get_cred takes a service name, instance, and realm, and a + * structure of type CREDENTIALS to be filled in with ticket + * information. It then searches the ticket file for the appropriate + * ticket and fills in the structure with the corresponding + * information from the file. If successful, it returns KSUCCESS. + * On failure it returns a Kerberos error code. + */ + +krb_get_cred(service,instance,realm,c) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + CREDENTIALS *c; /* Credentials struct */ +{ + int tf_status; /* return value of tf function calls */ + + /* Open ticket file and lock it for shared reading */ + if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Copy principal's name and instance into the CREDENTIALS struc c */ + + if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS || + (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS ) + return (tf_status); + + /* Search for requested service credentials and copy into c */ + + while ((tf_status = tf_get_cred(c)) == KSUCCESS) { + /* Is this the right ticket? */ + if ((strcmp(c->service,service) == 0) && + (strcmp(c->instance,instance) == 0) && + (strcmp(c->realm,realm) == 0)) + break; + } + (void) tf_close(); + + if (tf_status == EOF) + return (GC_NOTKT); + return(tf_status); +} diff --git a/eBones/krb/get_in_tkt.c b/eBones/krb/get_in_tkt.c new file mode 100644 index 0000000..5fb1560 --- /dev/null +++ b/eBones/krb/get_in_tkt.c @@ -0,0 +1,288 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $ + * $Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#ifndef NULL +#define NULL 0 +#endif + +/* + * This file contains two routines: passwd_to_key() converts + * a password into a DES key (prompting for the password if + * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for + * a user. + */ + +/* + * passwd_to_key(): given a password, return a DES key. + * There are extra arguments here which (used to be?) + * used by srvtab_to_key(). + * + * If the "passwd" argument is not null, generate a DES + * key from it, using string_to_key(). + * + * If the "passwd" argument is null, call des_read_password() + * to prompt for a password and then convert it into a DES key. + * + * In either case, the resulting key is put in the "key" argument, + * and 0 is returned. + */ + +/*ARGSUSED */ +static int passwd_to_key(user,instance,realm,passwd,key) + char *user, *instance, *realm, *passwd; + C_Block key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else + if (passwd) + string_to_key(passwd,key); + else + des_read_password(key,"Password: ",0); +#endif + return (0); +} + +/* + * krb_get_pw_in_tkt() takes the name of the server for which the initial + * ticket is to be obtained, the name of the principal the ticket is + * for, the desired lifetime of the ticket, and the user's password. + * It passes its arguments on to krb_get_in_tkt(), which contacts + * Kerberos to get the ticket, decrypts it using the password provided, + * and stores it away for future use. + * + * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt(): + * the name of a routine (passwd_to_key()) to be used to get the + * password in case the "password" argument is null and NULL for the + * decryption procedure indicating that krb_get_in_tkt should use the + * default method of decrypting the response from the KDC. + * + * The result of the call to krb_get_in_tkt() is returned. + */ + +krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *password; +{ + return(krb_get_in_tkt(user,instance,realm,service,sinstance,life, + passwd_to_key, NULL, password)); +} + +#ifdef NOENCRYPTION +/* + * $Source: /home/CVS/src/eBones/krb/get_in_tkt.c,v $ + * $Author: g89r4222 $ + * + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * This routine prints the supplied string to standard + * output as a prompt, and reads a password string without + * echoing. + */ + +#ifndef lint +static char rcsid_read_password_c[] = +"Bones$Header: /home/CVS/src/eBones/krb/get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $"; +#endif lint + +#include <des.h> +#include "conf.h" + +#include <stdio.h> +#ifdef BSDUNIX +#include <strings.h> +#include <sys/ioctl.h> +#include <signal.h> +#include <setjmp.h> +#else +char *strcpy(); +int strcmp(); +#endif + +#ifdef BSDUNIX +static jmp_buf env; +#endif + +#ifdef BSDUNIX +static void sig_restore(); +static push_signals(), pop_signals(); +int placebo_read_pw_string(); +#endif + +/*** Routines ****************************************************** */ +int +placebo_read_password(k,prompt,verify) + des_cblock *k; + char *prompt; + int verify; +{ + int ok; + char key_string[BUFSIZ]; + +#ifdef BSDUNIX + if (setjmp(env)) { + ok = -1; + goto lose; + } +#endif + + ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify); + if (ok == 0) + bzero(k, sizeof(C_Block)); + +lose: + bzero(key_string, sizeof (key_string)); + return ok; +} + +/* + * This version just returns the string, doesn't map to key. + * + * Returns 0 on success, non-zero on failure. + */ + +int +placebo_read_pw_string(s,max,prompt,verify) + char *s; + int max; + char *prompt; + int verify; +{ + int ok = 0; + char *ptr; + +#ifdef BSDUNIX + jmp_buf old_env; + struct sgttyb tty_state; +#endif + char key_string[BUFSIZ]; + + if (max > BUFSIZ) { + return -1; + } + +#ifdef BSDUNIX + bcopy(old_env, env, sizeof(env)); + if (setjmp(env)) + goto lose; + + /* save terminal state*/ + if (ioctl(0,TIOCGETP,&tty_state) == -1) + return -1; + + push_signals(); + /* Turn off echo */ + tty_state.sg_flags &= ~ECHO; + if (ioctl(0,TIOCSETP,&tty_state) == -1) + return -1; +#endif + while (!ok) { + printf(prompt); + fflush(stdout); +#ifdef CROSSMSDOS + h19line(s,sizeof(s),0); + if (!strlen(s)) + continue; +#else + if (!fgets(s, max, stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(s, '\n'))) + *ptr = '\0'; +#endif + if (verify) { + printf("\nVerifying, please re-enter %s",prompt); + fflush(stdout); +#ifdef CROSSMSDOS + h19line(key_string,sizeof(key_string),0); + if (!strlen(key_string)) + continue; +#else + if (!fgets(key_string, sizeof(key_string), stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(key_string, '\n'))) + *ptr = '\0'; +#endif + if (strcmp(s,key_string)) { + printf("\n\07\07Mismatch - try again\n"); + fflush(stdout); + continue; + } + } + ok = 1; + } + +#ifdef BSDUNIX +lose: + if (!ok) + bzero(s, max); + printf("\n"); + /* turn echo back on */ + tty_state.sg_flags |= ECHO; + if (ioctl(0,TIOCSETP,&tty_state)) + ok = 0; + pop_signals(); + bcopy(env, old_env, sizeof(env)); +#endif + if (verify) + bzero(key_string, sizeof (key_string)); + s[max-1] = 0; /* force termination */ + return !ok; /* return nonzero if not okay */ +} + +#ifdef BSDUNIX +/* + * this can be static since we should never have more than + * one set saved.... + */ +#ifdef POSIX +static void (*old_sigfunc[NSIG])(); +#else +static int (*old_sigfunc[NSIG])(); +#endif POSIX + +static push_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + old_sigfunc[i] = signal(i,sig_restore); +} + +static pop_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + signal(i,old_sigfunc[i]); +} + +static void sig_restore(sig,code,scp) + int sig,code; + struct sigcontext *scp; +{ + longjmp(env,1); +} +#endif +#endif /* NOENCRYPTION */ diff --git a/eBones/krb/get_krbhst.c b/eBones/krb/get_krbhst.c new file mode 100644 index 0000000..16c4ff2 --- /dev/null +++ b/eBones/krb/get_krbhst.c @@ -0,0 +1,84 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $ + * $Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* + * Given a Kerberos realm, find a host on which the Kerberos authenti- + * cation server can be found. + * + * krb_get_krbhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer, n, and + * returns (in h) the nth entry from the configuration file (KRB_CONF, + * defined in "krb.h") associated with the specified realm. + * + * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the + * configuration file does not exist, krb_get_krbhst will return KRB_HOST + * (also defined in "krb.h"). If all goes well, the routine returnes + * KSUCCESS. + * + * The KRB_CONF file contains the name of the local realm in the first + * line (not used by this routine), followed by lines indicating realm/host + * entries. The words "admin server" following the hostname indicate that + * the host provides an administrative database server. + * + * For example: + * + * ATHENA.MIT.EDU + * ATHENA.MIT.EDU kerberos-1.mit.edu admin server + * ATHENA.MIT.EDU kerberos-2.mit.edu + * LCS.MIT.EDU kerberos.lcs.mit.edu admin server + * + * This is a temporary hack to allow us to find the nearest system running + * kerberos. In the long run, this functionality will be provided by a + * nameserver. + */ + +krb_get_krbhst(h,r,n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + if (n==1) { + (void) strcpy(h,KRB_HOST); + return(KSUCCESS); + } + else + return(KFAILURE); + } + if (fscanf(cnffile,"%s",tr) == EOF) + return(KFAILURE); + /* run through the file, looking for the nth server for this realm */ + for (i = 1; i <= n;) { + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + if (sscanf(linebuf, "%s %s", tr, h) != 2) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/krb/get_krbrlm.c b/eBones/krb/get_krbrlm.c new file mode 100644 index 0000000..7df073d --- /dev/null +++ b/eBones/krb/get_krbrlm.c @@ -0,0 +1,59 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $ + * $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* + * krb_get_lrealm takes a pointer to a string, and a number, n. It fills + * in the string, r, with the name of the nth realm specified on the + * first line of the kerberos config file (KRB_CONF, defined in "krb.h"). + * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the + * config file does not exist, and if n=1, a successful return will occur + * with r = KRB_REALM (also defined in "krb.h"). + * + * NOTE: for archaic & compatibility reasons, this routine will only return + * valid results when n = 1. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + */ + +krb_get_lrealm(r,n) + char *r; + int n; +{ + FILE *cnffile, *fopen(); + + if (n > 1) + return(KFAILURE); /* Temporary restriction */ + + if ((cnffile = fopen(KRB_CONF, "r")) == NULL) { + if (n == 1) { + (void) strcpy(r, KRB_REALM); + return(KSUCCESS); + } + else + return(KFAILURE); + } + + if (fscanf(cnffile,"%s",r) != 1) { + (void) fclose(cnffile); + return(KFAILURE); + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/krb/get_phost.c b/eBones/krb/get_phost.c new file mode 100644 index 0000000..9b12d10 --- /dev/null +++ b/eBones/krb/get_phost.c @@ -0,0 +1,53 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $ + * $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <ctype.h> +#include <netdb.h> + +char *index(); + +/* + * This routine takes an alias for a host name and returns the first + * field, lower case, of its domain name. For example, if "menel" is + * an alias for host officially named "menelaus" (in /etc/hosts), for + * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus" + * is returned. + * + * This is done for historical Athena reasons: the Kerberos name of + * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm" + * where "host"is the lowercase for of the host name ("menelaus"). + * This should go away: the instance should be the domain name + * (MENELAUS.MIT.EDU). But for now we need this routine... + * + * A pointer to the name is returned, if found, otherwise a pointer + * to the original "alias" argument is returned. + */ + +char * krb_get_phost(alias) + char *alias; +{ + struct hostent *h; + char *phost = alias; + if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) { + char *p = index( h->h_name, '.' ); + if (p) + *p = NULL; + p = phost = h->h_name; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/eBones/krb/get_pw_tkt.c b/eBones/krb/get_pw_tkt.c new file mode 100644 index 0000000..48a003c --- /dev/null +++ b/eBones/krb/get_pw_tkt.c @@ -0,0 +1,72 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $ + * $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $"; +#endif /* lint */ + + +#include <krb.h> + +/* + * Get a ticket for the password-changing server ("changepw.KRB_MASTER"). + * + * Given the name, instance, realm, and current password of the + * principal for which the user wants a password-changing-ticket, + * return either: + * + * GT_PW_BADPW if current password was wrong, + * GT_PW_NULL if principal had a NULL password, + * or the result of the krb_get_pw_in_tkt() call. + * + * First, try to get a ticket for "user.instance@realm" to use the + * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h"). + * The requested lifetime for the ticket is "1", and the current + * password is the "cpw" argument given. + * + * If the password was bad, give up. + * + * If the principal had a NULL password in the Kerberos database + * (indicating that the principal is known to Kerberos, but hasn't + * got a password yet), try instead to get a ticket for the principal + * "default.changepw@realm" to use the "changepw.KRB_MASTER" server. + * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL + * if all goes well, otherwise the error. + * + * If this routine succeeds, a ticket and session key for either the + * principal "user.instance@realm" or "default.changepw@realm" to use + * the password-changing server will be in the user's ticket file. + */ + +get_pw_tkt(user,instance,realm,cpw) + char *user; + char *instance; + char *realm; + char *cpw; +{ + int kerror; + + kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw", + KRB_MASTER, 1, cpw); + + if (kerror == INTK_BADPW) + return(GT_PW_BADPW); + + if (kerror == KDC_NULL_KEY) { + kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw", + KRB_MASTER,1,"changepwkrb"); + if (kerror) + return(kerror); + return(GT_PW_NULL); + } + + return(kerror); +} diff --git a/eBones/krb/get_request.c b/eBones/krb/get_request.c new file mode 100644 index 0000000..131ffd5 --- /dev/null +++ b/eBones/krb/get_request.c @@ -0,0 +1,52 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $ + * $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +/* + * This procedure is obsolete. It is used in the kerberos_slave + * code for Version 3 tickets. + * + * This procedure sets s_name, and instance to point to + * the corresponding fields from tne nth request in the packet. + * it returns the lifetime requested. Garbage will be returned + * if there are less than n requests in the packet. + */ + +get_request(pkt, n, s_name, instance) + KTEXT pkt; /* The packet itself */ + int n; /* Which request do we want */ + char **s_name; /* Service name to be filled in */ + char **instance; /* Instance name to be filled in */ +{ + /* Go to the beginning of the request list */ + char *ptr = (char *) pkt_a_realm(pkt) + 6 + + strlen((char *)pkt_a_realm(pkt)); + + /* Read requests until we hit the right one */ + while (n-- > 1) { + ptr++; + ptr += 1 + strlen(ptr); + ptr += 1 + strlen(ptr); + } + + /* Set the arguments to point to the right place */ + *s_name = 1 + ptr; + *instance = 2 + ptr + strlen(*s_name); + + /* Return the requested lifetime */ + return((int) *ptr); +} diff --git a/eBones/krb/get_svc_in_tkt.c b/eBones/krb/get_svc_in_tkt.c new file mode 100644 index 0000000..6d9702f --- /dev/null +++ b/eBones/krb/get_svc_in_tkt.c @@ -0,0 +1,73 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $ + * $Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#ifndef NULL +#define NULL 0 +#endif + +/* + * This file contains two routines: srvtab_to_key(), which gets + * a server's key from a srvtab file, and krb_get_svc_in_tkt() which + * gets an initial ticket for a server. + */ + +/* + * srvtab_to_key(): given a "srvtab" file (where the keys for the + * service on a host are stored), return the private key of the + * given service (user.instance@realm). + * + * srvtab_to_key() passes its arguments on to read_service_key(), + * plus one additional argument, the key version number. + * (Currently, the key version number is always 0; this value + * is treated as a wildcard by read_service_key().) + * + * If the "srvtab" argument is null, KEYFILE (defined in "krb.h") + * is passed in its place. + * + * It returns the return value of the read_service_key() call. + * The service key is placed in "key". + */ + +static int srvtab_to_key(user, instance, realm, srvtab, key) + char *user, *instance, *realm, *srvtab; + C_Block key; +{ + if (!srvtab) + srvtab = KEYFILE; + + return(read_service_key(user, instance, realm, 0, srvtab, + (char *)key)); +} + +/* + * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(), + * plus two additional arguments: a pointer to the srvtab_to_key() + * function to be used to get the key from the key file and a NULL + * for the decryption procedure indicating that krb_get_in_tkt should + * use the default method of decrypting the response from the KDC. + * + * It returns the return value of the krb_get_in_tkt() call. + */ + +krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *srvtab; +{ + return(krb_get_in_tkt(user, instance, realm, service, sinstance, + life, srvtab_to_key, NULL, srvtab)); +} diff --git a/eBones/krb/get_tf_fullname.c b/eBones/krb/get_tf_fullname.c new file mode 100644 index 0000000..753ad1e --- /dev/null +++ b/eBones/krb/get_tf_fullname.c @@ -0,0 +1,66 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $ + * $Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> +#include <stdio.h> + +/* + * This file contains a routine to extract the fullname of a user + * from the ticket file. + */ + +/* + * krb_get_tf_fullname() takes four arguments: the name of the + * ticket file, and variables for name, instance, and realm to be + * returned in. Since the realm of a ticket file is not really fully + * supported, the realm used will be that of the the first ticket in + * the file as this is the one that was obtained with a password by + * krb_get_in_tkt(). + */ + +krb_get_tf_fullname(ticket_file, name, instance, realm) + char *ticket_file; + char *name; + char *instance; + char *realm; +{ + int tf_status; + CREDENTIALS c; + + if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) || + ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS)) + return (tf_status); + + if (name) + strcpy(name, c.pname); + if (instance) + strcpy(instance, c.pinst); + if ((tf_status = tf_get_cred(&c)) == KSUCCESS) { + if (realm) + strcpy(realm, c.realm); + } + else { + if (tf_status == EOF) + return(KFAILURE); + else + return(tf_status); + } + (void) tf_close(); + + return(tf_status); +} diff --git a/eBones/krb/get_tf_realm.c b/eBones/krb/get_tf_realm.c new file mode 100644 index 0000000..f405dcb --- /dev/null +++ b/eBones/krb/get_tf_realm.c @@ -0,0 +1,34 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $ + * $Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> + +/* + * This file contains a routine to extract the realm of a kerberos + * ticket file. + */ + +/* + * krb_get_tf_realm() takes two arguments: the name of a ticket + * and a variable to store the name of the realm in. + * + */ + +krb_get_tf_realm(ticket_file, realm) + char *ticket_file; + char *realm; +{ + return(krb_get_tf_fullname(ticket_file, 0, 0, realm)); +} diff --git a/eBones/krb/getrealm.c b/eBones/krb/getrealm.c new file mode 100644 index 0000000..96e9588 --- /dev/null +++ b/eBones/krb/getrealm.c @@ -0,0 +1,104 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * routine to convert hostname into realm name. + * + * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $ + * $Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $"; +#endif lint + +#include <strings.h> +#include <stdio.h> +#include <ctype.h> +#include <krb.h> +#include <sys/param.h> + +/* for Ultrix and friends ... */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +/* + * krb_realmofhost. + * Given a fully-qualified domain-style primary host name, + * return the name of the Kerberos realm for the host. + * If the hostname contains no discernable domain, or an error occurs, + * return the local realm name, as supplied by get_krbrlm(). + * If the hostname contains a domain, but no translation is found, + * the hostname's domain is converted to upper-case and returned. + * + * The format of each line of the translation file is: + * domain_name kerberos_realm + * -or- + * host_name kerberos_realm + * + * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU) + * host names should be in the usual form (e.g. FOO.BAR.BAZ) + */ + +static char ret_realm[REALM_SZ+1]; + +char * +krb_realmofhost(host) +char *host; +{ + char *domain; + FILE *trans_file; + char trans_host[MAXHOSTNAMELEN+1]; + char trans_realm[REALM_SZ+1]; + int retval; + + domain = index(host, '.'); + + /* prepare default */ + if (domain) { + char *cp; + + strncpy(ret_realm, &domain[1], REALM_SZ); + ret_realm[REALM_SZ] = '\0'; + /* Upper-case realm */ + for (cp = ret_realm; *cp; cp++) + if (islower(*cp)) + *cp = toupper(*cp); + } else { + krb_get_lrealm(ret_realm, 1); + } + + if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) { + /* krb_errno = KRB_NO_TRANS */ + return(ret_realm); + } + while (1) { + if ((retval = fscanf(trans_file, "%s %s", + trans_host, trans_realm)) != 2) { + if (retval == EOF) { + fclose(trans_file); + return(ret_realm); + } + continue; /* ignore broken lines */ + } + trans_host[MAXHOSTNAMELEN] = '\0'; + trans_realm[REALM_SZ] = '\0'; + if (!strcasecmp(trans_host, host)) { + /* exact match of hostname, so return the realm */ + (void) strcpy(ret_realm, trans_realm); + fclose(trans_file); + return(ret_realm); + } + if ((trans_host[0] == '.') && domain) { + /* this is a domain match */ + if (!strcasecmp(trans_host, domain)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } + } + } +} diff --git a/eBones/krb/getst.c b/eBones/krb/getst.c new file mode 100644 index 0000000..edd55ec --- /dev/null +++ b/eBones/krb/getst.c @@ -0,0 +1,35 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $ + * $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $"; +#endif /* lint */ + +/* + * getst() takes a file descriptor, a string and a count. It reads + * from the file until either it has read "count" characters, or until + * it reads a null byte. When finished, what has been read exists in + * the given string "s". If "count" characters were actually read, the + * last is changed to a null, so the returned string is always null- + * terminated. getst() returns the number of characters read, including + * the null terminator. + */ + +getst(fd, s, n) + int fd; + register char *s; +{ + register count = n; + while (read(fd, s, 1) > 0 && --count) + if (*s++ == '\0') + return (n - count); + *s = '\0'; + return (n - count); +} diff --git a/eBones/krb/in_tkt.c b/eBones/krb/in_tkt.c new file mode 100644 index 0000000..53510da --- /dev/null +++ b/eBones/krb/in_tkt.c @@ -0,0 +1,142 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $ + * $Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $"; +#endif /* lint */ + +#include <unistd.h> +#include <stdio.h> +#include <krb.h> +#include <sys/file.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif + +extern int krb_debug; + +/* + * in_tkt() is used to initialize the ticket store. It creates the + * file to contain the tickets and writes the given user's name "pname" + * and instance "pinst" in the file. in_tkt() returns KSUCCESS on + * success, or KFAILURE if something goes wrong. + */ + +in_tkt(pname,pinst) + char *pname; + char *pinst; +{ + int tktfile; + uid_t me, metoo; + struct stat buf; + int count; + char *file = TKT_FILE; + int fd; + register int i; + char charbuf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; +#endif /* TKT_SHMEM */ + + me = getuid (); + metoo = geteuid(); + if (lstat(file,&buf) == 0) { + if (buf.st_uid != me && me == 0) { + unlink(file); + } else { + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",file); + return(KFAILURE); + } + /* file already exists, and permissions appear ok, so nuke it */ + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; /* can't zero it, but we can still try truncating it */ + + bzero(charbuf, sizeof(charbuf)); + + for (i = 0; i < buf.st_size; i += sizeof(charbuf)) + if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + } + } + out: + /* arrange so the file is owned by the ruid + (swap real & effective uid if necessary). + This isn't a security problem, since the ticket file, if it already + exists, has the right uid (== ruid) and mode. */ + if (me != metoo) { + if (setreuid(metoo, me) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",metoo,me); + } + if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + if (me != metoo) { + if (setreuid(me, metoo) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid2"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",me,metoo); + } + if (lstat(file,&buf) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + count = strlen(pname)+1; + if (write(tktfile,pname,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + count = strlen(pinst)+1; + if (write(tktfile,pinst,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + (void) close(tktfile); +#ifdef TKT_SHMEM + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + return(krb_shm_create(shmidname)); +#else /* !TKT_SHMEM */ + return(KSUCCESS); +#endif /* TKT_SHMEM */ +} diff --git a/eBones/krb/k_gethostname.c b/eBones/krb/k_gethostname.c new file mode 100644 index 0000000..e5c11ca --- /dev/null +++ b/eBones/krb/k_gethostname.c @@ -0,0 +1,65 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $ + * $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $"; +#endif /* lint */ + +#ifndef PC +#ifndef BSD42 +/* teach me how to k_gethostname for your system here */ +#endif +#endif + +#ifdef PC +#include <stdio.h> +typedef long in_name; +#include "custom.h" /* where is this file? */ +extern get_custom(); +#define LEN 64 /* just a guess */ +#endif /* PC */ + +/* + * Return the local host's name in "name", up to "namelen" characters. + * "name" will be null-terminated if "namelen" is big enough. + * The return code is 0 on success, -1 on failure. (The calling + * interface is identical to gethostname(2).) + * + * Currently defined for BSD 4.2 and PC. The BSD version just calls + * gethostname(); the PC code was taken from "kinit.c", and may or may + * not work. + */ + +k_gethostname(name, namelen) + char *name; +{ +#ifdef BSD42 + return gethostname(name, namelen); +#endif + +#ifdef PC + char buf[LEN]; + char b1, b2, b3, b4; + register char *ptr; + + get_custom(); /* should check for errors, + * return -1 on failure */ + ptr = (char *) &(custom.c_me); + b1 = *ptr++; + b2 = *ptr++; + b3 = *ptr++; + b4 = *ptr; + (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4); + if (strlen(buf) > namelen) + fprintf(stderr, "gethostname: namelen too small; truncating"); + strnpcy(name, buf, namelen); + return 0; +#endif +} diff --git a/eBones/krb/klog.c b/eBones/krb/klog.c new file mode 100644 index 0000000..b530e8b --- /dev/null +++ b/eBones/krb/klog.c @@ -0,0 +1,108 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $ + * $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> + +#include <krb.h> +#include <klog.h> + +static char *log_name = KRBLOG; +static int is_open; +static char logtxt[1000]; + +/* + * This file contains two logging routines: kset_logfile() + * to determine the file to which log entries should be written; + * and klog() to write log entries to the file. + */ + +/* + * klog() is used to add entries to the logfile (see kset_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format" string. + * + * The log file is opened and closed for each log entry. + * + * If the given log type "type" is unknown, or if the log file + * cannot be opened, no entry is made to the log file. + * + * The return value is always a pointer to the formatted log + * text string "logtxt". + */ + +char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0) + int type; + char *format; + int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0; +{ + FILE *logfile, *fopen(); + long time(),now; + char *month_sname(); + struct tm *tm; + static int logtype_array[NLOGTYPE] = {0,0}; + static int array_initialized; + + if (!(array_initialized++)) { + logtype_array[L_NET_ERR] = 1; + logtype_array[L_KRB_PERR] = 1; + logtype_array[L_KRB_PWARN] = 1; + logtype_array[L_APPL_REQ] = 1; + logtype_array[L_INI_REQ] = 1; + logtype_array[L_DEATH_REQ] = 1; + logtype_array[L_NTGT_INTK] = 1; + logtype_array[L_ERR_SEXP] = 1; + logtype_array[L_ERR_MKV] = 1; + logtype_array[L_ERR_NKY] = 1; + logtype_array[L_ERR_NUN] = 1; + logtype_array[L_ERR_UNK] = 1; + } + + (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + + if (!logtype_array[type]) + return(logtxt); + + if ((logfile = fopen(log_name,"a")) == NULL) + return(logtxt); + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,"%s\n",logtxt); + (void) fclose(logfile); + return(logtxt); +} + +/* + * kset_logfile() changes the name of the file to which + * messages are logged. If kset_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +kset_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} diff --git a/eBones/krb/kname_parse.c b/eBones/krb/kname_parse.c new file mode 100644 index 0000000..dd5fe0b --- /dev/null +++ b/eBones/krb/kname_parse.c @@ -0,0 +1,233 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $ + * $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* max size of full name */ +#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ) + +#define NAME 0 /* which field are we in? */ +#define INST 1 +#define REALM 2 + +extern char *krb_err_txt[]; + +/* + * This file contains four routines for handling Kerberos names. + * + * kname_parse() breaks a Kerberos name into its name, instance, + * and realm components. + * + * k_isname(), k_isinst(), and k_isrealm() check a given string to see if + * it's a syntactically legitimate respective part of a Kerberos name, + * returning 1 if it is, 0 if it isn't. + * + * Definition of "syntactically legitimate" names is according to + * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying + * names", version dated 21 Dec 1987. + * / + +/* + * kname_parse() takes a Kerberos name "fullname" of the form: + * + * username[.instance][@realm] + * + * and returns the three components ("name", "instance", and "realm" + * in the example above) in the given arguments "np", "ip", and "rp". + * + * If successful, it returns KSUCCESS. If there was an error, + * KNAME_FMT is returned. + */ + +kname_parse(np, ip, rp, fullname) + char *np, *ip, *rp, *fullname; +{ + static char buf[FULL_SZ]; + char *rnext, *wnext; /* next char to read, write */ + register char c; + int backslash; + int field; + + backslash = 0; + rnext = buf; + wnext = np; + field = NAME; + + if (strlen(fullname) > FULL_SZ) + return KNAME_FMT; + (void) strcpy(buf, fullname); + + while (c = *rnext++) { + if (backslash) { + *wnext++ = c; + backslash = 0; + continue; + } + switch (c) { + case '\\': + backslash++; + break; + case '.': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *wnext = '\0'; + field = INST; + wnext = ip; + break; + case INST: + return KNAME_FMT; + /* break; */ + case REALM: + *wnext++ = c; + break; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + case '@': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *ip = '\0'; + /* fall through */ + case INST: + *wnext = '\0'; + field = REALM; + wnext = rp; + break; + case REALM: + return KNAME_FMT; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + default: + *wnext++ = c; + } + } + *wnext = '\0'; + if ((strlen(np) > ANAME_SZ - 1) || + (strlen(ip) > INST_SZ - 1) || + (strlen(rp) > REALM_SZ - 1)) + return KNAME_FMT; + return KSUCCESS; +} + +/* + * k_isname() returns 1 if the given name is a syntactically legitimate + * Kerberos name; returns 0 if it's not. + */ + +k_isname(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > ANAME_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + + +/* + * k_isinst() returns 1 if the given name is a syntactically legitimate + * Kerberos instance; returns 0 if it's not. + */ + +k_isinst(s) + char *s; +{ + register char c; + int backslash = 0; + + if (strlen(s) > INST_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + +/* + * k_isrealm() returns 1 if the given name is a syntactically legitimate + * Kerberos realm; returns 0 if it's not. + */ + +k_isrealm(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > REALM_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '@': + return 0; + /* break; */ + } + } + return 1; +} diff --git a/eBones/krb/kntoln.c b/eBones/krb/kntoln.c new file mode 100644 index 0000000..62ec1b5 --- /dev/null +++ b/eBones/krb/kntoln.c @@ -0,0 +1,60 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $ + * $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> + +/* + * krb_kntoln converts an auth name into a local name by looking up + * the auth name in the /etc/aname file. The format of the aname + * file is: + * + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | anl | inl | rll | lnl | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | 1by | 1by | 1by | 1by | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * + * If the /etc/aname file can not be opened it will set the + * local name to the auth name. Thus, in this case it performs as + * the identity function. + * + * The name instance and realm are passed to krb_kntoln through + * the AUTH_DAT structure (ad). + * + * Now here's what it *really* does: + * + * Given a Kerberos name in an AUTH_DAT structure, check that the + * instance is null, and that the realm is the same as the local + * realm, and return the principal's name in "lname". Return + * KSUCCESS if all goes well, otherwise KFAILURE. + */ + +krb_kntoln(ad,lname) + AUTH_DAT *ad; + char *lname; +{ + static char lrealm[REALM_SZ] = ""; + + if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE)) + return(KFAILURE); + + if (strcmp(ad->pinst,"")) + return(KFAILURE); + if (strcmp(ad->prealm,lrealm)) + return(KFAILURE); + (void) strcpy(lname,ad->pname); + return(KSUCCESS); +} diff --git a/eBones/krb/kparse.c b/eBones/krb/kparse.c new file mode 100644 index 0000000..d79f1cf --- /dev/null +++ b/eBones/krb/kparse.c @@ -0,0 +1,763 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Purpose: + * This module was developed to parse the "~/.klogin" files for + * Kerberos-authenticated rlogin/rcp/rsh services. However, it is + * general purpose and can be used to parse any such parameter file. + * + * The parameter file should consist of one or more entries, with each + * entry on a separate line and consisting of zero or more + * "keyword=value" combinations. The keyword is case insensitive, but + * the value is not. Any string may be enclosed in quotes, and + * c-style "\" literals are supported. A comma may be used to + * separate the k/v combinations, and multiple commas are ignored. + * Whitespace (blank or tab) may be used freely and is ignored. + * + * Full error processing is available. When PS_BAD_KEYWORD or + * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg + * contains a meaningful error message. + * + * Keywords and their default values are programmed by an external + * table. + * + * Routines: + * fGetParameterSet() parse one line of the parameter file + * fGetKeywordValue() parse one "keyword=value" combo + * fGetToken() parse one token + * + * + * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $ + * $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <ctype.h> +#include <kparse.h> + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define void int + +#define MAXKEY 80 +#define MAXVALUE 80 + +char *malloc(); +char *strcpy(); + +int LineNbr=1; /* current line nbr in parameter file */ +char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX, + * or PS_BAD_KEYWORD is returned by + * fGetKeywordValue or fGetParameterSet */ + +int fGetParameterSet( fp,parm,parmcount ) + FILE *fp; + parmtable parm[]; + int parmcount; +{ + int rc,i; + char keyword[MAXKEY]; + char value[MAXVALUE]; + + while (TRUE) { + rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE); + + switch (rc) { + + case KV_EOF: + return(PS_EOF); + + case KV_EOL: + return(PS_OKAY); + + case KV_SYNTAX: + return(PS_SYNTAX); + + case KV_OKAY: + /* + * got a reasonable keyword/value pair. Search the + * parameter table to see if we recognize the keyword; if + * not, return an error. If we DO recognize it, make sure + * it has not already been given. If not already given, + * save the value. + */ + for (i=0; i<parmcount; i++) { + if (strcmp(strutol(keyword),parm[i].keyword)==0) { + if (parm[i].value) { + sprintf(ErrorMsg,"duplicate keyword \"%s\" found", + keyword); + return(PS_BAD_KEYWORD); + } + parm[i].value = strsave( value ); + break; + } + } + if (i >= parmcount) { + sprintf(ErrorMsg, "unrecognized keyword \"%s\" found", + keyword); + return(PS_BAD_KEYWORD); + } + break; + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + break; + } + } +} + +/* + * Routine: ParmCompare + * + * Purpose: + * ParmCompare checks a specified value for a particular keyword. + * fails if keyword not found or keyword found but the value was + * different. Like strcmp, ParmCompare returns 0 for a match found, -1 + * otherwise + */ +int ParmCompare( parm, parmcount, keyword, value ) + parmtable parm[]; + int parmcount; + char *keyword; + char *value; +{ + int i; + + for (i=0; i<parmcount; i++) { + if (strcmp(parm[i].keyword,keyword)==0) { + if (parm[i].value) { + return(strcmp(parm[i].value,value)); + } else { + return(strcmp(parm[i].defvalue,value)); + } + } + } + return(-1); +} + +void FreeParameterSet(parm,parmcount) + parmtable parm[]; + int parmcount; +{ + int i; + + for (i=0; i<parmcount; i++) { + if (parm[i].value) { + free(parm[i].value); + parm[i].value = (char *)NULL; + } + } +} + +int fGetKeywordValue( fp, keyword, klen, value, vlen ) + FILE *fp; + char *keyword; + int klen; + char *value; + int vlen; +{ + int rc; + int gotit; + + *keyword = *value = '\0'; /* preset strings to NULL */ + + /* + * Looking for a keyword. + * return an exception for EOF or BAD_QSTRING + * ignore leading WHITEspace + * ignore any number of leading commas + * newline means we have all the parms for this + * statement; give an indication that there is + * nothing more on this line. + * stop looking if we find QSTRING, STRING, or NUMBER + * return syntax error for any other PUNKtuation + */ + gotit = FALSE; + do { + rc = fGetToken(fp,keyword,klen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_EOF: + return(KV_EOF); + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg,"unterminated string \"%s found",keyword); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("\n",keyword)==0) { + return(KV_EOL); + } else if (strcmp(",",keyword)!=0) { + sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword); + } + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + gotit = TRUE; + break; + + default: + sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while (!gotit); + + /* + * now we expect an equal sign. + * skip any whitespace + * stop looking if we find an equal sign + * anything else causes a syntax error + */ + gotit = FALSE; + do { + rc = fGetToken(fp,value,vlen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg, + "expecting \'=\', found unterminated string \"%s", + value); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("=",value)==0) { + gotit = TRUE; + } else { + if (strcmp("\n",value)==0) { + sprintf(ErrorMsg,"expecting \"=\", found newline"); + fUngetChar('\n',fp); + } else { + sprintf(ErrorMsg, + "expecting rvalue, found \'%s\'",keyword); + } + return(KV_SYNTAX); + } + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value); + return(KV_SYNTAX); + + case GTOK_EOF: + sprintf(ErrorMsg,"expecting \'=\', found EOF"); + return(KV_SYNTAX); + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while ( !gotit ); + + /* + * got the keyword and equal sign, now get a value. + * ignore any whitespace + * any punctuation is a syntax error + */ + gotit = FALSE; + do { + rc = fGetToken(fp,value,vlen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_EOF: + sprintf(ErrorMsg,"expecting rvalue, found EOF"); + return(KV_SYNTAX); + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg,"unterminated quoted string \"%s",value); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("\n",value)==0) { + sprintf(ErrorMsg,"expecting rvalue, found newline"); + fUngetChar('\n',fp); + } else { + sprintf(ErrorMsg, + "expecting rvalue, found \'%s\'",value); + } + return(KV_SYNTAX); + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + gotit = TRUE; + return(KV_OKAY); + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while ( !gotit ); + /*NOTREACHED*/ +} + +/* + * Routine Name: fGetToken + * + * Function: read the next token from the specified file. + * A token is defined as a group of characters + * terminated by a white space char (SPACE, CR, + * LF, FF, TAB). The token returned is stripped of + * both leading and trailing white space, and is + * terminated by a NULL terminator. An alternate + * definition of a token is a string enclosed in + * single or double quotes. + * + * Explicit Parameters: + * fp pointer to the input FILE + * dest pointer to destination buffer + * maxlen length of the destination buffer. The buffer + * length INCLUDES the NULL terminator. + * + * Implicit Parameters: stderr where the "token too long" message goes + * + * External Procedures: fgetc + * + * Side Effects: None + * + * Return Value: A token classification value, as + * defined in kparse.h. Note that the + * classification for end of file is + * always zero. + */ +int fGetToken(fp, dest, maxlen) + FILE *fp; + char *dest; + int maxlen; +{ + int ch='\0'; + int len=0; + char *p = dest; + int digits; + + ch=fGetChar(fp); + + /* + * check for a quoted string. If found, take all characters + * that fit until a closing quote is found. Note that this + * algorithm will not behave well for a string which is too long. + */ + if (ISQUOTE(ch)) { + int done = FALSE; + do { + ch = fGetChar(fp); + done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF) + ||ISQUOTE(ch)); + if (ch=='\\') + ch = fGetLiteral(fp); + if (!done) + *p++ = ch; + else if ((ch!=EOF) && !ISQUOTE(ch)) + fUngetChar(ch,fp); + } while (!done); + *p = '\0'; + if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING); + return(GTOK_QSTRING); + } + + /* + * Not a quoted string. If its a token character (rules are + * defined via the ISTOKENCHAR macro, in kparse.h) take it and all + * token chars following it until we run out of space. + */ + digits=TRUE; + if (ISTOKENCHAR(ch)) { + while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) { + if (!isdigit(ch)) digits=FALSE; + *p++ = ch; + len++; + ch = fGetChar(fp); + }; + *p = '\0'; + + if (ch!=EOF) { + fUngetChar(ch,fp); + } + if (digits) { + return(GTOK_NUMBER); + } else { + return(GTOK_STRING); + } + } + + /* + * Neither a quoted string nor a token character. Return a string + * with just that one character in it. + */ + if (ch==EOF) { + return(GTOK_EOF); + } + if (!ISWHITESPACE(ch)) { + *p++ = ch; + *p='\0'; + } else { + *p++ = ' '; /* white space is always the + * blank character */ + *p='\0'; + /* + * The character is a white space. Flush all additional white + * space. + */ + while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF)) + ; + if (ch!=EOF) { + fUngetChar(ch,fp); + } + return(GTOK_WHITE); + } + return(GTOK_PUNK); +} + +/* + * fGetLiteral is called after we find a '\' in the input stream. A + * string of numbers following the backslash are converted to the + * appropriate value; hex (0xn), octal (0n), and decimal (otherwise) + * are all supported. If the char after the \ is not a number, we + * special case certain values (\n, \f, \r, \b) or return a literal + * otherwise (useful for \", for example). + */ +fGetLiteral(fp) + FILE *fp; +{ + int ch; + int n=0; + int base; + + ch = fGetChar(fp); + + if (!isdigit(ch)) { + switch (ch) { + case 'n': return('\n'); + case 'f': return('\f'); + case 'r': return('\r'); + case 'b': return('\b'); + default: return(ch); + } + } + + /* + * got a number. might be decimal (no prefix), octal (prefix 0), + * or hexadecimal (prefix 0x). Set the base appropriately. + */ + if (ch!='0') { + base=10; /* its a decimal number */ + } else { + /* + * found a zero, its either hex or octal + */ + ch = fGetChar(fp); + if ((ch!='x') && (ch!='X')) { + base=010; + } else { + ch = fGetChar(fp); + base=0x10; + } + } + + switch (base) { + + case 010: /* octal */ + while (ISOCTAL(ch)) { + n = (n*base) + ch - '0'; + ch = fGetChar(fp); + } + break; + + case 10: /* decimal */ + while (isdigit(ch)) { + n = (n*base) + ch - '0'; + ch = fGetChar(fp); + } + break; + case 0x10: /* hexadecimal */ + while (isxdigit(ch)) { + if (isdigit(ch)) { + n = (n*base) + ch - '0'; + } else { + n = (n*base) + toupper(ch) - 'A' + 0xA ; + } + ch = fGetChar(fp); + } + break; + default: + fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c."); + exit(1); + break; + } + fUngetChar(ch,fp); + return(n); +} + +/* + * exactly the same as ungetc(3) except that the line number of the + * input file is maintained. + */ +fUngetChar(ch,fp) + int ch; + FILE *fp; +{ + if (ch=='\n') LineNbr--; + return(ungetc(ch,fp)); +} + + +/* + * exactly the same as fgetc(3) except that the line number of the + * input file is maintained. + */ +fGetChar(fp) + FILE *fp; +{ + int ch = fgetc(fp); + if (ch=='\n') LineNbr++; + return(ch); +} + + +/* + * Routine Name: strsave + * + * Function: return a pointer to a saved copy of the + * input string. the copy will be allocated + * as large as necessary. + * + * Explicit Parameters: pointer to string to save + * + * Implicit Parameters: None + * + * External Procedures: malloc,strcpy,strlen + * + * Side Effects: None + * + * Return Value: pointer to copied string + * + */ +char * strsave(p) + char *p; +{ + return(strcpy(malloc(strlen(p)+1),p)); +} + + +/* + * strutol changes all characters in a string to lower case, in place. + * the pointer to the beginning of the string is returned. + */ + +char * strutol( start ) + char *start; +{ + char *q; + for (q=start; *q; q++) + if (isupper(*q)) + *q=tolower(*q); + return(start); +} + +#ifdef GTOK_TEST /* mainline test routine for fGetToken() */ + +#define MAXTOKEN 100 + +char *pgm = "gettoken"; + +main(argc,argv) + int argc; + char **argv; +{ + char *p; + int type; + FILE *fp; + + if (--argc) { + fp = fopen(*++argv,"ra"); + if (fp == (FILE *)NULL) { + fprintf(stderr,"can\'t open \"%s\"\n",*argv); + } + } else + fp = stdin; + + p = malloc(MAXTOKEN); + while (type = fGetToken(fp,p,MAXTOKEN)) { + switch(type) { + case GTOK_BAD_QSTRING: + printf("BAD QSTRING!\t"); + break; + case GTOK_EOF: + printf("EOF!\t"); + break; + case GTOK_QSTRING: + printf("QSTRING\t"); + break; + case GTOK_STRING: + printf("STRING\t"); + break; + case GTOK_NUMBER: + printf("NUMBER\t"); + break; + case GTOK_PUNK: + printf("PUNK\t"); + break; + case GTOK_WHITE: + printf("WHITE\t"); + break; + default: + printf("HUH?\t"); + break; + } + if (*p=='\n') + printf("\\n\n"); + else + printf("%s\n",p); + } + exit(0); +} +#endif + +#ifdef KVTEST + +main(argc,argv) + int argc; + char **argv; +{ + int rc,ch; + FILE *fp; + char key[MAXKEY],valu[MAXVALUE]; + char *filename; + + if (argc != 2) { + fprintf(stderr,"usage: test <filename>\n"); + exit(1); + } + + if (!(fp=fopen(*++argv,"r"))) { + fprintf(stderr,"can\'t open input file \"%s\"\n",filename); + exit(1); + } + filename = *argv; + + while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){ + + switch (rc) { + + case KV_EOL: + printf("%s, line %d: nada mas.\n",filename,LineNbr-1); + break; + + case KV_SYNTAX: + printf("%s, line %d: syntax error: %s\n", + filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case KV_OKAY: + printf("%s, line %d: okay, %s=\"%s\"\n", + filename,LineNbr,key,valu); + break; + + default: + printf("panic: bad return (%d) from fGetKeywordValue\n",rc); + break; + } + } + printf("EOF"); + fclose(fp); + exit(0); +} +#endif + +#ifdef PSTEST + +parmtable kparm[] = { + /* keyword, default, found value */ + { "user", "", (char *)NULL }, + { "realm", "Athena", (char *)NULL }, + { "instance", "", (char *)NULL } +}; + +main(argc,argv) + int argc; + char **argv; +{ + int rc,i,ch; + FILE *fp; + char *filename; + + if (argc != 2) { + fprintf(stderr,"usage: test <filename>\n"); + exit(1); + } + + if (!(fp=fopen(*++argv,"r"))) { + fprintf(stderr,"can\'t open input file \"%s\"\n",filename); + exit(1); + } + filename = *argv; + + while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) { + + switch (rc) { + + case PS_BAD_KEYWORD: + printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case PS_SYNTAX: + printf("%s, line %d: syntax error: %s\n", + filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case PS_OKAY: + printf("%s, line %d: valid parameter set found:\n", + filename,LineNbr-1); + for (i=0; i<PARMCOUNT(kparm); i++) { + printf("\t%s = \"%s\"\n",kparm[i].keyword, + (kparm[i].value ? kparm[i].value + : kparm[i].defvalue)); + } + break; + + default: + printf("panic: bad return (%d) from fGetParameterSet\n",rc); + break; + } + FreeParameterSet(kparm,PARMCOUNT(kparm)); + } + printf("EOF"); + fclose(fp); + exit(0); +} +#endif diff --git a/eBones/krb/krb_err.et b/eBones/krb/krb_err.et new file mode 100644 index 0000000..2c6830b --- /dev/null +++ b/eBones/krb/krb_err.et @@ -0,0 +1,257 @@ +# Copyright 1987,1988 Massachusetts Institute of Technology +# For copying and distribution information, see the file +# "Copyright.MIT". +# +# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $ +# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $ +# + error_table krb + + ec KRBET_KSUCCESS, + "Kerberos successful" + + ec KRBET_KDC_NAME_EXP, + "Kerberos principal expired" + + ec KRBET_KDC_SERVICE_EXP, + "Kerberos service expired" + + ec KRBET_KDC_AUTH_EXP, + "Kerberos auth expired" + + ec KRBET_KDC_PKT_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_P_MKEY_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_S_MKEY_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_BYTE_ORDER, + "Kerberos error: byte order unknown" + + ec KRBET_KDC_PR_UNKNOWN, + "Kerberos principal unknown" + + ec KRBET_KDC_PR_N_UNIQUE, + "Kerberos principal not unique" + + ec KRBET_KDC_NULL_KEY, + "Kerberos principal has null key" + + ec KRBET_KRB_RES11, + "Reserved 11" + + ec KRBET_KRB_RES12, + "Reserved 12" + + ec KRBET_KRB_RES13, + "Reserved 13" + + ec KRBET_KRB_RES14, + "Reserved 14" + + ec KRBET_KRB_RES15, + "Reserved 15" + + ec KRBET_KRB_RES16, + "Reserved 16" + + ec KRBET_KRB_RES17, + "Reserved 17" + + ec KRBET_KRB_RES18, + "Reserved 18" + + ec KRBET_KRB_RES19, + "Reserved 19" + + ec KRBET_KDC_GEN_ERR, + "Generic error from Kerberos KDC" + + ec KRBET_GC_TKFIL, + "Can't read Kerberos ticket file" + + ec KRBET_GC_NOTKT, + "Can't find Kerberos ticket or TGT" + + ec KRBET_KRB_RES23, + "Reserved 23" + + ec KRBET_KRB_RES24, + "Reserved 24" + + ec KRBET_KRB_RES25, + "Reserved 25" + + ec KRBET_MK_AP_TGTEXP, + "Kerberos TGT Expired" + + ec KRBET_KRB_RES27, + "Reserved 27" + + ec KRBET_KRB_RES28, + "Reserved 28" + + ec KRBET_KRB_RES29, + "Reserved 29" + + ec KRBET_KRB_RES30, + "Reserved 30" + + ec KRBET_RD_AP_UNDEC, + "Kerberos error: Can't decode authenticator" + + ec KRBET_RD_AP_EXP, + "Kerberos ticket expired" + + ec KRBET_RD_AP_NYV, + "Kerberos ticket not yet valid" + + ec KRBET_RD_AP_REPEAT, + "Kerberos error: Repeated request" + + ec KRBET_RD_AP_NOT_US, + "The kerberos ticket isn't for us" + + ec KRBET_RD_AP_INCON, + "Kerberos request inconsistent" + + ec KRBET_RD_AP_TIME, + "Kerberos error: delta_t too big" + + ec KRBET_RD_AP_BADD, + "Kerberos error: incorrect net address" + + ec KRBET_RD_AP_VERSION, + "Kerberos protocol version mismatch" + + ec KRBET_RD_AP_MSG_TYPE, + "Kerberos error: invalid msg type" + + ec KRBET_RD_AP_MODIFIED, + "Kerberos error: message stream modified" + + ec KRBET_RD_AP_ORDER, + "Kerberos error: message out of order" + + ec KRBET_RD_AP_UNAUTHOR, + "Kerberos error: unauthorized request" + + ec KRBET_KRB_RES44, + "Reserved 44" + + ec KRBET_KRB_RES45, + "Reserved 45" + + ec KRBET_KRB_RES46, + "Reserved 46" + + ec KRBET_KRB_RES47, + "Reserved 47" + + ec KRBET_KRB_RES48, + "Reserved 48" + + ec KRBET_KRB_RES49, + "Reserved 49" + + ec KRBET_KRB_RES50, + "Reserved 50" + + ec KRBET_GT_PW_NULL, + "Kerberos error: current PW is null" + + ec KRBET_GT_PW_BADPW, + "Kerberos error: Incorrect current password" + + ec KRBET_GT_PW_PROT, + "Kerberos protocol error" + + ec KRBET_GT_PW_KDCERR, + "Error returned by Kerberos KDC" + + ec KRBET_GT_PW_NULLTKT, + "Null Kerberos ticket returned by KDC" + + ec KRBET_SKDC_RETRY, + "Kerberos error: Retry count exceeded" + + ec KRBET_SKDC_CANT, + "Kerberos error: Can't send request" + + ec KRBET_KRB_RES58, + "Reserved 58" + + ec KRBET_KRB_RES59, + "Reserved 59" + + ec KRBET_KRB_RES60, + "Reserved 60" + + ec KRBET_INTK_W_NOTALL, + "Kerberos error: not all tickets returned" + + ec KRBET_INTK_BADPW, + "Kerberos error: incorrect password" + + ec KRBET_INTK_PROT, + "Kerberos error: Protocol Error" + + ec KRBET_KRB_RES64, + "Reserved 64" + + ec KRBET_KRB_RES65, + "Reserved 65" + + ec KRBET_KRB_RES66, + "Reserved 66" + + ec KRBET_KRB_RES67, + "Reserved 67" + + ec KRBET_KRB_RES68, + "Reserved 68" + + ec KRBET_KRB_RES69, + "Reserved 69" + + ec KRBET_INTK_ERR, + "Other error" + + ec KRBET_AD_NOTGT, + "Don't have Kerberos ticket-granting ticket" + + ec KRBET_KRB_RES72, + "Reserved 72" + + ec KRBET_KRB_RES73, + "Reserved 73" + + ec KRBET_KRB_RES74, + "Reserved 74" + + ec KRBET_KRB_RES75, + "Reserved 75" + + ec KRBET_NO_TKT_FIL, + "No ticket file found" + + ec KRBET_TKT_FIL_ACC, + "Couldn't access ticket file" + + ec KRBET_TKT_FIL_LCK, + "Couldn't lock ticket file" + + ec KRBET_TKT_FIL_FMT, + "Bad ticket file format" + + ec KRBET_TKT_FIL_INI, + "tf_init not called first" + + ec KRBET_KNAME_FMT, + "Bad Kerberos name format" + + end + diff --git a/eBones/krb/krb_err_txt.c b/eBones/krb/krb_err_txt.c new file mode 100644 index 0000000..785563f --- /dev/null +++ b/eBones/krb/krb_err_txt.c @@ -0,0 +1,278 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $ + * $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $"; +#endif lint + +/* + * This file contains an array of error text strings. + * The associated error codes (which are defined in "krb.h") + * follow the string in the comments at the end of each line. + */ + +char *krb_err_txt[256] = { + "OK", /* 000 */ + "Principal expired (kerberos)", /* 001 */ + "Service expired (kerberos)", /* 002 */ + "Authentication expired (kerberos)", /* 003 */ + "Unknown protocol version number (kerberos)", /* 004 */ + "Principal: Incorrect master key version (kerberos)", /* 005 */ + "Service: Incorrect master key version (kerberos)", /* 006 */ + "Bad byte order (kerberos)", /* 007 */ + "Principal unknown (kerberos)", /* 008 */ + "Principal not unique (kerberos)", /* 009 */ + "Principal has null key (kerberos)", /* 010 */ + "Reserved error message 11 (kerberos)", /* 011 */ + "Reserved error message 12 (kerberos)", /* 012 */ + "Reserved error message 13 (kerberos)", /* 013 */ + "Reserved error message 14 (kerberos)", /* 014 */ + "Reserved error message 15 (kerberos)", /* 015 */ + "Reserved error message 16 (kerberos)", /* 016 */ + "Reserved error message 17 (kerberos)", /* 017 */ + "Reserved error message 18 (kerberos)", /* 018 */ + "Reserved error message 19 (kerberos)", /* 019 */ + "Permission Denied (kerberos)", /* 020 */ + "Can't read ticket file (krb_get_cred)", /* 021 */ + "Can't find ticket (krb_get_cred)", /* 022 */ + "Reserved error message 23 (krb_get_cred)", /* 023 */ + "Reserved error message 24 (krb_get_cred)", /* 024 */ + "Reserved error message 25 (krb_get_cred)", /* 025 */ + "Ticket granting ticket expired (krb_mk_req)", /* 026 */ + "Reserved error message 27 (krb_mk_req)", /* 027 */ + "Reserved error message 28 (krb_mk_req)", /* 028 */ + "Reserved error message 29 (krb_mk_req)", /* 029 */ + "Reserved error message 30 (krb_mk_req)", /* 030 */ + "Can't decode authenticator (krb_rd_req)", /* 031 */ + "Ticket expired (krb_rd_req)", /* 032 */ + "Ticket issue date too far in the future (krb_rd_req)",/* 033 */ + "Repeat request (krb_rd_req)", /* 034 */ + "Ticket for wrong server (krb_rd_req)", /* 035 */ + "Request inconsistent (krb_rd_req)", /* 036 */ + "Time is out of bounds (krb_rd_req)", /* 037 */ + "Incorrect network address (krb_rd_req)", /* 038 */ + "Protocol version mismatch (krb_rd_req)", /* 039 */ + "Illegal message type (krb_rd_req)", /* 040 */ + "Message integrity error (krb_rd_req)", /* 041 */ + "Message duplicate or out of order (krb_rd_req)", /* 042 */ + "Unauthorized request (krb_rd_req)", /* 043 */ + "Reserved error message 44 (krb_rd_req)", /* 044 */ + "Reserved error message 45 (krb_rd_req)", /* 045 */ + "Reserved error message 46 (krb_rd_req)", /* 046 */ + "Reserved error message 47 (krb_rd_req)", /* 047 */ + "Reserved error message 48 (krb_rd_req)", /* 048 */ + "Reserved error message 49 (krb_rd_req)", /* 049 */ + "Reserved error message 50 (krb_rd_req)", /* 050 */ + "Current password is NULL (get_pw_tkt)", /* 051 */ + "Current password incorrect (get_pw_tkt)", /* 052 */ + "Protocol error (gt_pw_tkt)", /* 053 */ + "Error returned by KDC (gt_pw_tkt)", /* 054 */ + "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */ + "Retry count exceeded (send_to_kdc)", /* 056 */ + "Can't send request (send_to_kdc)", /* 057 */ + "Reserved error message 58 (send_to_kdc)", /* 058 */ + "Reserved error message 59 (send_to_kdc)", /* 059 */ + "Reserved error message 60 (send_to_kdc)", /* 060 */ + "Warning: Not ALL tickets returned", /* 061 */ + "Password incorrect", /* 062 */ + "Protocol error (get_intkt)", /* 063 */ + "Reserved error message 64 (get_in_tkt)", /* 064 */ + "Reserved error message 65 (get_in_tkt)", /* 065 */ + "Reserved error message 66 (get_in_tkt)", /* 066 */ + "Reserved error message 67 (get_in_tkt)", /* 067 */ + "Reserved error message 68 (get_in_tkt)", /* 068 */ + "Reserved error message 69 (get_in_tkt)", /* 069 */ + "Generic error (get_intkt)", /* 070 */ + "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */ + "Reserved error message 72 (get_ad_tkt)", /* 072 */ + "Reserved error message 73 (get_ad_tkt)", /* 073 */ + "Reserved error message 74 (get_ad_tkt)", /* 074 */ + "Reserved error message 75 (get_ad_tkt)", /* 075 */ + "No ticket file (tf_util)", /* 076 */ + "Can't access ticket file (tf_util)", /* 077 */ + "Can't lock ticket file; try later (tf_util)", /* 078 */ + "Bad ticket file format (tf_util)", /* 079 */ + "Read ticket file before tf_init (tf_util)", /* 080 */ + "Bad Kerberos name format (kname_parse)", /* 081 */ + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "Generic kerberos error (kfailure)", /* 255 */ +}; diff --git a/eBones/krb/krb_get_in_tkt.c b/eBones/krb/krb_get_in_tkt.c new file mode 100644 index 0000000..a37bb60 --- /dev/null +++ b/eBones/krb/krb_get_in_tkt.c @@ -0,0 +1,297 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $ + * $Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <prot.h> + +#include <stdio.h> +#include <strings.h> +#include <errno.h> + +/* use the bsd time.h struct defs for PC too! */ +#include <sys/time.h> +#include <sys/types.h> + +int swap_bytes; + +/* + * decrypt_tkt(): Given user, instance, realm, passwd, key_proc + * and the cipher text sent from the KDC, decrypt the cipher text + * using the key returned by key_proc. + */ + +static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp) + char *user; + char *instance; + char *realm; + char *arg; + int (*key_proc)(); + KTEXT *cipp; +{ + KTEXT cip = *cipp; + C_Block key; /* Key for decrypting cipher */ + Key_schedule key_s; + +#ifndef NOENCRYPTION + /* Attempt to decrypt it */ +#endif + + /* generate a key */ + + { + register int rc; + rc = (*key_proc)(user,instance,realm,arg,key); + if (rc) + return(rc); + } + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat, + (long) cip->length,key_s,key,DES_DECRYPT); +#endif /* !NOENCRYPTION */ + /* Get rid of all traces of key */ + bzero((char *)key,sizeof(key)); + bzero((char *)key_s,sizeof(key_s)); + + return(0); +} + +/* + * krb_get_in_tkt() gets a ticket for a given principal to use a given + * service and stores the returned ticket and session key for future + * use. + * + * The "user", "instance", and "realm" arguments give the identity of + * the client who will use the ticket. The "service" and "sinstance" + * arguments give the identity of the server that the client wishes + * to use. (The realm of the server is the same as the Kerberos server + * to whom the request is sent.) The "life" argument indicates the + * desired lifetime of the ticket; the "key_proc" argument is a pointer + * to the routine used for getting the client's private key to decrypt + * the reply from Kerberos. The "decrypt_proc" argument is a pointer + * to the routine used to decrypt the reply from Kerberos; and "arg" + * is an argument to be passed on to the "key_proc" routine. + * + * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it + * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned + * by Kerberos, then the error code it contains is returned. Other + * error codes returned by this routine include INTK_PROT to indicate + * wrong protocol version, INTK_BADPW to indicate bad password (if + * decrypted ticket didn't make sense), INTK_ERR if the ticket was for + * the wrong server or the ticket store couldn't be initialized. + * + * The format of the message sent to Kerberos is as follows: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_KDC_REQUEST | message type + * HOST_BYTE_ORDER local byte order in lsb + * string user client's name + * string instance client's instance + * string realm client's realm + * 4 bytes tlocal.tv_sec timestamp in seconds + * 1 byte life desired lifetime + * string service service's name + * string sinstance service's instance + */ + +krb_get_in_tkt(user, instance, realm, service, sinstance, life, + key_proc, decrypt_proc, arg) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + int (*key_proc)(); + int (*decrypt_proc)(); + char *arg; +{ + KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; /* Packet to KDC */ + KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + C_Block ses; /* Session key for tkt */ + int kvno; /* Kvno for session key */ + unsigned char *v = pkt->dat; /* Prot vers no */ + unsigned char *t = (pkt->dat+1); /* Prot msg type */ + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + char rlm[REALM_SZ]; + int lifetime; + int msg_byte_order; + int kerror; + unsigned long exp_date; + char *ptr; + + struct timeval t_local; + + unsigned long rep_err_code; + + unsigned long kdc_time; /* KDC time */ + + /* BUILD REQUEST PACKET */ + + /* Set up the fixed part of the packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Now for the variable info */ + (void) strcpy((char *)(pkt->dat+2),user); /* aname */ + pkt->length = 3 + strlen(user); + (void) strcpy((char *)(pkt->dat+pkt->length), + instance); /* instance */ + pkt->length += 1 + strlen(instance); + (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */ + pkt->length += 1 + strlen(realm); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + /* timestamp */ + bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4); + pkt->length += 4; + + *(pkt->dat+(pkt->length)++) = (char) life; + (void) strcpy((char *)(pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */ + + if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4); + if (swap_bytes) swap_u_long(rep_err_code); + return((int)rep_err_code); + default: + return(INTK_PROT); + } + + /* EXTRACT INFORMATION FROM RETURN PACKET */ + + /* get the principal's expiration date */ + bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date)); + if (swap_bytes) swap_u_long(exp_date); + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + if ((cip->length < 0) || (cip->length > sizeof(cip->dat))) + return(INTK_ERR); /* no appropriate error code + currently defined for INTK_ */ + /* copy information from return packet into "cip" */ + bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length); + + /* Attempt to decrypt the reply. */ + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip); + + ptr = (char *) cip->dat; + + /* extract session key */ + bcopy(ptr,(char *)ses,8); + ptr += 8; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's name */ + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's instance */ + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's realm */ + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + /* extract ticket lifetime, server key version, ticket length */ + /* be sure to avoid sign extension on lifetime! */ + lifetime = (unsigned char) ptr[0]; + kvno = (unsigned char) ptr[1]; + tkt->length = (unsigned char) ptr[2]; + ptr += 3; + + if ((tkt->length < 0) || + ((tkt->length + (ptr - (char *) cip->dat)) > cip->length)) + return(INTK_BADPW); + + /* extract ticket itself */ + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&t_local,(struct timezone *) 0); + if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + /* initialize ticket cache */ + if (in_tkt(user,instance) != KSUCCESS) + return(INTK_ERR); + + /* stash ticket, session key, etc. for future use */ + if (kerror = save_credentials(s_name, s_instance, rlm, ses, + lifetime, kvno, tkt, t_local.tv_sec)) + return(kerror); + + return(INTK_OK); +} diff --git a/eBones/krb/krb_realmofhost.3 b/eBones/krb/krb_realmofhost.3 new file mode 100644 index 0000000..f284069 --- /dev/null +++ b/eBones/krb/krb_realmofhost.3 @@ -0,0 +1,161 @@ +.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $ +.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst, +krb_get_lrealm \- additional Kerberos utility routines +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.ft B +char *krb_realmofhost(host) +char *host; +.PP +.ft B +char *krb_get_phost(alias) +char *alias; +.PP +.ft B +krb_get_krbhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_admhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_lrealm(realm,n) +char *realm; +int n; +.fi +.ft R +.SH DESCRIPTION +.I krb_realmofhost +returns the Kerberos realm of the host +.IR host , +as determined by the translation table +.IR /etc/krb.realms . +.I host +should be the fully-qualified domain-style primary host name of the host +in question. In order to prevent certain security attacks, this routine +must either have +.I a priori +knowledge of a host's realm, or obtain such information securely. +.PP +The format of the translation file is described by +.IR krb.realms (5). +If +.I host +exactly matches a host_name line, the corresponding realm +is returned. +Otherwise, if the domain portion of +.I host +matches a domain_name line, the corresponding realm +is returned. +If +.I host +contains a domain, but no translation is found, +.IR host 's +domain is converted to upper-case and returned. +If +.I host +contains no discernable domain, or an error occurs, +the local realm name, as supplied by +.IR krb_get_lrealm (3), +is returned. +.PP +.I krb_get_phost +converts the hostname +.I alias +(which can be either an official name or an alias) into the instance +name to be used in obtaining Kerberos tickets for most services, +including the Berkeley rcmd suite (rlogin, rcp, rsh). +.br +The current convention is to return the first segment of the official +domain-style name after conversion to lower case. +.PP +.I krb_get_krbhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos key distribution center (KDC) +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +The configuration file is described by +.IR krb.conf (5). +If the host is successfully filled in, the routine +returns KSUCCESS. +If the file cannot be opened, and +.I n +equals 1, then the value of KRB_HOST as defined in +.I <krb.h> +is filled in, and KSUCCESS is returned. If there are fewer than +.I n +hosts running a Kerberos KDC for the requested realm, or the +configuration file is malformed, the routine +returns KFAILURE. +.PP +.I krb_get_admhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos KDC database administration server +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +If the file cannot be opened or is malformed, or there are fewer than +.I n +hosts running a Kerberos KDC database administration server, +the routine returns KFAILURE. +.PP +The character arrays used as return values for +.IR krb_get_krbhst , +.IR krb_get_admhst , +should be large enough to +hold any hostname (MAXHOSTNAMELEN from <sys/param.h>). +.PP +.I krb_get_lrealm +fills in +.I realm +with the +.IR n th +realm of the local host, as specified in the configuration file. +.I realm +should be at least REALM_SZ (from +.IR <krb.h>) characters long. +.PP +.SH SEE ALSO +kerberos(3), krb.conf(5), krb.realms(5) +.SH FILES +.TP 20n +/etc/krb.realms +translation file for host-to-realm mapping. +.TP +/etc/krb.conf +local realm-name and realm/server configuration file. +.SH BUGS +The current convention for instance names is too limited; the full +domain name should be used. +.PP +.I krb_get_lrealm +currently only supports +.I n += 1. It should really consult the user's ticket cache to determine the +user's current realm, rather than consulting a file on the host. diff --git a/eBones/krb/krb_sendauth.3 b/eBones/krb/krb_sendauth.3 new file mode 100644 index 0000000..f5e95b7 --- /dev/null +++ b/eBones/krb/krb_sendauth.3 @@ -0,0 +1,348 @@ +.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $ +.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $ +.\" Copyright 1988 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \- +Kerberos routines for sending authentication via network stream sockets +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.fi +.HP 1i +.ft B +int krb_sendauth(options, fd, ktext, service, inst, realm, checksum, +msg_data, cred, schedule, laddr, faddr, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst, *realm; +u_long checksum; +MSG_DAT *msg_data; +CREDENTIALS *cred; +Key_schedule schedule; +struct sockaddr_in *laddr, *faddr; +char *version; +.PP +.fi +.HP 1i +.ft B +int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr, +auth_data, filename, schedule, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst; +struct sockaddr_in *faddr, *laddr; +AUTH_DAT *auth_data; +char *filename; +Key_schedule schedule; +char *version; +.PP +.ft B +int krb_net_write(fd, buf, len) +int fd; +char *buf; +int len; +.PP +.ft B +int krb_net_read(fd, buf, len) +int fd; +char *buf; +int len; +.fi +.SH DESCRIPTION +.PP +These functions, +which are built on top of the core Kerberos library, +provide a convenient means for client and server +programs to send authentication messages +to one another through network connections. +The +.I krb_sendauth +function sends an authenticated ticket from the client program to +the server program by writing the ticket to a network socket. +The +.I krb_recvauth +function receives the ticket from the client by +reading from a network socket. + +.SH KRB_SENDAUTH +.PP +This function writes the ticket to +the network socket specified by the +file descriptor +.IR fd, +returning KSUCCESS if the write proceeds successfully, +and an error code if it does not. + +The +.I ktext +argument should point to an allocated KTEXT_ST structure. +The +.IR service, +.IR inst, +and +.IR realm +arguments specify the server program's Kerberos principal name, +instance, and realm. +If you are writing a client that uses the local realm exclusively, +you can set the +.I realm +argument to NULL. + +The +.I version +argument allows the client program to pass an application-specific +version string that the server program can then match against +its own version string. +The +.I version +string can be up to KSEND_VNO_LEN (see +.IR <krb.h> ) +characters in length. + +The +.I checksum +argument can be used to pass checksum information to the +server program. +The client program is responsible for specifying this information. +This checksum information is difficult to corrupt because +.I krb_sendauth +passes it over the network in encrypted form. +The +.I checksum +argument is passed as the checksum argument to +.IR krb_mk_req . + +You can set +.IR krb_sendauth's +other arguments to NULL unless you want the +client and server programs to mutually authenticate +themselves. +In the case of mutual authentication, +the client authenticates itself to the server program, +and demands that the server in turn authenticate itself to +the client. + +.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION +.PP +If you want mutual authentication, +make sure that you read all pending data from the local socket +before calling +.IR krb_sendauth. +Set +.IR krb_sendauth's +.I options +argument to +.BR KOPT_DO_MUTUAL +(this macro is defined in the +.IR krb.h +file); +make sure that the +.I laddr +argument points to +the address of the local socket, +and that +.I faddr +points to the foreign socket's network address. + +.I Krb_sendauth +fills in the other arguments-- +.IR msg_data , +.IR cred , +and +.IR schedule --before +sending the ticket to the server program. +You must, however, allocate space for these arguments +before calling the function. + +.I Krb_sendauth +supports two other options: +.BR KOPT_DONT_MK_REQ, +and +.BR KOPT_DONT_CANON. +If called with +.I options +set as KOPT_DONT_MK_REQ, +.I krb_sendauth +will not use the +.I krb_mk_req +function to retrieve the ticket from the Kerberos server. +The +.I ktext +argument must point to an existing ticket and authenticator (such as +would be created by +.IR krb_mk_req ), +and the +.IR service, +.IR inst, +and +.IR realm +arguments can be set to NULL. + +If called with +.I options +set as KOPT_DONT_CANON, +.I krb_sendauth +will not convert the service's instance to canonical form using +.IR krb_get_phost (3). + +If you want to call +.I krb_sendauth +with a multiple +.I options +specification, +construct +.I options +as a bitwise-OR of the options you want to specify. + +.SH KRB_RECVAUTH +.PP +The +.I krb_recvauth +function +reads a ticket/authenticator pair from the socket pointed to by the +.I fd +argument. +Set the +.I options +argument +as a bitwise-OR of the options desired. +Currently only KOPT_DO_MUTUAL is useful to the receiver. + +The +.I ktext +argument +should point to an allocated KTEXT_ST structure. +.I Krb_recvauth +fills +.I ktext +with the +ticket/authenticator pair read from +.IR fd , +then passes it to +.IR krb_rd_req . + +The +.I service +and +.I inst +arguments +specify the expected service and instance for which the ticket was +generated. They are also passed to +.IR krb_rd_req. +The +.I inst +argument may be set to "*" if the caller wishes +.I krb_mk_req +to fill in the instance used (note that there must be space in the +.I inst +argument to hold a full instance name, see +.IR krb_mk_req (3)). + +The +.I faddr +argument +should point to the address of the peer which is presenting the ticket. +It is also passed to +.IR krb_rd_req . + +If the client and server plan to mutually authenticate +one another, +the +.I laddr +argument +should point to the local address of the file descriptor. +Otherwise you can set this argument to NULL. + +The +.I auth_data +argument +should point to an allocated AUTH_DAT area. +It is passed to and filled in by +.IR krb_rd_req . +The checksum passed to the corresponding +.I krb_sendauth +is available as part of the filled-in AUTH_DAT area. + +The +.I filename +argument +specifies the filename +which the service program should use to obtain its service key. +.I Krb_recvauth +passes +.I filename +to the +.I krb_rd_req +function. +If you set this argument to "", +.I krb_rd_req +looks for the service key in the file +.IR /etc/srvtab. + +If the client and server are performing mutual authenication, +the +.I schedule +argument +should point to an allocated Key_schedule. +Otherwise it is ignored and may be NULL. + +The +.I version +argument should point to a character array of at least KSEND_VNO_LEN +characters. It is filled in with the version string passed by the client to +.IR krb_sendauth. +.PP +.SH KRB_NET_WRITE AND KRB_NET_READ +.PP +The +.I krb_net_write +function +emulates the write(2) system call, but guarantees that all data +specified is written to +.I fd +before returning, unless an error condition occurs. +.PP +The +.I krb_net_read +function +emulates the read(2) system call, but guarantees that the requested +amount of data is read from +.I fd +before returning, unless an error condition occurs. +.PP +.SH BUGS +.IR krb_sendauth, +.IR krb_recvauth, +.IR krb_net_write, +and +.IR krb_net_read +will not work properly on sockets set to non-blocking I/O mode. + +.SH SEE ALSO + +krb_mk_req(3), krb_rd_req(3), krb_get_phost(3) + +.SH AUTHOR +John T. Kohl, MIT Project Athena +.SH RESTRICTIONS +Copyright 1988, Massachusetts Instititute of Technology. +For copying and distribution information, +please see the file <mit-copyright.h>. diff --git a/eBones/krb/krb_set_tkt_string.3 b/eBones/krb/krb_set_tkt_string.3 new file mode 100644 index 0000000..c9f3dcf --- /dev/null +++ b/eBones/krb/krb_set_tkt_string.3 @@ -0,0 +1,43 @@ +.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $ +.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_set_tkt_string \- set Kerberos ticket cache file name +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +void krb_set_tkt_string(filename) +char *filename; +.fi +.ft R +.SH DESCRIPTION +.I krb_set_tkt_string +sets the name of the file that holds the user's +cache of Kerberos server tickets and associated session keys. +.PP +The string +.I filename +passed in is copied into local storage. +Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are +copied in for use as the cache file name. +.PP +This routine should be called during initialization, before other +Kerberos routines are called; otherwise the routines which fetch the +ticket cache file name may be called and return an undesired ticket file +name until this routine is called. +.SH FILES +.TP 20n +/tmp/tkt[uid] +default ticket file name, unless the environment variable KRBTKFILE is set. +[uid] denotes the user's uid, in decimal. +.SH SEE ALSO +kerberos(3), setenv(3) diff --git a/eBones/krb/krbglue.c b/eBones/krb/krbglue.c new file mode 100644 index 0000000..8e864c1 --- /dev/null +++ b/eBones/krb/krbglue.c @@ -0,0 +1,252 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $ + * $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $"; +#endif lint + +#ifndef NCOMPAT +/* + * glue together new libraries and old clients + */ + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "des.h" +#include "krb.h" + +/* These definitions should be in krb.h, no? */ +#if defined(__HIGHC__) +#undef __STDC__ +#endif +#ifdef __STDC__ +extern int krb_mk_req (KTEXT, char *, char *, char *, long); +extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *); +extern int krb_kntoln (AUTH_DAT *, char *); +extern int krb_set_key (char *, int); +extern int krb_get_cred (char *, char *, char *, CREDENTIALS *); +extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule, + C_Block, struct sockaddr_in *, + struct sockaddr_in *); +extern long krb_rd_priv (u_char *, u_long, Key_schedule, + C_Block, struct sockaddr_in *, + struct sockaddr_in *, MSG_DAT *); +extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *, + struct sockaddr_in *, struct sockaddr_in *); +extern long krb_rd_safe (u_char *, u_long, C_Block *, + struct sockaddr_in *, struct sockaddr_in *, + MSG_DAT *); +extern long krb_mk_err (u_char *, long, char *); +extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *); +extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int, + char *); +extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int, + char *); +extern int krb_get_pw_tkt (char *, char *, char *, char *); +extern int krb_get_lrealm (char *, char *); +extern int krb_realmofhost (char *); +extern char *krb_get_phost (char *); +extern int krb_get_krbhst (char *, char *, int); +#ifdef DEBUG +extern KTEXT krb_create_death_packet (char *); +#endif /* DEBUG */ +#else +extern int krb_mk_req (); +extern int krb_rd_req (); +extern int krb_kntoln (); +extern int krb_set_key (); +extern int krb_get_cred (); +extern long krb_mk_priv (); +extern long krb_rd_priv (); +extern long krb_mk_safe (); +extern long krb_rd_safe (); +extern long krb_mk_err (); +extern int krb_rd_err (); +extern int krb_get_pw_in_tkt (); +extern int krb_get_svc_in_tkt (); +extern int krb_get_pw_tkt (); +extern int krb_get_lrealm (); +extern int krb_realmofhost (); +extern char *krb_get_phost (); +extern int krb_get_krbhst (); +#ifdef DEBUG +extern KTEXT krb_create_death_packet (); +#endif /* DEBUG */ +#endif /* STDC */ +int mk_ap_req(authent, service, instance, realm, checksum) + KTEXT authent; + char *service, *instance, *realm; + u_long checksum; +{ + return krb_mk_req(authent,service,instance,realm,checksum); +} + +int rd_ap_req(authent, service, instance, from_addr, ad, fn) + KTEXT authent; + char *service, *instance; + u_long from_addr; + AUTH_DAT *ad; + char *fn; +{ + return krb_rd_req(authent,service,instance,from_addr,ad,fn); +} + +int an_to_ln(ad, lname) + AUTH_DAT *ad; + char *lname; +{ + return krb_kntoln (ad,lname); +} + +int set_serv_key (key, cvt) + char *key; + int cvt; +{ + return krb_set_key(key,cvt); +} + +int get_credentials (svc,inst,rlm,cred) + char *svc, *inst, *rlm; + CREDENTIALS *cred; +{ + return krb_get_cred (svc, inst, rlm, cred); +} + +long mk_private_msg (in,out,in_length,schedule,key,sender,receiver) + u_char *in, *out; + u_long in_length; + Key_schedule schedule; + C_Block key; + struct sockaddr_in *sender, *receiver; +{ + return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver); +} + +long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data) + u_char *in; + u_long in_length; + Key_schedule schedule; + C_Block key; + struct sockaddr_in *sender, *receiver; + MSG_DAT *msg_data; +{ + return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data); +} + +long mk_safe_msg (in,out,in_length,key,sender,receiver) + u_char *in, *out; + u_long in_length; + C_Block *key; + struct sockaddr_in *sender, *receiver; +{ + return krb_mk_safe (in,out,in_length,key,sender,receiver); +} + +long rd_safe_msg (in,length,key,sender,receiver,msg_data) + u_char *in; + u_long length; + C_Block *key; + struct sockaddr_in *sender, *receiver; + MSG_DAT *msg_data; +{ + return krb_rd_safe (in,length,key,sender,receiver,msg_data); +} + +long mk_appl_err_msg (out,code,string) + u_char *out; + long code; + char *string; +{ + return krb_mk_err (out,code,string); +} + +long rd_appl_err_msg (in,length,code,msg_data) + u_char *in; + u_long length; + long *code; + MSG_DAT *msg_data; +{ + return krb_rd_err (in,length,code,msg_data); +} + +int get_in_tkt(user,instance,realm,service,sinstance,life,password) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *password; +{ + return krb_get_pw_in_tkt(user,instance,realm,service,sinstance, + life,password); +} + +int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *srvtab; +{ + return krb_get_svc_in_tkt(user, instance, realm, service, sinstance, + life, srvtab); +} + +int get_pw_tkt(user,instance,realm,cpw) + char *user; + char *instance; + char *realm; + char *cpw; +{ + return krb_get_pw_tkt(user,instance,realm,cpw); +} + +int +get_krbrlm (r, n) +char *r; +int n; +{ + return krb_get_lream(r,n); +} + +int +krb_getrealm (host) +{ + return krb_realmofhost(host); +} + +char * +get_phost (host) +char *host +{ + return krb_get_phost(host); +} + +int +get_krbhst (h, r, n) +char *h; +char *r; +int n; +{ + return krb_get_krbhst(h,r,n); +} +#ifdef DEBUG +struct ktext *create_death_packet(a_name) + char *a_name; +{ + return krb_create_death_packet(a_name); +} +#endif /* DEBUG */ + +#if 0 +extern int krb_ck_repl (); + +int check_replay () +{ + return krb_ck_repl (); +} +#endif +#endif /* NCOMPAT */ diff --git a/eBones/krb/kuserok.3 b/eBones/krb/kuserok.3 new file mode 100644 index 0000000..36968ba --- /dev/null +++ b/eBones/krb/kuserok.3 @@ -0,0 +1,63 @@ +.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $ +.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kuserok \- Kerberos version of ruserok +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +kuserok(kdata, localuser) +AUTH_DAT *auth_data; +char *localuser; +.fi +.ft R +.SH DESCRIPTION +.I kuserok +determines whether a Kerberos principal described by the structure +.I auth_data +is authorized to login as user +.I localuser +according to the authorization file +("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized, +1 (one) if not authorized. +.PP +If there is no account for +.I localuser +on the local machine, authorization is not granted. +If there is no authorization file, and the Kerberos principal described +by +.I auth_data +translates to +.I localuser +(using +.IR krb_kntoln (3)), +authorization is granted. +If the authorization file +can't be accessed, or the file is not owned by +.IR localuser, +authorization is denied. Otherwise, the file is searched for +a matching principal name, instance, and realm. If a match is found, +authorization is granted, else authorization is denied. +.PP +The file entries are in the format: +.nf +.in +5n + name.instance@realm +.in -5n +.fi +with one entry per line. +.SH SEE ALSO +kerberos(3), ruserok(3), krb_kntoln(3) +.SH FILES +.TP 20n +~\fIlocaluser\fR/.klogin +authorization list diff --git a/eBones/krb/kuserok.c b/eBones/krb/kuserok.c new file mode 100644 index 0000000..cb1f708 --- /dev/null +++ b/eBones/krb/kuserok.c @@ -0,0 +1,195 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * kuserok: check if a kerberos principal has + * access to a local account + * + * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $ + * $Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <stdio.h> +#include <pwd.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <strings.h> + +#define OK 0 +#define NOTOK 1 +#define MAX_USERNAME 10 + +/* + * Given a Kerberos principal "kdata", and a local username "luser", + * determine whether user is authorized to login according to the + * authorization file ("~luser/.klogin" by default). Returns OK + * if authorized, NOTOK if not authorized. + * + * If there is no account for "luser" on the local machine, returns + * NOTOK. If there is no authorization file, and the given Kerberos + * name "kdata" translates to the same name as "luser" (using + * krb_kntoln()), returns OK. Otherwise, if the authorization file + * can't be accessed, returns NOTOK. Otherwise, the file is read for + * a matching principal name, instance, and realm. If one is found, + * returns OK, if none is found, returns NOTOK. + * + * The file entries are in the format: + * + * name.instance@realm + * + * one entry per line. + * + * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin + * file entries. See the file "kparse.c". + */ + +#ifdef ATHENA_COMPAT + +#include <kparse.h> + +/* + * The parmtable defines the keywords we will recognize with their + * default values, and keeps a pointer to the found value. The found + * value should be filled in with strsave(), since FreeParameterSet() + * will release memory for all non-NULL found strings. + * +*** NOTE WELL! *** + * + * The table below is very nice, but we cannot hard-code a default for the + * realm: we have to get the realm via krb_get_lrealm(). Even though the + * default shows as "from krb_get_lrealm, below", it gets changed in + * kuserok to whatever krb_get_lrealm() tells us. That code assumes that + * the realm will be the entry number in the table below, so if you + * change the order of the entries below, you have to change the + * #definition of REALM_SCRIPT to reflect it. + */ +#define REALM_SUBSCRIPT 1 +parmtable kparm[] = { + +/* keyword default found value */ +{"user", "", (char *) NULL}, +{"realm", "see krb_get_lrealm, below", (char *) NULL}, +{"instance", "", (char *) NULL}, +}; +#define KPARMS kparm,PARMCOUNT(kparm) +#endif ATHENA_COMPAT + +kuserok(kdata, luser) + AUTH_DAT *kdata; + char *luser; +{ + struct stat sbuf; + struct passwd *pwd; + char pbuf[MAXPATHLEN]; + int isok = NOTOK, rc; + FILE *fp; + char kuser[MAX_USERNAME]; + char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; + char linebuf[BUFSIZ]; + char *newline; + int gobble; +#ifdef ATHENA_COMPAT + char local_realm[REALM_SZ]; +#endif ATHENA_COMPAT + + /* no account => no access */ + if ((pwd = getpwnam(luser)) == NULL) { + return(NOTOK); + } + (void) strcpy(pbuf, pwd->pw_dir); + (void) strcat(pbuf, "/.klogin"); + + if (access(pbuf, F_OK)) { /* not accessible */ + /* + * if he's trying to log in as himself, and there is no .klogin file, + * let him. To find out, call + * krb_kntoln to convert the triple in kdata to a name which we can + * string compare. + */ + if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) { + return(OK); + } + } + /* open ~/.klogin */ + if ((fp = fopen(pbuf, "r")) == NULL) { + return(NOTOK); + } + /* + * security: if the user does not own his own .klogin file, + * do not grant access + */ + if (fstat(fileno(fp), &sbuf)) { + fclose(fp); + return(NOTOK); + } + if (sbuf.st_uid != pwd->pw_uid) { + fclose(fp); + return(NOTOK); + } + +#ifdef ATHENA_COMPAT + /* Accept old-style .klogin files */ + + /* + * change the default realm from the hard-coded value to the + * accepted realm that Kerberos specifies. + */ + rc = krb_get_lrealm(local_realm, 1); + if (rc == KSUCCESS) + kparm[REALM_SUBSCRIPT].defvalue = local_realm; + else + return (rc); + + /* check each line */ + while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) { + switch (rc) { + case PS_BAD_KEYWORD: + case PS_SYNTAX: + while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n')); + break; + + case PS_OKAY: + isok = (ParmCompare(KPARMS, "user", kdata->pname) || + ParmCompare(KPARMS, "instance", kdata->pinst) || + ParmCompare(KPARMS, "realm", kdata->prealm)); + break; + + default: + break; + } + FreeParameterSet(kparm, PARMCOUNT(kparm)); + } + /* reset the stream for parsing new-style names, if necessary */ + rewind(fp); +#endif ATHENA_COMPAT + + /* check each line */ + while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) { + /* null-terminate the input string */ + linebuf[BUFSIZ-1] = '\0'; + newline = NULL; + /* nuke the newline if it exists */ + if (newline = index(linebuf, '\n')) + *newline = '\0'; + rc = kname_parse(principal, inst, realm, linebuf); + if (rc == KSUCCESS) { + isok = (strncmp(kdata->pname, principal, ANAME_SZ) || + strncmp(kdata->pinst, inst, INST_SZ) || + strncmp(kdata->prealm, realm, REALM_SZ)); + } + /* clean up the rest of the line if necessary */ + if (!newline) + while (((gobble = getc(fp)) != EOF) && gobble != '\n'); + } + fclose(fp); + return(isok); +} diff --git a/eBones/krb/log.c b/eBones/krb/log.c new file mode 100644 index 0000000..42fccfb --- /dev/null +++ b/eBones/krb/log.c @@ -0,0 +1,121 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $ + * $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> +#include <krb.h> +#include <klog.h> + +static char *log_name = KRBLOG; +static is_open; + +/* + * This file contains three logging routines: set_logfile() + * to determine the file that log entries should be written to; + * and log() and new_log() to write log entries to the file. + */ + +/* + * log() is used to add entries to the logfile (see set_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format". + * + * The log file is opened and closed for each log entry. + * + * The return value is undefined. + */ + +__BEGIN_DECLS +char *month_sname __P((int)); +__END_DECLS + + +/*VARARGS1 */ +void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0) + char *format; + int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0; +{ + FILE *logfile, *fopen(); + long time(),now; + struct tm *tm; + + if ((logfile = fopen(log_name,"a")) == NULL) + return; + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + fprintf(logfile,"\n"); + (void) fclose(logfile); + return; +} + +/* + * set_logfile() changes the name of the file to which + * messages are logged. If set_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +set_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} + +/* + * new_log() appends a log entry containing the give time "t" and the + * string "string" to the logfile (see set_logfile() above). The file + * is opened once and left open. The routine returns 1 on failure, 0 + * on success. + */ + +new_log(t,string) + long t; + char *string; +{ + static FILE *logfile; + + long time(); + struct tm *tm; + + if (!is_open) { + if ((logfile = fopen(log_name,"a")) == NULL) return(1); + is_open = 1; + } + + if (t) { + tm = localtime(&t); + + fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec, string); + } + else { + fprintf(logfile,"\n%20s%s","",string); + } + + (void) fflush(logfile); + return(0); +} diff --git a/eBones/krb/mk_err.c b/eBones/krb/mk_err.c new file mode 100644 index 0000000..331cba9 --- /dev/null +++ b/eBones/krb/mk_err.c @@ -0,0 +1,63 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $ + * $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/types.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine creates a general purpose error reply message. It + * doesn't use KTEXT because application protocol may have long + * messages, and may want this part of buffer contiguous to other + * stuff. + * + * The error reply is built in "p", using the error code "e" and + * error text "e_string" given. The length of the error reply is + * returned. + * + * The error reply is in the following format: + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_ERR message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte order + * 4 bytes e given error code + * string e_string given error text + */ + +long krb_mk_err(p,e,e_string) + u_char *p; /* Where to build error packet */ + long e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *start; + + start = p; + + /* Create fixed part of packet */ + *p++ = (unsigned char) KRB_PROT_VERSION; + *p = (unsigned char) AUTH_MSG_APPL_ERR; + *p++ |= HOST_BYTE_ORDER; + + /* Add the basic info */ + bcopy((char *)&e,(char *)p,4); /* err code */ + p += sizeof(e); + (void) strcpy((char *)p,e_string); /* err text */ + p += strlen(e_string); + + /* And return the length */ + return p-start; +} diff --git a/eBones/krb/mk_priv.c b/eBones/krb/mk_priv.c new file mode 100644 index 0000000..3bae4ed --- /dev/null +++ b/eBones/krb/mk_priv.c @@ -0,0 +1,203 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine constructs a Kerberos 'private msg', i.e. + * cryptographically sealed with a private session key. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT. + * + * Note-- It's too bad that it did a long int compare on the RT before. + * + * Returns either < 0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + * + * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $ + * $Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + + +static u_long c_length; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes + * some user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address. +#ifndef NOENCRYTION + * The packet is encrypted by pcbc_encrypt(), using the given + * "key" and "schedule". +#endif + * The length of the resulting packet "out" is + * returned. + * + * It is similar to krb_mk_safe() except for the additional key + * schedule argument "schedule" and the fact that the data is encrypted + * rather than appended with a checksum. Also, the protocol version + * number is "private_msg_ver", defined in krb_rd_priv.c, rather than + * KRB_PROT_VERSION, defined in "krb.h". + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte private_msg_ver protocol version number + * 1 byte AUTH_MSG_PRIVATE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * 4 bytes c_length length of data +#ifndef NOENCRYPT + * we encrypt from here with pcbc_encrypt +#endif + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * 0<=n<=7 bytes pad to 8 byte multiple zeroes + */ + +long krb_mk_priv(in,out,length,schedule,key,sender,receiver) + u_char *in; /* application data */ + u_char *out; /* put msg here, leave room for + * header! breaks if in and out + * (header stuff) overlap */ + u_long length; /* of in data */ + Key_schedule schedule; /* precomputed key schedule */ + C_Block key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + static u_char *c_length_ptr; + extern int private_msg_ver; /* in krb_rd_priv.c */ + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = private_msg_ver; + *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER; + + /* calculate cipher length */ + c_length_ptr = p; + p += sizeof(c_length); + + q = p; + + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + +#ifdef NOENCRYPTION + /* make all the stuff contiguous for checksum */ +#else + /* make all the stuff contiguous for checksum and encryption */ +#endif + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *)&sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok + * until 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + +#ifdef notdef + /* + * calculate the checksum of the length, address, sequence, and + * inp data + */ + cksum = quad_cksum(q,NULL,p-q,0,key); + if (krb_debug) + printf("\ncksum = %u",cksum); + /* stuff checksum */ + bcopy((char *) &cksum,(char *) p,sizeof(cksum)); + p += sizeof(cksum); +#endif + + /* + * All the data have been assembled, compute length + */ + + c_length = p - q; + c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) * + sizeof(C_Block); + /* stuff the length */ + bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length)); + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT); +#endif /* NOENCRYPTION */ + + return (q - out + c_length); /* resulting size */ +} diff --git a/eBones/krb/mk_req.c b/eBones/krb/mk_req.c new file mode 100644 index 0000000..bb0f097 --- /dev/null +++ b/eBones/krb/mk_req.c @@ -0,0 +1,195 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $ + * $Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <des.h> +#include <sys/time.h> +#include <strings.h> + +extern int krb_ap_req_debug; +static struct timeval tv_local = { 0, 0 }; +static int lifetime = DEFAULT_TKT_LIFE; + +/* + * krb_mk_req takes a text structure in which an authenticator is to + * be built, the name of a service, an instance, a realm, + * and a checksum. It then retrieves a ticket for + * the desired service and creates an authenticator in the text + * structure passed as the first argument. krb_mk_req returns + * KSUCCESS on success and a Kerberos error code on failure. + * + * The peer procedure on the other end is krb_rd_req. When making + * any changes to this routine it is important to make corresponding + * changes to krb_rd_req. + * + * The authenticator consists of the following: + * + * authent->dat + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_REQUEST message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte ordering + * unsigned char kvno from ticket server's key version + * string realm server's realm + * unsigned char tl ticket length + * unsigned char idl request id length + * text ticket->dat ticket for server + * text req_id->dat request id + * + * The ticket information is retrieved from the ticket cache or + * fetched from Kerberos. The request id (called the "authenticator" + * in the papers on Kerberos) contains the following: + * + * req_id->dat + * + * string cr.pname {name, instance, and + * string cr.pinst realm of principal + * string myrealm making this request} + * 4 bytes checksum checksum argument given + * unsigned char tv_local.tf_usec time (milliseconds) + * 4 bytes tv_local.tv_sec time (seconds) + * + * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time, + * all rounded up to multiple of 8. + */ + +krb_mk_req(authent,service,instance,realm,checksum) + register KTEXT authent; /* Place to build the authenticator */ + char *service; /* Name of the service */ + char *instance; /* Service instance */ + char *realm; /* Authentication domain of service */ + long checksum; /* Checksum of data (optional) */ +{ + static KTEXT_ST req_st; /* Temp storage for req id */ + register KTEXT req_id = &req_st; + unsigned char *v = authent->dat; /* Prot version number */ + unsigned char *t = (authent->dat+1); /* Message type */ + unsigned char *kv = (authent->dat+2); /* Key version no */ + unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */ + unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */ + CREDENTIALS cr; /* Credentials used by retr */ + register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */ + int retval; /* Returned by krb_get_cred */ + static Key_schedule key_s; + char myrealm[REALM_SZ]; + + /* The fixed parts of the authenticator */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_APPL_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Get the ticket and move it into the authenticator */ + if (krb_ap_req_debug) + printf("Realm: %s\n",realm); + /* + * Determine realm of these tickets. We will send this to the + * KDC from which we are requesting tickets so it knows what to + * with our session key. + */ + if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS) + return(retval); + + retval = krb_get_cred(service,instance,realm,&cr); + + if (retval == RET_NOTKT) { + if (retval = get_ad_tkt(service,instance,realm,lifetime)) + return(retval); + if (retval = krb_get_cred(service,instance,realm,&cr)) + return(retval); + } + + if (retval != KSUCCESS) return (retval); + + if (krb_ap_req_debug) + printf("%s %s %s %s %s\n", service, instance, realm, + cr.pname, cr.pinst); + *kv = (unsigned char) cr.kvno; + (void) strcpy((char *)(authent->dat+3),realm); + *tl = (unsigned char) ticket->length; + bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)), + ticket->length); + authent->length = 6 + strlen(realm) + ticket->length; + if (krb_ap_req_debug) + printf("Ticket->length = %d\n",ticket->length); + if (krb_ap_req_debug) + printf("Issue date: %d\n",cr.issue_date); + + /* Build request id */ + (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */ + req_id->length = strlen(cr.pname)+1; + /* Principal's instance */ + (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst); + req_id->length += strlen(cr.pinst)+1; + /* Authentication domain */ + (void) strcpy((char *)(req_id->dat+req_id->length),myrealm); + req_id->length += strlen(myrealm)+1; + /* Checksum */ + bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4); + req_id->length += 4; + + /* Fill in the times on the request id */ + (void) gettimeofday(&tv_local,(struct timezone *) 0); + *(req_id->dat+(req_id->length)++) = + (unsigned char) tv_local.tv_usec; + /* Time (coarse) */ + bcopy((char *)&(tv_local.tv_sec), + (char *)(req_id->dat+req_id->length), 4); + req_id->length += 4; + + /* Fill to a multiple of 8 bytes for DES */ + req_id->length = ((req_id->length+7)/8)*8; + +#ifndef NOENCRYPTION + key_sched(cr.session,key_s); + pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat, + (long)req_id->length,key_s,cr.session,ENCRYPT); + bzero((char *) key_s, sizeof(key_s)); +#endif /* NOENCRYPTION */ + + /* Copy it into the authenticator */ + bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length), + req_id->length); + authent->length += req_id->length; + /* And set the id length */ + *idl = (unsigned char) req_id->length; + /* clean up */ + bzero((char *)req_id, sizeof(*req_id)); + + if (krb_ap_req_debug) + printf("Authent->length = %d\n",authent->length); + if (krb_ap_req_debug) + printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl); + + return(KSUCCESS); +} + +/* + * krb_set_lifetime sets the default lifetime for additional tickets + * obtained via krb_mk_req(). + * + * It returns the previous value of the default lifetime. + */ + +int +krb_set_lifetime(newval) +int newval; +{ + int olife = lifetime; + + lifetime = newval; + return(olife); +} diff --git a/eBones/krb/mk_safe.c b/eBones/krb/mk_safe.c new file mode 100644 index 0000000..567004b --- /dev/null +++ b/eBones/krb/mk_safe.c @@ -0,0 +1,168 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine constructs a Kerberos 'safe msg', i.e. authenticated + * using a private session key to seed a checksum. Msg is NOT + * encrypted. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT + * + * Returns either <0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + * + * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $ + * $Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static u_long cksum; +static C_Block big_cksum[2]; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some + * user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address, followed by a checksum computed on the above, using the + * given "key". The length of the resulting packet is returned. + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_SAFE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * ===================== begin checksum ================================ + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * ======================= end checksum ================================ + * + * 16 bytes big_cksum quadratic checksum of + * above using "key" + */ + +long krb_mk_safe(in,out,length,key,sender,receiver) + u_char *in; /* application data */ + u_char *out; /* + * put msg here, leave room for header! + * breaks if in and out (header stuff) + * overlap + */ + u_long length; /* of in data */ + C_Block *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = KRB_PROT_VERSION; + *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER; + + q = p; /* start for checksum stuff */ + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + + /* make all the stuff contiguous for checksum */ + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *) &sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok until + * 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* + * all that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + +#ifdef NOENCRYPTION + cksum = 0; + bzero(big_cksum, sizeof(big_cksum)); +#else + cksum=quad_cksum(q,big_cksum,p-q,2,key); +#endif + if (krb_debug) + printf("\ncksum = %u",cksum); + + /* stuff checksum */ + bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum)); + p += sizeof(big_cksum); + + return ((long)(p - out)); /* resulting size */ + +} diff --git a/eBones/krb/month_sname.c b/eBones/krb/month_sname.c new file mode 100644 index 0000000..e7a63ec --- /dev/null +++ b/eBones/krb/month_sname.c @@ -0,0 +1,31 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $ + * $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $"; +#endif /* lint */ + + +/* + * Given an integer 1-12, month_sname() returns a string + * containing the first three letters of the corresponding + * month. Returns 0 if the argument is out of range. + */ + +char *month_sname(n) + int n; +{ + static char *name[] = { + "Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec" + }; + return((n < 1 || n > 12) ? 0 : name [n-1]); +} diff --git a/eBones/krb/netread.c b/eBones/krb/netread.c new file mode 100644 index 0000000..eb86327 --- /dev/null +++ b/eBones/krb/netread.c @@ -0,0 +1,46 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $ + * $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $"; +#endif lint + +/* + * krb_net_read() reads from the file descriptor "fd" to the buffer + * "buf", until either 1) "len" bytes have been read or 2) cannot + * read anymore from "fd". It returns the number of bytes read + * or a read() error. (The calling interface is identical to + * read(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_read(fd, buf, len) +int fd; +register char *buf; +register int len; +{ + int cc, len2 = 0; + + do { + cc = read(fd, buf, len); + if (cc < 0) + return(cc); /* errno is already set */ + else if (cc == 0) { + return(len2); + } else { + buf += cc; + len2 += cc; + len -= cc; + } + } while (len > 0); + return(len2); +} diff --git a/eBones/krb/netwrite.c b/eBones/krb/netwrite.c new file mode 100644 index 0000000..5945ce0 --- /dev/null +++ b/eBones/krb/netwrite.c @@ -0,0 +1,42 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $"; + * $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $"; +#endif lint + +/* + * krb_net_write() writes "len" bytes from "buf" to the file + * descriptor "fd". It returns the number of bytes written or + * a write() error. (The calling interface is identical to + * write(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_write(fd, buf, len) +int fd; +register char *buf; +int len; +{ + int cc; + register int wrlen = len; + do { + cc = write(fd, buf, wrlen); + if (cc < 0) + return(cc); + else { + buf += cc; + wrlen -= cc; + } + } while (wrlen > 0); + return(len); +} diff --git a/eBones/krb/one.c b/eBones/krb/one.c new file mode 100644 index 0000000..c0e8bc6 --- /dev/null +++ b/eBones/krb/one.c @@ -0,0 +1,20 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $ + * $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $"; +#endif lint + +/* + * definition of variable set to 1. + * used in krb_conf.h to determine host byte order. + */ + +int krbONE = 1; diff --git a/eBones/krb/pkt_cipher.c b/eBones/krb/pkt_cipher.c new file mode 100644 index 0000000..6ef870c --- /dev/null +++ b/eBones/krb/pkt_cipher.c @@ -0,0 +1,38 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $ + * $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + + +/* + * This routine takes a reply packet from the Kerberos ticket-granting + * service and returns a pointer to the beginning of the ciphertext in it. + * + * See "prot.h" for packet format. + */ + +KTEXT +pkt_cipher(packet) + KTEXT packet; +{ + unsigned char *ptr = pkt_a_realm(packet) + 6 + + strlen((char *)pkt_a_realm(packet)); + /* Skip a few more fields */ + ptr += 3 + 4; /* add 4 for exp_date */ + + /* And return the pointer */ + return((KTEXT) ptr); +} diff --git a/eBones/krb/pkt_clen.c b/eBones/krb/pkt_clen.c new file mode 100644 index 0000000..23ad4c3 --- /dev/null +++ b/eBones/krb/pkt_clen.c @@ -0,0 +1,53 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $ + * $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +extern int krb_debug; +extern int swap_bytes; + +/* + * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of + * its ciphertext portion. The external variable "swap_bytes" is assumed + * to have been set to indicate whether or not the packet is in local + * byte order. pkt_clen() takes this into account when reading the + * ciphertext length out of the packet. + */ + +pkt_clen(pkt) + KTEXT pkt; +{ + static unsigned short temp,temp2; + int clen = 0; + + /* Start of ticket list */ + unsigned char *ptr = pkt_a_realm(pkt) + 10 + + strlen((char *)pkt_a_realm(pkt)); + + /* Finally the length */ + bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */ + if (swap_bytes) { + /* assume a short is 2 bytes?? */ + swab((char *)&temp,(char *)&temp2,2); + temp = temp2; + } + + clen = (int) temp; + + if (krb_debug) + printf("Clen is %d\n",clen); + return(clen); +} diff --git a/eBones/krb/rd_err.c b/eBones/krb/rd_err.c new file mode 100644 index 0000000..e73c47b --- /dev/null +++ b/eBones/krb/rd_err.c @@ -0,0 +1,79 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'safe msg', + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $ + * $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <krb.h> +#include <prot.h> + +/* + * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length", + * return the error code from the message in "code" and the text in + * "m_data" as follows: + * + * m_data->app_data points to the error text + * m_data->app_length points to the length of the error text + * + * If all goes well, return RD_AP_OK. If the version number + * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR + * type message, return RD_AP_MSG_TYPE. + * + * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c + */ + +int +krb_rd_err(in,in_length,code,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* of in msg */ + long *code; /* received error code */ + MSG_DAT *m_data; +{ + register u_char *p; + int swap_bytes = 0; + p = in; /* beginning of message */ + + if (*p++ != KRB_PROT_VERSION) + return(RD_AP_VERSION); + if (((*p) & ~1) != AUTH_MSG_APPL_ERR) + return(RD_AP_MSG_TYPE); + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* safely get code */ + bcopy((char *)p,(char *)code,sizeof(*code)); + if (swap_bytes) + swap_u_long(*code); + p += sizeof(*code); /* skip over */ + + m_data->app_data = p; /* we're now at the error text + * message */ + m_data->app_length = in_length; + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/eBones/krb/rd_priv.c b/eBones/krb/rd_priv.c new file mode 100644 index 0000000..9adefec --- /dev/null +++ b/eBones/krb/rd_priv.c @@ -0,0 +1,204 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'private msg', decrypting it, + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If + * the return value is RD_AP_TIME, then either the times are too far + * out of synch, OR the packet was modified. + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $ + * $Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[]= +"$Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static u_long c_length; +static int swap_bytes; +static struct timeval local_time; +static long delta_t; +int private_msg_ver = KRB_PROT_VERSION; + +/* +#ifdef NOENCRPYTION + * krb_rd_priv() checks the integrity of an +#else + * krb_rd_priv() decrypts and checks the integrity of an +#endif + * AUTH_MSG_PRIVATE message. Given the message received, "in", + * the length of that message, "in_length", the key "schedule" + * and "key", and the network addresses of the + * "sender" and "receiver" of the message, krb_rd_safe() returns + * RD_AP_OK if the message is okay, otherwise some error code. + * + * The message data retrieved from "in" are returned in the structure + * "m_data". The pointer to the application data + * (m_data->app_data) refers back to the appropriate place in "in". + * + * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* length of "in" msg */ + Key_schedule schedule; /* precomputed key schedule */ + C_Block key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; + struct sockaddr_in *receiver; + MSG_DAT *m_data; /*various input/output data from msg */ +{ + register u_char *p,*q; + static u_long src_addr; /* Can't send structs since no + * guarantees on size */ + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION && *(p-1) != 3) + return RD_AP_VERSION; + private_msg_ver = *(p-1); + if (((*p) & ~1) != AUTH_MSG_PRIVATE) + return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* get cipher length */ + bcopy((char *)p,(char *)&c_length,sizeof(c_length)); + if (swap_bytes) + swap_u_long(c_length); + p += sizeof(c_length); + /* check for rational length so we don't go comatose */ + if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length) + return RD_AP_MODIFIED; + + + q = p; /* mark start of encrypted stuff */ + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT); +#endif + + /* safely get application data length */ + bcopy((char *) p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) + swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(c_length) + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ + > in_length) + return RD_AP_MODIFIED; + +#ifndef NOENCRYPTION + /* we're now at the decrypted application data */ +#endif + m_data->app_data = p; + + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *) p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *) p,(char *)&src_addr,sizeof(src_addr)); + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (src_addr != (u_long) sender->sin_addr.s_addr) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *) p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) swap_u_long(m_data->time_sec); + + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + /* + * all that for one tiny bit! + * Heaven help those that talk to themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec + - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) + return RD_AP_TIME; + if (krb_debug) + printf("\ndelta_t = %d",delta_t); + + /* + * caller must check timestamps for proper order and + * replays, since server might have multiple clients + * each with its own timestamps and we don't assume + * tightly synchronized clocks. + */ + +#ifdef notdef + bcopy((char *) p,(char *)&cksum,sizeof(cksum)); + if (swap_bytes) swap_u_long(cksum) + /* + * calculate the checksum of the length, sequence, + * and input data, on the sending byte order!! + */ + calc_cksum = quad_cksum(q,NULL,p-q,0,key); + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + calc_cksum, cksum); + if (cksum != calc_cksum) + return RD_AP_MODIFIED; +#endif + return RD_AP_OK; /* OK == 0 */ +} diff --git a/eBones/krb/rd_req.c b/eBones/krb/rd_req.c new file mode 100644 index 0000000..22b6540 --- /dev/null +++ b/eBones/krb/rd_req.c @@ -0,0 +1,328 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $ + * $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $"; +#endif /* lint */ + +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <sys/time.h> +#include <strings.h> + +extern int krb_ap_req_debug; + +static struct timeval t_local = { 0, 0 }; + +/* + * Keep the following information around for subsequent calls + * to this routine by the same server using the same key. + */ + +static Key_schedule serv_key; /* Key sched to decrypt ticket */ +static C_Block ky; /* Initialization vector */ +static int st_kvno; /* version number for this key */ +static char st_rlm[REALM_SZ]; /* server's realm */ +static char st_nam[ANAME_SZ]; /* service name */ +static char st_inst[INST_SZ]; /* server's instance */ + +/* + * This file contains two functions. krb_set_key() takes a DES + * key or password string and returns a DES key (either the original + * key, or the password converted into a DES key) and a key schedule + * for it. + * + * krb_rd_req() reads an authentication request and returns information + * about the identity of the requestor, or an indication that the + * identity information was not authentic. + */ + +/* + * krb_set_key() takes as its first argument either a DES key or a + * password string. The "cvt" argument indicates how the first + * argument "key" is to be interpreted: if "cvt" is null, "key" is + * taken to be a DES key; if "cvt" is non-null, "key" is taken to + * be a password string, and is converted into a DES key using + * string_to_key(). In either case, the resulting key is returned + * in the external static variable "ky". A key schedule is + * generated for "ky" and returned in the external static variable + * "serv_key". + * + * This routine returns the return value of des_key_sched. + * + * krb_set_key() needs to be in the same .o file as krb_rd_req() so that + * the key set by krb_set_key() is available in private storage for + * krb_rd_req(). + */ + +int +krb_set_key(key,cvt) + char *key; + int cvt; +{ +#ifdef NOENCRYPTION + bzero(ky, sizeof(ky)); + return KSUCCESS; +#else + if (cvt) + string_to_key(key,ky); + else + bcopy(key,(char *)ky,8); + return(des_key_sched(ky,serv_key)); +#endif +} + + +/* + * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or + * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), + * checks its integrity and returns a judgement as to the requestor's + * identity. + * + * The "authent" argument is a pointer to the received message. + * The "service" and "instance" arguments name the receiving server, + * and are used to get the service's ticket to decrypt the ticket + * in the message, and to compare against the server name inside the + * ticket. "from_addr" is the network address of the host from which + * the message was received; this is checked against the network + * address in the ticket. If "from_addr" is zero, the check is not + * performed. "ad" is an AUTH_DAT structure which is + * filled in with information about the sender's identity according + * to the authenticator and ticket sent in the message. Finally, + * "fn" contains the name of the file containing the server's key. + * (If "fn" is NULL, the server's key is assumed to have been set + * by krb_set_key(). If "fn" is the null string ("") the default + * file KEYFILE, defined in "krb.h", is used.) + * + * krb_rd_req() returns RD_AP_OK if the authentication information + * was genuine, or one of the following error codes (defined in + * "krb.h"): + * + * RD_AP_VERSION - wrong protocol version number + * RD_AP_MSG_TYPE - wrong message type + * RD_AP_UNDEC - couldn't decipher the message + * RD_AP_INCON - inconsistencies found + * RD_AP_BADD - wrong network address + * RD_AP_TIME - client time (in authenticator) + * too far off server time + * RD_AP_NYV - Kerberos time (in ticket) too + * far off server time + * RD_AP_EXP - ticket expired + * + * For the message format, see krb_mk_req(). + * + * Mutual authentication is not implemented. + */ + +krb_rd_req(authent,service,instance,from_addr,ad,fn) + register KTEXT authent; /* The received message */ + char *service; /* Service name */ + char *instance; /* Service instance */ + long from_addr; /* Net address of originating host */ + AUTH_DAT *ad; /* Structure to be filled in */ + char *fn; /* Filename to get keys from */ +{ + static KTEXT_ST ticket; /* Temp storage for ticket */ + static KTEXT tkt = &ticket; + static KTEXT_ST req_id_st; /* Temp storage for authenticator */ + register KTEXT req_id = &req_id_st; + + char realm[REALM_SZ]; /* Realm of issuing kerberos */ + static Key_schedule seskey_sched; /* Key sched for session key */ + unsigned char skey[KKEY_SZ]; /* Session key from ticket */ + char sname[SNAME_SZ]; /* Service name from ticket */ + char iname[INST_SZ]; /* Instance name from ticket */ + char r_aname[ANAME_SZ]; /* Client name from authenticator */ + char r_inst[INST_SZ]; /* Client instance from authenticator */ + char r_realm[REALM_SZ]; /* Client realm from authenticator */ + unsigned int r_time_ms; /* Fine time from authenticator */ + unsigned long r_time_sec; /* Coarse time from authenticator */ + register char *ptr; /* For stepping through */ + unsigned long delta_t; /* Time in authenticator - local time */ + long tkt_age; /* Age of ticket */ + static int swap_bytes; /* Need to swap bytes? */ + static int mutual; /* Mutual authentication requested? */ + static unsigned char s_kvno;/* Version number of the server's key + * Kerberos used to encrypt ticket */ + int status; + + if (authent->length <= 0) + return(RD_AP_MODIFIED); + + ptr = (char *) authent->dat; + + /* get msg version, type and byte order, and server key version */ + + /* check version */ + if (KRB_PROT_VERSION != (unsigned int) *ptr++) + return(RD_AP_VERSION); + + /* byte order */ + swap_bytes = 0; + if ((*ptr & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* check msg type */ + mutual = 0; + switch (*ptr++ & ~1) { + case AUTH_MSG_APPL_REQUEST: + break; + case AUTH_MSG_APPL_REQUEST_MUTUAL: + mutual++; + break; + default: + return(RD_AP_MSG_TYPE); + } + +#ifdef lint + /* XXX mutual is set but not used; why??? */ + /* this is a crock to get lint to shut up */ + if (mutual) + mutual = 0; +#endif /* lint */ + s_kvno = *ptr++; /* get server key version */ + (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */ + ptr += strlen(ptr) + 1; /* skip the realm "hint" */ + + /* + * If "fn" is NULL, key info should already be set; don't + * bother with ticket file. Otherwise, check to see if we + * already have key info for the given server and key version + * (saved in the static st_* variables). If not, go get it + * from the ticket file. If "fn" is the null string, use the + * default ticket file. + */ + if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) || + strcmp(st_rlm,realm) || (st_kvno != s_kvno))) { + if (*fn == 0) fn = KEYFILE; + st_kvno = s_kvno; +#ifndef NOENCRYPTION + if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey)) + return(RD_AP_UNDEC); + if (status=krb_set_key((char *)skey,0)) return(status); +#endif + (void) strcpy(st_rlm,realm); + (void) strcpy(st_nam,service); + (void) strcpy(st_inst,instance); + } + + /* Get ticket from authenticator */ + tkt->length = (int) *ptr++; + if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr+1,(char *)(tkt->dat),tkt->length); + + if (krb_ap_req_debug) + log("ticket->length: %d",tkt->length); + +#ifndef NOENCRYPTION + /* Decrypt and take apart ticket */ +#endif + + if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, + &(ad->address),ad->session, &(ad->life), + &(ad->time_sec),sname,iname,ky,serv_key)) + return(RD_AP_UNDEC); + + if (krb_ap_req_debug) { + log("Ticket Contents."); + log(" Aname: %s.%s",ad->pname, + ((int)*(ad->prealm) ? ad->prealm : "Athena")); + log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname); + } + + /* Extract the authenticator */ + req_id->length = (int) *(ptr++); + if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) > + authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length); + +#ifndef NOENCRYPTION + key_sched(ad->session,seskey_sched); + pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat, + (long)req_id->length,seskey_sched,ad->session,DES_DECRYPT); +#endif /* NOENCRYPTION */ + +#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); + + ptr = (char *) req_id->dat; + (void) strcpy(r_aname,ptr); /* Authentication name */ + ptr += strlen(r_aname)+1; + check_ptr(); + (void) strcpy(r_inst,ptr); /* Authentication instance */ + ptr += strlen(r_inst)+1; + check_ptr(); + (void) strcpy(r_realm,ptr); /* Authentication name */ + ptr += strlen(r_realm)+1; + check_ptr(); + bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */ + ptr += 4; + check_ptr(); + if (swap_bytes) swap_u_long(ad->checksum); + r_time_ms = *(ptr++); /* Time (fine) */ +#ifdef lint + /* XXX r_time_ms is set but not used. why??? */ + /* this is a crock to get lint to shut up */ + if (r_time_ms) + r_time_ms = 0; +#endif /* lint */ + check_ptr(); + /* assume sizeof(r_time_sec) == 4 ?? */ + bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(r_time_sec); + + /* Check for authenticity of the request */ + if (krb_ap_req_debug) + log("Pname: %s %s",ad->pname,r_aname); + if (strcmp(ad->pname,r_aname) != 0) + return(RD_AP_INCON); + if (strcmp(ad->pinst,r_inst) != 0) + return(RD_AP_INCON); + if (krb_ap_req_debug) + log("Realm: %s %s",ad->prealm,r_realm); + if ((strcmp(ad->prealm,r_realm) != 0)) + return(RD_AP_INCON); + + if (krb_ap_req_debug) + log("Address: %d %d",ad->address,from_addr); + if (from_addr && (ad->address != from_addr)) + return(RD_AP_BADD); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + delta_t = abs((int)(t_local.tv_sec - r_time_sec)); + if (delta_t > CLOCK_SKEW) { + if (krb_ap_req_debug) + log("Time out of range: %d - %d = %d", + t_local.tv_sec,r_time_sec,delta_t); + return(RD_AP_TIME); + } + + /* Now check for expiration of ticket */ + + tkt_age = t_local.tv_sec - ad->time_sec; + if (krb_ap_req_debug) + log("Time: %d Issue Date: %d Diff: %d Life %x", + t_local.tv_sec,ad->time_sec,tkt_age,ad->life); + + if (t_local.tv_sec < ad->time_sec) { + if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW) + return(RD_AP_NYV); + } + else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life) + return(RD_AP_EXP); + + /* All seems OK */ + ad->reply.length = 0; + + return(RD_AP_OK); +} diff --git a/eBones/krb/rd_safe.c b/eBones/krb/rd_safe.c new file mode 100644 index 0000000..e500b4d --- /dev/null +++ b/eBones/krb/rd_safe.c @@ -0,0 +1,180 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'safe msg', checking its + * integrity, and returning a pointer to the application data + * contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $ + * $Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static C_Block calc_cksum[2]; +static C_Block big_cksum[2]; +static int swap_bytes; +static struct timeval local_time; +static u_long delta_t; + +/* + * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message. + * Given the message received, "in", the length of that message, + * "in_length", the "key" to compute the checksum with, and the + * network addresses of the "sender" and "receiver" of the message, + * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise + * some error code. + * + * The message data retrieved from "in" is returned in the structure + * "m_data". The pointer to the application data (m_data->app_data) + * refers back to the appropriate place in "in". + * + * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +long krb_rd_safe(in,in_length,key,sender,receiver,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* length of "in" msg */ + C_Block *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender's address */ + struct sockaddr_in *receiver; /* receiver's address -- me */ + MSG_DAT *m_data; /* where to put message information */ +{ + register u_char *p,*q; + static u_long src_addr; /* Can't send structs since no + * guarantees on size */ + /* Be very conservative */ + if (sizeof(u_long) != sizeof(struct in_addr)) { + fprintf(stderr,"\n\ +krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)"); + exit(-1); + } + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION; + if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++; + + q = p; /* mark start of cksum stuff */ + + /* safely get length */ + bcopy((char *)p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(big_cksum) + sizeof(src_addr) + + VERSION_SZ + MSG_TYPE_SZ > in_length) + return(RD_AP_MODIFIED); + + m_data->app_data = p; /* we're now at the application data */ + + /* skip app data */ + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *)p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *)p,(char *)&src_addr,sizeof(src_addr)); + + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (src_addr != (u_long) sender->sin_addr.s_addr) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *)p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) + swap_u_long(m_data->time_sec); + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) return RD_AP_TIME; + + /* + * caller must check timestamps for proper order and replays, since + * server might have multiple clients each with its own timestamps + * and we don't assume tightly synchronized clocks. + */ + + bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum)); + if (swap_bytes) swap_u_16(big_cksum); + +#ifdef NOENCRYPTION + bzero(calc_cksum, sizeof(calc_cksum)); +#else + quad_cksum(q,calc_cksum,p-q,2,key); +#endif + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + (long) calc_cksum[0], (long) big_cksum[0]); + if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum))) + return(RD_AP_MODIFIED); + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/eBones/krb/read_service_key.c b/eBones/krb/read_service_key.c new file mode 100644 index 0000000..4d66710 --- /dev/null +++ b/eBones/krb/read_service_key.c @@ -0,0 +1,120 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $ + * $Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <stdio.h> +#include <strings.h> + +/* + * The private keys for servers on a given host are stored in a + * "srvtab" file (typically "/etc/srvtab"). This routine extracts + * a given server's key from the file. + * + * read_service_key() takes the server's name ("service"), "instance", + * and "realm" and a key version number "kvno", and looks in the given + * "file" for the corresponding entry, and if found, returns the entry's + * key field in "key". + * + * If "instance" contains the string "*", then it will match + * any instance, and the chosen instance will be copied to that + * string. For this reason it is important that the there is enough + * space beyond the "*" to receive the entry. + * + * If "kvno" is 0, it is treated as a wild card and the first + * matching entry regardless of the "vno" field is returned. + * + * This routine returns KSUCCESS on success, otherwise KFAILURE. + * + * The format of each "srvtab" entry is as follows: + * + * Size Variable Field in file + * ---- -------- ------------- + * string serv server name + * string inst server instance + * string realm server realm + * 1 byte vno server key version # + * 8 bytes key server's key + * ... ... ... + */ + + +/*ARGSUSED */ +read_service_key(service,instance,realm,kvno,file,key) + char *service; /* Service Name */ + char *instance; /* Instance name or "*" */ + char *realm; /* Realm */ + int kvno; /* Key version number */ + char *file; /* Filename */ + char *key; /* Pointer to key to be filled in */ +{ + char serv[SNAME_SZ]; + char inst[INST_SZ]; + char rlm[REALM_SZ]; + unsigned char vno; /* Key version number */ + int wcard; + + int stab, open(); + + if ((stab = open(file, 0, 0)) < NULL) + return(KFAILURE); + + wcard = (instance[0] == '*') && (instance[1] == '\0'); + + while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */ + (void) getst(stab,inst,INST_SZ); /* Instance */ + (void) getst(stab,rlm,REALM_SZ); /* Realm */ + /* Vers number */ + if (read(stab,(char *)&vno,1) != 1) { + close(stab); + return(KFAILURE); + } + /* Key */ + if (read(stab,key,8) != 8) { + close(stab); + return(KFAILURE); + } + /* Is this the right service */ + if (strcmp(serv,service)) + continue; + /* How about instance */ + if (!wcard && strcmp(inst,instance)) + continue; + if (wcard) + (void) strncpy(instance,inst,INST_SZ); + /* Is this the right realm */ +#ifdef ATHENA_COMPAT + /* XXX For backward compatibility: if keyfile says "Athena" + and caller wants "ATHENA.MIT.EDU", call it a match */ + if (strcmp(rlm,realm) && + (strcmp(rlm,"Athena") || + strcmp(realm,"ATHENA.MIT.EDU"))) + continue; +#else /* ! ATHENA_COMPAT */ + if (strcmp(rlm,realm)) + continue; +#endif /* ATHENA_COMPAT */ + + /* How about the key version number */ + if (kvno && kvno != (int) vno) + continue; + + (void) close(stab); + return(KSUCCESS); + } + + /* Can't find the requested service */ + (void) close(stab); + return(KFAILURE); +} diff --git a/eBones/krb/recvauth.c b/eBones/krb/recvauth.c new file mode 100644 index 0000000..fe26814 --- /dev/null +++ b/eBones/krb/recvauth.c @@ -0,0 +1,286 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $"; + * $Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> + + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN + chars */ + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_sendauth.c + * be sure to support old versions of krb_sendauth! + */ + +extern int errno; + +/* + * krb_recvauth() reads (and optionally responds to) a message sent + * using krb_sendauth(). The "options" argument is a bit-field of + * selected options (see "sendauth.c" for options description). + * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL + * (mutual authentication requested). The "fd" argument supplies + * a file descriptor to read from (and write to, if mutual authenti- + * cation is requested). + * + * Part of the received message will be a Kerberos ticket sent by the + * client; this is read into the "ticket" argument. The "service" and + * "instance" arguments supply the server's Kerberos name. If the + * "instance" argument is the string "*", it is treated as a wild card + * and filled in during the krb_rd_req() call (see read_service_key()). + * + * The "faddr" and "laddr" give the sending (client) and receiving + * (local server) network addresses. ("laddr" may be left NULL unless + * mutual authentication is requested, in which case it must be set.) + * + * The authentication information extracted from the message is returned + * in "kdata". The "filename" argument indicates the file where the + * server's key can be found. (It is passed on to krb_rd_req().) If + * left null, the default "/etc/srvtab" will be used. + * + * If mutual authentication is requested, the session key schedule must + * be computed in order to reply; this schedule is returned in the + * "schedule" argument. A string containing the application version + * number from the received message is returned in "version", which + * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. + * + * See krb_sendauth() for the format of the received client message. + * + * This routine supports another client format, for backward + * compatibility, consisting of: + * + * Size Variable Field + * ---- -------- ----- + * + * string tmp_buf, tkt_len length of ticket, in + * ascii + * + * char ' ' (space char) separator + * + * tkt_len ticket->dat the ticket + * + * This old-style version does not support mutual authentication. + * + * krb_recvauth() first reads the protocol version string from the + * given file descriptor. If it doesn't match the current protocol + * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In + * that case, the string of characters up to the first space is read + * and interpreted as the ticket length, then the ticket is read. + * + * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() + * next reads the application protocol version string. Then the + * ticket length and ticket itself are read. + * + * The ticket is decrypted and checked by the call to krb_rd_req(). + * If no mutual authentication is required, the result of the + * krb_rd_req() call is retured by this routine. If mutual authenti- + * cation is required, a message in the following format is returned + * on "fd": + * + * Size Variable Field + * ---- -------- ----- + * + * 4 bytes tkt_len length of ticket or -1 + * if error occurred + * + * priv_len tmp_buf "private" message created + * by krb_mk_priv() which + * contains the incremented + * checksum sent by the client + * encrypted in the session + * key. (This field is not + * present in case of error.) + * + * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some + * other error code is returned. + */ + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif /* max */ + +int +krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, + filename, schedule, version) +long options; /* bit-pattern of options */ +int fd; /* file descr. to read from */ +KTEXT ticket; /* storage for client's ticket */ +char *service; /* service expected */ +char *instance; /* inst expected (may be filled in) */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +struct sockaddr_in *laddr; /* local address */ +AUTH_DAT *kdata; /* kerberos data (returned) */ +char *filename; /* name of file with service keys */ +Key_schedule schedule; /* key schedule (return) */ +char *version; /* version string (filled in) */ +{ + + int i, cc, old_vers = 0; + char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ + char *cp; + int rem; + long tkt_len, priv_len; + u_long cksum; + u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)]; + + /* read the protocol version number */ + if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + krb_vers[KRB_SENDAUTH_VLEN] = '\0'; + + /* check version string */ + if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) { + /* Assume the old version of sendkerberosdata: send ascii + length, ' ', and ticket. */ + if (options & KOPT_DO_MUTUAL) + return(KFAILURE); /* XXX can't do old style with mutual auth */ + old_vers = 1; + + /* copy what we have read into tmp_buf */ + (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN); + + /* search for space, and make it a null */ + for (i = 0; i < KRB_SENDAUTH_VLEN; i++) + if (tmp_buf[i]== ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + + if (i == KRB_SENDAUTH_VLEN) + /* didn't find the space, keep reading to find it */ + for (; i<20; i++) { + if (read(fd, (char *)&tmp_buf[i], 1) != 1) { + return(KFAILURE); + } + if (tmp_buf[i] == ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + } + + tkt_len = (long) atoi((char *) tmp_buf); + + /* sanity check the length */ + if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN)) + return(KFAILURE); + + if (i < KRB_SENDAUTH_VLEN) { + /* since we already got the space, and part of the ticket, + we read fewer bytes to get the rest of the ticket */ + if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), + (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + return(errno); + } else { + if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != + (int) tkt_len) + return(errno); + } + ticket->length = tkt_len; + /* copy the ticket into the struct */ + (void) bcopy(cp, (char *) ticket->dat, ticket->length); + + } else { + /* read the application version string */ + if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + version[KRB_SENDAUTH_VLEN] = '\0'; + + /* get the length of the ticket */ + if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + + /* sanity check */ + ticket->length = ntohl((unsigned long)tkt_len); + if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) { + if (options & KOPT_DO_MUTUAL) { + rem = KFAILURE; + goto mutual_fail; + } else + return(KFAILURE); /* XXX there may still be junk on the fd? */ + } + + /* read the ticket */ + if (krb_net_read(fd, (char *) ticket->dat, ticket->length) + != ticket->length) + return(errno); + } + /* + * now have the ticket. decrypt it to get the authenticated + * data. + */ + rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr, + kdata,filename); + + if (old_vers) return(rem); /* XXX can't do mutual with old client */ + + /* if we are doing mutual auth, compose a response */ + if (options & KOPT_DO_MUTUAL) { + if (rem != KSUCCESS) + /* the krb_rd_req failed */ + goto mutual_fail; + + /* add one to the (formerly) sealed checksum, and re-seal it + for return to the client */ + cksum = kdata->checksum + 1; + cksum = htonl(cksum); +#ifndef NOENCRYPTION + key_sched(kdata->session,schedule); +#endif + priv_len = krb_mk_priv((unsigned char *)&cksum, + tmp_buf, + (unsigned long) sizeof(cksum), + schedule, + kdata->session, + laddr, + faddr); + if (priv_len < 0) { + /* re-sealing failed; notify the client */ + rem = KFAILURE; /* XXX */ +mutual_fail: + priv_len = -1; + tkt_len = htonl((unsigned long) priv_len); + /* a length of -1 is interpreted as an authentication + failure by the client */ + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + return(rem); + } else { + /* re-sealing succeeded, send the private message */ + tkt_len = htonl((unsigned long)priv_len); + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len)) + != (int) priv_len) + return(cc); + } + } + return(rem); +} diff --git a/eBones/krb/save_credentials.c b/eBones/krb/save_credentials.c new file mode 100644 index 0000000..129c912 --- /dev/null +++ b/eBones/krb/save_credentials.c @@ -0,0 +1,53 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $ + * $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> + +/* + * This routine takes a ticket and associated info and calls + * tf_save_cred() to store them in the ticket cache. The peer + * routine for extracting a ticket and associated info from the + * ticket cache is krb_get_cred(). When changes are made to + * this routine, the corresponding changes should be made + * in krb_get_cred() as well. + * + * Returns KSUCCESS if all goes well, otherwise an error returned + * by the tf_init() or tf_save_cred() routines. + */ + +save_credentials(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + C_Block session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + long issue_date; /* The issue time */ +{ + int tf_status; /* return values of the tf_util calls */ + + /* Open and lock the ticket file for writing */ + if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Save credentials by appending to the ticket file */ + tf_status = tf_save_cred(service, instance, realm, session, + lifetime, kvno, ticket, issue_date); + (void) tf_close(); + return (tf_status); +} diff --git a/eBones/krb/send_to_kdc.c b/eBones/krb/send_to_kdc.c new file mode 100644 index 0000000..aeaf389 --- /dev/null +++ b/eBones/krb/send_to_kdc.c @@ -0,0 +1,313 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $ + * $Id: send_to_kdc.c,v 1.2 1994/07/19 19:26:21 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid_send_to_kdc_c[] = +"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp "; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#include <stdio.h> +#include <errno.h> +#include <sys/time.h> +#include <sys/types.h> +#ifdef lint +#include <sys/uio.h> /* struct iovec to make lint happy */ +#endif /* lint */ +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <strings.h> + +#define S_AD_SZ sizeof(struct sockaddr_in) + +extern int errno; +extern int krb_debug; + +extern char *malloc(), *calloc(), *realloc(); + +int krb_udp_port = 0; + +/* CLIENT_KRB_TIMEOUT indicates the time to wait before + * retrying a server. It's defined in "krb.h". + */ +static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0}; +static char *prog = "send_to_kdc"; +static send_recv(); + +/* + * This file contains two routines, send_to_kdc() and send_recv(). + * send_recv() is a static routine used by send_to_kdc(). + */ + +/* + * send_to_kdc() sends a message to the Kerberos authentication + * server(s) in the given realm and returns the reply message. + * The "pkt" argument points to the message to be sent to Kerberos; + * the "rpkt" argument will be filled in with Kerberos' reply. + * The "realm" argument indicates the realm of the Kerberos server(s) + * to transact with. If the realm is null, the local realm is used. + * + * If more than one Kerberos server is known for a given realm, + * different servers will be queried until one of them replies. + * Several attempts (retries) are made for each server before + * giving up entirely. + * + * If an answer was received from a Kerberos host, KSUCCESS is + * returned. The following errors can be returned: + * + * SKDC_CANT - can't get local realm + * - can't find "kerberos" in /etc/services database + * - can't open socket + * - can't bind socket + * - all ports in use + * - couldn't find any Kerberos host + * + * SKDC_RETRY - couldn't get an answer from any Kerberos server, + * after several retries + */ + +send_to_kdc(pkt,rpkt,realm) + KTEXT pkt; + KTEXT rpkt; + char *realm; +{ + int i, f; + int no_host; /* was a kerberos host found? */ + int retry; + int n_hosts; + int retval; + struct sockaddr_in to; + struct hostent *host, *hostlist; + char *cp; + char krbhst[MAX_HSTNM]; + char lrealm[REALM_SZ]; + + /* + * If "realm" is non-null, use that, otherwise get the + * local realm. + */ + if (realm) + (void) strcpy(lrealm, realm); + else + if (krb_get_lrealm(lrealm,1)) { + if (krb_debug) + fprintf(stderr, "%s: can't get local realm\n", prog); + return(SKDC_CANT); + } + if (krb_debug) + printf("lrealm is %s\n", lrealm); + if (krb_udp_port == 0) { + register struct servent *sp; + if ((sp = getservbyname("kerberos","udp")) == 0) { + if (krb_debug) + fprintf(stderr, "%s: Can't get kerberos/udp service\n", + prog); + return(SKDC_CANT); + } + krb_udp_port = sp->s_port; + if (krb_debug) + printf("krb_udp_port is %d\n", krb_udp_port); + } + bzero((char *)&to, S_AD_SZ); + hostlist = (struct hostent *) malloc(sizeof(struct hostent)); + if (!hostlist) + return (/*errno */SKDC_CANT); + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if (krb_debug) + fprintf(stderr,"%s: Can't open socket\n", prog); + return(SKDC_CANT); + } + /* from now on, exit through rtn label for cleanup */ + + no_host = 1; + /* get an initial allocation */ + n_hosts = 0; + for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { + if (krb_debug) { + printf("Getting host entry for %s...",krbhst); + (void) fflush(stdout); + } + host = gethostbyname(krbhst); + if (krb_debug) { + printf("%s.\n", + host ? "Got it" : "Didn't get it"); + (void) fflush(stdout); + } + if (!host) + continue; + no_host = 0; /* found at least one */ + n_hosts++; + /* preserve host network address to check later + * (would be better to preserve *all* addresses, + * take care of that later) + */ + hostlist = (struct hostent *) + realloc((char *)hostlist, + (unsigned) + sizeof(struct hostent)*(n_hosts+1)); + if (!hostlist) + return /*errno */SKDC_CANT; + bcopy((char *)host, (char *)&hostlist[n_hosts-1], + sizeof(struct hostent)); + host = &hostlist[n_hosts-1]; + cp = malloc((unsigned)host->h_length); + if (!cp) { + retval = /*errno */SKDC_CANT; + goto rtn; + } + bcopy((char *)host->h_addr, cp, host->h_length); +/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2 + (or worse) only return one name ... */ +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + host->h_addr_list = (char **)malloc(sizeof(char *)); + if (!host->h_addr_list) { + retval = /*errno */SKDC_CANT; + goto rtn; + } +#endif /* ULTRIX022 || SunOS */ + host->h_addr = cp; + bzero((char *)&hostlist[n_hosts], + sizeof(struct hostent)); + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + to.sin_port = krb_udp_port; + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + if (krb_debug) { + printf("Timeout, error, or wrong descriptor\n"); + (void) fflush(stdout); + } + } + if (no_host) { + if (krb_debug) + fprintf(stderr, "%s: can't find any Kerberos host.\n", + prog); + retval = SKDC_CANT; + goto rtn; + } + /* retry each host in sequence */ + for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { + for (host = hostlist; host->h_name != (char *)NULL; host++) { + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + } + } + retval = SKDC_RETRY; +rtn: + (void) close(f); + if (hostlist) { + register struct hostent *hp; + for (hp = hostlist; hp->h_name; hp++) +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + if (hp->h_addr_list) { +#endif /* ULTRIX022 || SunOS */ + if (hp->h_addr) + free(hp->h_addr); +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + free((char *)hp->h_addr_list); + } +#endif /* ULTRIX022 || SunOS */ + free((char *)hostlist); + } + return(retval); +} + +/* + * try to send out and receive message. + * return 1 on success, 0 on failure + */ + +static send_recv(pkt,rpkt,f,_to,addrs) + KTEXT pkt; + KTEXT rpkt; + int f; + struct sockaddr_in *_to; + struct hostent *addrs; +{ + fd_set readfds; + register struct hostent *hp; + struct sockaddr_in from; + int sin_size; + int numsent; + + if (krb_debug) { + if (_to->sin_family == AF_INET) + printf("Sending message to %s...", + inet_ntoa(_to->sin_addr)); + else + printf("Sending message..."); + (void) fflush(stdout); + } + if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0, + (struct sockaddr *)_to, + S_AD_SZ)) != pkt->length) { + if (krb_debug) + printf("sent only %d/%d\n",numsent, pkt->length); + return 0; + } + if (krb_debug) { + printf("Sent\nWaiting for reply..."); + (void) fflush(stdout); + } + FD_ZERO(&readfds); + FD_SET(f, &readfds); + errno = 0; + /* select - either recv is ready, or timeout */ + /* see if timeout or error or wrong descriptor */ + if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1 + || !FD_ISSET(f, &readfds)) { + if (krb_debug) { + fprintf(stderr, "select failed: readfds=%x", + readfds); + perror(""); + } + return 0; + } + sin_size = sizeof(from); + if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0, + (struct sockaddr *)&from, &sin_size) + < 0) { + if (krb_debug) + perror("recvfrom"); + return 0; + } + if (krb_debug) { + printf("received packet from %s\n", inet_ntoa(from.sin_addr)); + fflush(stdout); + } + for (hp = addrs; hp->h_name != (char *)NULL; hp++) { + if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr, + hp->h_length)) { + if (krb_debug) { + printf("Received it\n"); + (void) fflush(stdout); + } + return 1; + } + if (krb_debug) + fprintf(stderr, + "packet not from %x\n", + hp->h_addr); + } + if (krb_debug) + fprintf(stderr, "%s: received packet from wrong host! (%x)\n", + "send_to_kdc(send_rcv)", from.sin_addr.s_addr); + return 0; +} diff --git a/eBones/krb/sendauth.c b/eBones/krb/sendauth.c new file mode 100644 index 0000000..7d798bb --- /dev/null +++ b/eBones/krb/sendauth.c @@ -0,0 +1,257 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $ + * $Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */ +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_recvauth.c + */ + +extern int errno; + +extern char *krb_get_phost(); + +/* + * This file contains two routines: krb_sendauth() and krb_sendsrv(). + * + * krb_sendauth() transmits a ticket over a file descriptor for a + * desired service, instance, and realm, doing mutual authentication + * with the server if desired. + * + * krb_sendsvc() sends a service name to a remote knetd server. + */ + +/* + * The first argument to krb_sendauth() contains a bitfield of + * options (the options are defined in "krb.h"): + * + * KOPT_DONT_CANON Don't canonicalize instance as a hostname. + * (If this option is not chosen, krb_get_phost() + * is called to canonicalize it.) + * + * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. + * A ticket must be supplied in the "ticket" + * argument. + * (If this option is not chosen, and there + * is no ticket for the given server in the + * ticket cache, one will be fetched using + * krb_mk_req() and returned in "ticket".) + * + * KOPT_DO_MUTUAL Do mutual authentication, requiring that the + * receiving server return the checksum+1 encrypted + * in the session key. The mutual authentication + * is done using krb_mk_priv() on the other side + * (see "recvauth.c") and krb_rd_priv() on this + * side. + * + * The "fd" argument is a file descriptor to write to the remote + * server on. The "ticket" argument is used to store the new ticket + * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is + * chosen, the ticket must be supplied in the "ticket" argument. + * The "service", "inst", and "realm" arguments identify the ticket. + * If "realm" is null, the local realm is used. + * + * The following arguments are only needed if the KOPT_DO_MUTUAL option + * is chosen: + * + * The "checksum" argument is a number that the server will add 1 to + * to authenticate itself back to the client; the "msg_data" argument + * holds the returned mutual-authentication message from the server + * (i.e., the checksum+1); the "cred" structure is used to hold the + * session key of the server, extracted from the ticket file, for use + * in decrypting the mutual authentication message from the server; + * and "schedule" holds the key schedule for that decryption. The + * the local and server addresses are given in "laddr" and "faddr". + * + * The application protocol version number (of up to KRB_SENDAUTH_VLEN + * characters) is passed in "version". + * + * If all goes well, KSUCCESS is returned, otherwise some error code. + * + * The format of the message sent to the server is: + * + * Size Variable Field + * ---- -------- ----- + * + * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol + * bytes version number + * + * KRB_SENDAUTH_VLEN version application protocol + * bytes version number + * + * 4 bytes ticket->length length of ticket + * + * ticket->length ticket->dat ticket itself + */ + +/* + * XXX: Note that krb_rd_priv() is coded in such a way that + * "msg_data->app_data" will be pointing into "priv_buf", which + * will disappear when krb_sendauth() returns. + */ + +int +krb_sendauth(options, fd, ticket, service, inst, realm, checksum, + msg_data, cred, schedule, laddr, faddr, version) +long options; /* bit-pattern of options */ +int fd; /* file descriptor to write onto */ +KTEXT ticket; /* where to put ticket (return); or + * supplied in case of KOPT_DONT_MK_REQ */ +char *service, *inst, *realm; /* service name, instance, realm */ +u_long checksum; /* checksum to include in request */ +MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */ +CREDENTIALS *cred; /* credentials (return) */ +Key_schedule schedule; /* key schedule (return) */ +struct sockaddr_in *laddr; /* local address */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +char *version; /* version string */ +{ + int rem, i, cc; + char srv_inst[INST_SZ]; + char krb_realm[REALM_SZ]; + char buf[BUFSIZ]; + long tkt_len; + u_char priv_buf[1024]; + u_long cksum; + + rem=KSUCCESS; + + /* get current realm if not passed in */ + if (!realm) { + rem = krb_get_lrealm(krb_realm,1); + if (rem != KSUCCESS) + return(rem); + realm = krb_realm; + } + + /* copy instance into local storage, canonicalizing if desired */ + if (options & KOPT_DONT_CANON) + (void) strncpy(srv_inst, inst, INST_SZ); + else + (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ); + + /* get the ticket if desired */ + if (!(options & KOPT_DONT_MK_REQ)) { + rem = krb_mk_req(ticket, service, srv_inst, realm, checksum); + if (rem != KSUCCESS) + return(rem); + } + +#ifdef ATHENA_COMPAT + /* this is only for compatibility with old servers */ + if (options & KOPT_DO_OLDSTYLE) { + (void) sprintf(buf,"%d ",ticket->length); + (void) write(fd, buf, strlen(buf)); + (void) write(fd, (char *) ticket->dat, ticket->length); + return(rem); + } +#endif ATHENA_COMPAT + /* if mutual auth, get credentials so we have service session + keys for decryption below */ + if (options & KOPT_DO_MUTUAL) + if (cc = krb_get_cred(service, srv_inst, realm, cred)) + return(cc); + + /* zero the buffer */ + (void) bzero(buf, BUFSIZ); + + /* insert version strings */ + (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN); + (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN); + + /* increment past vers strings */ + i = 2*KRB_SENDAUTH_VLEN; + + /* put ticket length into buffer */ + tkt_len = htonl((unsigned long) ticket->length); + (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len)); + i += sizeof(tkt_len); + + /* put ticket into buffer */ + (void) bcopy((char *) ticket->dat, buf+i, ticket->length); + i += ticket->length; + + /* write the request to the server */ + if ((cc = krb_net_write(fd, buf, i)) != i) + return(cc); + + /* mutual authentication, if desired */ + if (options & KOPT_DO_MUTUAL) { + /* get the length of the reply */ + if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + tkt_len = ntohl((unsigned long)tkt_len); + + /* if the length is negative, the server failed to recognize us. */ + if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf))) + return(KFAILURE); /* XXX */ + /* read the reply... */ + if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len) + return(errno); + + /* ...and decrypt it */ +#ifndef NOENCRYPTION + key_sched(cred->session,schedule); +#endif + if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule, + cred->session, faddr, laddr, msg_data)) + return(cc); + + /* fetch the (modified) checksum */ + (void) bcopy((char *)msg_data->app_data, (char *)&cksum, + sizeof(cksum)); + cksum = ntohl(cksum); + + /* if it doesn't match, fail */ + if (cksum != checksum + 1) + return(KFAILURE); /* XXX */ + } + return(KSUCCESS); +} + +#ifdef ATHENA_COMPAT +/* + * krb_sendsvc + */ + +int +krb_sendsvc(fd, service) +int fd; +char *service; +{ + /* write the service name length and then the service name to + the fd */ + long serv_length; + int cc; + + serv_length = htonl((unsigned long)strlen(service)); + if ((cc = krb_net_write(fd, (char *) &serv_length, + sizeof(serv_length))) + != sizeof(serv_length)) + return(cc); + if ((cc = krb_net_write(fd, service, strlen(service))) + != strlen(service)) + return(cc); + return(KSUCCESS); +} +#endif ATHENA_COMPAT diff --git a/eBones/krb/stime.c b/eBones/krb/stime.c new file mode 100644 index 0000000..c040374 --- /dev/null +++ b/eBones/krb/stime.c @@ -0,0 +1,40 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $ + * $Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> /* for sprintf() */ + +/* + * Given a pointer to a long containing the number of seconds + * since the beginning of time (midnight 1 Jan 1970 GMT), return + * a string containing the local time in the form: + * + * "25-Jan-88 10:17:56" + */ + +char *stime(t) + long *t; +{ + static char st_data[40]; + static char *st = st_data; + struct tm *tm; + char *month_sname(); + + tm = localtime(t); + (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + return st; +} diff --git a/eBones/krb/tf_shm.c b/eBones/krb/tf_shm.c new file mode 100644 index 0000000..5548f0d --- /dev/null +++ b/eBones/krb/tf_shm.c @@ -0,0 +1,174 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Shared memory segment functions for session keys. Derived from code + * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu). + * + * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $ + * $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <krb.h> +#include <des.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */ + +extern int errno; +extern int krb_debug; + +/* + * krb_create_shmtkt: + * + * create a shared memory segment for session keys, leaving its id + * in the specified filename. + */ + +int +krb_shm_create(file_name) +char *file_name; +{ + int retval; + int shmid; + struct shmid_ds shm_buf; + FILE *sfile; + uid_t me, metoo, getuid(), geteuid(); + + (void) krb_shm_dest(file_name); /* nuke it if it exists... + this cleans up to make sure we + don't slowly lose memory. */ + + shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT); + if (shmid == -1) { + if (krb_debug) + perror("krb_shm_create shmget"); + return(KFAILURE); /* XXX */ + } + me = getuid(); + metoo = geteuid(); + /* + * now set up the buffer so that we can modify it + */ + shm_buf.shm_perm.uid = me; + shm_buf.shm_perm.gid = getgid(); + shm_buf.shm_perm.mode = 0600; + if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */ + if (krb_debug) + perror("krb_shm_create shmctl"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */ + /* arrange so the file is owned by the ruid + (swap real & effective uid if necessary). */ + if (me != metoo) { + if (setreuid(metoo, me) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("krb_shm_create: setreuid"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",metoo,me); + } + if ((sfile = fopen(file_name,"w")) == 0) { + if (krb_debug) + perror("krb_shm_create file"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + if (fchmod(fileno(sfile),0600) < 0) { + if (krb_debug) + perror("krb_shm_create fchmod"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + if (me != metoo) { + if (setreuid(me, metoo) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("krb_shm_create: setreuid2"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",me,metoo); + } + + (void) fprintf(sfile,"%d",shmid); + (void) fflush(sfile); + (void) fclose(sfile); + return(KSUCCESS); +} + + +/* + * krb_is_diskless: + * + * check / to see if file .diskless exists. If so it is diskless. + * Do it this way now to avoid dependencies on a particular routine. + * Choose root file system since that will be private to the client. + */ + +int krb_is_diskless() +{ + struct stat buf; + if (stat("/.diskless",&buf) < 0) + return(0); + else return(1); +} + +/* + * krb_shm_dest: destroy shared memory segment with session keys, and remove + * file pointing to it. + */ + +int krb_shm_dest(file) +char *file; +{ + int shmid; + FILE *sfile; + struct stat st_buf; + + if (stat(file,&st_buf) == 0) { + /* successful stat */ + if ((sfile = fopen(file,"r")) == 0) { + if (krb_debug) + perror("cannot open shared memory file"); + return(KFAILURE); /* XXX */ + } + if (fscanf(sfile,"%d",&shmid) == 1) { + if (shmctl(shmid,IPC_RMID,0) != 0) { + if (krb_debug) + perror("krb_shm_dest: cannot delete shm segment"); + (void) fclose(sfile); + return(KFAILURE); /* XXX */ + } + } else { + if (krb_debug) + fprintf(stderr, "bad format in shmid file\n"); + (void) fclose(sfile); + return(KFAILURE); /* XXX */ + } + (void) fclose(sfile); + (void) unlink(file); + return(KSUCCESS); + } else + return(RET_TKFIL); /* XXX */ +} + + + diff --git a/eBones/krb/tf_util.3 b/eBones/krb/tf_util.3 new file mode 100644 index 0000000..3a9bc94 --- /dev/null +++ b/eBones/krb/tf_util.3 @@ -0,0 +1,151 @@ +.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $ +.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \ +\- Routines for manipulating a Kerberos ticket file +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +extern char *krb_err_txt[]; +.PP +.ft B +tf_init(tf_name, rw) +char *tf_name; +int rw; +.PP +.ft B +tf_get_pname(pname) +char *pname; +.PP +.ft B +tf_get_pinst(pinst) +char *pinst; +.PP +.ft B +tf_get_cred(c) +CREDENTIALS *c; +.PP +.ft B +tf_close() +.PP +.fi +.SH DESCRIPTION +This group of routines are provided to manipulate the Kerberos tickets +file. A ticket file has the following format: +.nf +.in +4 +.sp +principal's name (null-terminated string) +principal's instance (null-terminated string) +CREDENTIAL_1 +CREDENTIAL_2 + ... +CREDENTIAL_n +EOF +.sp +.in -4 +.LP +Where "CREDENTIAL_x" consists of the following fixed-length +fields from the CREDENTIALS structure (defined in <krb.h>): +.nf +.sp +.in +4 + char service[ANAME_SZ] + char instance[INST_SZ] + char realm[REALM_SZ] + des_cblock session + int lifetime + int kvno + KTEXT_ST ticket_st + long issue_date +.in -4 +.sp +.fi +.PP +.I tf_init +must be called before the other ticket file +routines. +It takes the name of the ticket file to use, +and a read/write flag as arguments. +It tries to open the ticket file, checks the mode and if +everything is okay, locks the file. If it's opened for +reading, the lock is shared. If it's opened for writing, +the lock is exclusive. +KSUCCESS is returned if all went well, otherwise one of the +following: +.nf +.sp +NO_TKT_FIL - file wasn't there +TKT_FIL_ACC - file was in wrong mode, etc. +TKT_FIL_LCK - couldn't lock the file, even after a retry +.sp +.fi +.PP +The +.I tf_get_pname +reads the principal's name from a ticket file. +It should only be called after tf_init has been called. The +principal's name is filled into the +.I pname +parameter. If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If the principal's name was null, or EOF was encountered, or the +name was longer than ANAME_SZ, TKT_FIL_FMT is returned. +.PP +The +.I tf_get_pinst +reads the principal's instance from a ticket file. +It should only be called after tf_init and tf_get_pname +have been called. +The principal's instance is filled into the +.I pinst +parameter. +If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If EOF was encountered, or the +name was longer than INST_SZ, TKT_FIL_FMT is returned. +Note that, unlike the principal name, the instance name may be null. +.PP +The +.I tf_get_cred +routine reads a CREDENTIALS record from a ticket file and +fills in the given structure. +It should only be called after +tf_init, tf_get_pname, and tf_get_pinst have been called. +If all goes well, KSUCCESS is returned. Possible error codes +are: +.nf +.sp +TKT_FIL_INI - tf_init wasn't called first +TKT_FIL_FMT - bad format +EOF - end of file encountered +.sp +.fi +.PP +.I tf_close +closes the ticket file and releases the lock on it. +.SH "SEE ALSO" +krb(3) +.SH DIAGNOSTICS +.SH BUGS +The ticket file routines have to be called in a certain order. +.SH AUTHORS +Jennifer Steiner, MIT Project Athena +.br +Bill Bryant, MIT Project Athena +.SH RESTRICTIONS +Copyright 1987 Massachusetts Institute of Technology diff --git a/eBones/krb/tf_util.c b/eBones/krb/tf_util.c new file mode 100644 index 0000000..a9e8551 --- /dev/null +++ b/eBones/krb/tf_util.c @@ -0,0 +1,572 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $ + * $Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <krb.h> + +#ifdef TKT_SHMEM +#include <sys/param.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#endif /* TKT_SHMEM */ + +#define TOO_BIG -1 +#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before + * retry if ticket file is + * locked */ +extern errno; +extern int krb_debug; + +#ifdef TKT_SHMEM +char *krb_shm_addr = 0; +static char *tmp_shm_addr = 0; +static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0}; + +char *shmat(); +#endif /* TKT_SHMEM */ + +/* + * fd must be initialized to something that won't ever occur as a real + * file descriptor. Since open(2) returns only non-negative numbers as + * valid file descriptors, and tf_init always stuffs the return value + * from open in here even if it is an error flag, we must + * a. Initialize fd to a negative number, to indicate that it is + * not initially valid. + * b. When checking for a valid fd, assume that negative values + * are invalid (ie. when deciding whether tf_init has been + * called.) + * c. In tf_close, be sure it gets reinitialized to a negative + * number. + */ +static fd = -1; +static curpos; /* Position in tfbfr */ +static lastpos; /* End of tfbfr */ +static char tfbfr[BUFSIZ]; /* Buffer for ticket data */ + +static tf_gets(), tf_read(); + +/* + * This file contains routines for manipulating the ticket cache file. + * + * The ticket file is in the following format: + * + * principal's name (null-terminated string) + * principal's instance (null-terminated string) + * CREDENTIAL_1 + * CREDENTIAL_2 + * ... + * CREDENTIAL_n + * EOF + * + * Where "CREDENTIAL_x" consists of the following fixed-length + * fields from the CREDENTIALS structure (see "krb.h"): + * + * char service[ANAME_SZ] + * char instance[INST_SZ] + * char realm[REALM_SZ] + * C_Block session + * int lifetime + * int kvno + * KTEXT_ST ticket_st + * long issue_date + * + * Short description of routines: + * + * tf_init() opens the ticket file and locks it. + * + * tf_get_pname() returns the principal's name. + * + * tf_get_pinst() returns the principal's instance (may be null). + * + * tf_get_cred() returns the next CREDENTIALS record. + * + * tf_save_cred() appends a new CREDENTIAL record to the ticket file. + * + * tf_close() closes the ticket file and releases the lock. + * + * tf_gets() returns the next null-terminated string. It's an internal + * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred(). + * + * tf_read() reads a given number of bytes. It's an internal routine + * used by tf_get_cred(). + */ + +/* + * tf_init() should be called before the other ticket file routines. + * It takes the name of the ticket file to use, "tf_name", and a + * read/write flag "rw" as arguments. + * + * It tries to open the ticket file, checks the mode, and if everything + * is okay, locks the file. If it's opened for reading, the lock is + * shared. If it's opened for writing, the lock is exclusive. + * + * Returns KSUCCESS if all went well, otherwise one of the following: + * + * NO_TKT_FIL - file wasn't there + * TKT_FIL_ACC - file was in wrong mode, etc. + * TKT_FIL_LCK - couldn't lock the file, even after a retry + */ + +tf_init(tf_name, rw) + char *tf_name; +{ + int wflag; + uid_t me, getuid(); + struct stat stat_buf; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; + FILE *sfp; + int shmid; +#endif + + switch (rw) { + case R_TKT_FIL: + wflag = 0; + break; + case W_TKT_FIL: + wflag = 1; + break; + default: + if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n"); + return TKT_FIL_ACC; + } + if (lstat(tf_name, &stat_buf) < 0) + switch (errno) { + case ENOENT: + return NO_TKT_FIL; + default: + return TKT_FIL_ACC; + } + me = getuid(); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#ifdef TKT_SHMEM + (void) strcpy(shmidname, tf_name); + (void) strcat(shmidname, ".shm"); + if (stat(shmidname,&stat_buf) < 0) + return(TKT_FIL_ACC); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#endif /* TKT_SHMEM */ + + /* + * If "wflag" is set, open the ticket file in append-writeonly mode + * and lock the ticket file in exclusive mode. If unable to lock + * the file, sleep and try again. If we fail again, return with the + * proper error message. + */ + + curpos = sizeof(tfbfr); + +#ifdef TKT_SHMEM + sfp = fopen(shmidname, "r"); /* only need read/write on the + actual tickets */ + if (sfp == 0) + return TKT_FIL_ACC; + shmid = -1; + { + char buf[BUFSIZ]; + int val; /* useful for debugging fscanf */ + /* We provide our own buffer here since some STDIO libraries + barf on unbuffered input with fscanf() */ + + setbuf(sfp, buf); + if ((val = fscanf(sfp,"%d",&shmid)) != 1) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + if (shmid < 0) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + (void) fclose(sfp); + } + /* + * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and + * attach the same segment twice so we need this check. + */ + if (!krb_shm_addr) { + if ((krb_shm_addr = shmat(shmid,0,0)) == -1){ + if (krb_debug) + fprintf(stderr, + "cannot attach shared memory for segment %d\n", + shmid); + krb_shm_addr = 0; /* reset so we catch further errors */ + return TKT_FIL_ACC; + } + } + tmp_shm_addr = krb_shm_addr; +#endif /* TKT_SHMEM */ + + if (wflag) { + fd = open(tf_name, O_RDWR, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; + } + /* + * Otherwise "wflag" is not set and the ticket file should be opened + * for read-only operations and locked for shared access. + */ + + fd = open(tf_name, O_RDONLY, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; +} + +/* + * tf_get_pname() reads the principal's name from the ticket file. It + * should only be called after tf_init() has been called. The + * principal's name is filled into the "p" parameter. If all goes well, + * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is + * returned. If the name was null, or EOF was encountered, or the name + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. + */ + +tf_get_pname(p) + char *p; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pname called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */ + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_pinst() reads the principal's instance from a ticket file. + * It should only be called after tf_init() and tf_get_pname() have been + * called. The instance is filled into the "inst" parameter. If all + * goes well, KSUCCESS is returned. If tf_init() wasn't called, + * TKT_FIL_INI is returned. If EOF was encountered, or the instance + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the + * instance may be null. + */ + +tf_get_pinst(inst) + char *inst; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pinst called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(inst, INST_SZ) < 1) + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills + * in the given structure "c". It should only be called after tf_init(), + * tf_get_pname(), and tf_get_pinst() have been called. If all goes well, + * KSUCCESS is returned. Possible error codes are: + * + * TKT_FIL_INI - tf_init wasn't called first + * TKT_FIL_FMT - bad format + * EOF - end of file encountered + */ + +tf_get_cred(c) + CREDENTIALS *c; +{ + KTEXT ticket = &c->ticket_st; /* pointer to ticket */ + int k_errno; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1) + switch (k_errno) { + case TOO_BIG: + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ( + tf_read((char *) (c->session), KEY_SZ) < 1 || + tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 || + tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 || + tf_read((char *) &(ticket->length), sizeof(ticket->length)) + < 1 || + /* don't try to read a silly amount into ticket->dat */ + ticket->length > MAX_KTXT_LEN || + tf_read((char *) (ticket->dat), ticket->length) < 1 || + tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1 + ) { + tf_close(); + return TKT_FIL_FMT; + } +#ifdef TKT_SHMEM + bcopy(tmp_shm_addr,c->session,KEY_SZ); + tmp_shm_addr += KEY_SZ; +#endif /* TKT_SHMEM */ + return KSUCCESS; +} + +/* + * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is + * not a valid file descriptor, it just returns. It also clears the + * buffer used to read tickets. + * + * The return value is not defined. + */ + +tf_close() +{ + if (!(fd < 0)) { +#ifdef TKT_SHMEM + if (shmdt(krb_shm_addr)) { + /* what kind of error? */ + if (krb_debug) + fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno); + } else { + krb_shm_addr = 0; + } +#endif TKT_SHMEM + (void) flock(fd, LOCK_UN); + (void) close(fd); + fd = -1; /* see declaration of fd above */ + } + bzero(tfbfr, sizeof(tfbfr)); +} + +/* + * tf_gets() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until either it has read "n" characters, + * or until it reads a null byte. When finished, what has been read exists + * in "s". If it encounters EOF or an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read (including null terminator) + * when all goes well + * + * 0 end of file or read error + * + * TOO_BIG if "count" characters are read and no null is + * encountered. This is an indication that the ticket + * file is seriously ill. + */ + +static +tf_gets(s, n) + register char *s; +{ + register count; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_gets called before tf_init.\n"); + return TKT_FIL_INI; + } + for (count = n - 1; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s = tfbfr[curpos++]; + if (*s++ == '\0') + return (n - count); + } + tf_close(); + return TOO_BIG; +} + +/* + * tf_read() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until "n" bytes have been read. When + * finished, what has been read exists in "s". If it encounters EOF or + * an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read when all goes well + * + * 0 on end of file or read error + */ + +static +tf_read(s, n) + register char *s; + register n; +{ + register count; + + for (count = n; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s++ = tfbfr[curpos++]; + } + return n; +} + +char *tkt_string(); + +/* + * tf_save_cred() appends an incoming ticket to the end of the ticket + * file. You must call tf_init() before calling tf_save_cred(). + * + * The "service", "instance", and "realm" arguments specify the + * server's name; "session" contains the session key to be used with + * the ticket; "kvno" is the server key version number in which the + * ticket is encrypted, "ticket" contains the actual ticket, and + * "issue_date" is the time the ticket was requested (local host's time). + * + * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't + * called previously, and KFAILURE for anything else that went wrong. + */ + +tf_save_cred(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + C_Block session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + long issue_date; /* The issue time */ +{ + + off_t lseek(); + int count; /* count for write */ +#ifdef TKT_SHMEM + int *skey_check; +#endif /* TKT_SHMEM */ + + if (fd < 0) { /* fd is ticket file as set by tf_init */ + if (krb_debug) + fprintf(stderr, "tf_save_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + /* Find the end of the ticket file */ + (void) lseek(fd, 0L, 2); +#ifdef TKT_SHMEM + /* scan to end of existing keys: pick first 'empty' slot. + we assume that no real keys will be completely zero (it's a weak + key under DES) */ + + skey_check = (int *) krb_shm_addr; + + while (*skey_check && *(skey_check+1)) + skey_check += 2; + tmp_shm_addr = (char *)skey_check; +#endif /* TKT_SHMEM */ + + /* Write the ticket and associated data */ + /* Service */ + count = strlen(service) + 1; + if (write(fd, service, count) != count) + goto bad; + /* Instance */ + count = strlen(instance) + 1; + if (write(fd, instance, count) != count) + goto bad; + /* Realm */ + count = strlen(realm) + 1; + if (write(fd, realm, count) != count) + goto bad; + /* Session key */ +#ifdef TKT_SHMEM + bcopy(session,tmp_shm_addr,8); + tmp_shm_addr+=8; + if (write(fd,krb_dummy_skey,8) != 8) + goto bad; +#else /* ! TKT_SHMEM */ + if (write(fd, (char *) session, 8) != 8) + goto bad; +#endif /* TKT_SHMEM */ + /* Lifetime */ + if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int)) + goto bad; + /* Key vno */ + if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int)) + goto bad; + /* Tkt length */ + if (write(fd, (char *) &(ticket->length), sizeof(int)) != + sizeof(int)) + goto bad; + /* Ticket */ + count = ticket->length; + if (write(fd, (char *) (ticket->dat), count) != count) + goto bad; + /* Issue date */ + if (write(fd, (char *) &issue_date, sizeof(long)) + != sizeof(long)) + goto bad; + + /* Actually, we should check each write for success */ + return (KSUCCESS); +bad: + return (KFAILURE); +} diff --git a/eBones/krb/tkt_string.c b/eBones/krb/tkt_string.c new file mode 100644 index 0000000..ba22db8 --- /dev/null +++ b/eBones/krb/tkt_string.c @@ -0,0 +1,79 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $ + * $Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <sys/types.h> +#include <krb.h> +#include <string.h> +#include <sys/param.h> + +char *getenv(); + +/* + * This routine is used to generate the name of the file that holds + * the user's cache of server tickets and associated session keys. + * + * If it is set, krb_ticket_string contains the ticket file name. + * Otherwise, the filename is constructed as follows: + * + * If it is set, the environment variable "KRBTKFILE" will be used as + * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and + * the user's uid are concatenated to produce the ticket file name + * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket + * file name is returned. + */ + +static char krb_ticket_string[MAXPATHLEN] = ""; + +char *tkt_string() +{ + char *env; + uid_t getuid(); + + if (!*krb_ticket_string) { + if (env = getenv("KRBTKFILE")) { + (void) strncpy(krb_ticket_string, env, + sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + } else { + /* 32 bits of signed integer will always fit in 11 characters + (including the sign), so no need to worry about overflow */ + (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,getuid()); + } + } + return krb_ticket_string; +} + +/* + * This routine is used to set the name of the file that holds the user's + * cache of server tickets and associated session keys. + * + * The value passed in is copied into local storage. + * + * NOTE: This routine should be called during initialization, before other + * Kerberos routines are called; otherwise tkt_string() above may be called + * and return an undesired ticket file name until this routine is called. + */ + +void +krb_set_tkt_string(val) +char *val; +{ + + (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + + return; +} diff --git a/eBones/krb/util.c b/eBones/krb/util.c new file mode 100644 index 0000000..8e48557 --- /dev/null +++ b/eBones/krb/util.c @@ -0,0 +1,72 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Miscellaneous debug printing utilities + * + * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $ + * $Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <des.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> + +/* + * Print some of the contents of the given authenticator structure + * (AUTH_DAT defined in "krb.h"). Fields printed are: + * + * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session + */ + +ad_print(x) +AUTH_DAT *x; +{ + struct in_addr in; + + /* Print the contents of an auth_dat struct. */ + in.s_addr = x->address; + printf("\n%s %s %s %s flags %u cksum 0x%X\n\ttkt_tm 0x%X sess_key", + x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags, + x->checksum, x->time_sec); + + printf("[8] ="); +#ifdef NOENCRYPTION + placebo_cblock_print(x->session); +#else + des_cblock_print_file(x->session,stdout); +#endif + /* skip reply for now */ +} + +/* + * Print in hex the 8 bytes of the given session key. + * + * Printed format is: " 0x { x, x, x, x, x, x, x, x }" + */ + +#ifdef NOENCRYPTION +placebo_cblock_print(x) + des_cblock x; +{ + unsigned char *y = (unsigned char *) x; + register int i = 0; + + printf(" 0x { "); + + while (i++ <8) { + printf("%x",*y++); + if (i<8) printf(", "); + } + printf(" }"); +} +#endif diff --git a/eBones/ksrvtgt/Makefile b/eBones/ksrvtgt/Makefile new file mode 100644 index 0000000..5e8944d --- /dev/null +++ b/eBones/ksrvtgt/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:26:54 g89r4222 Exp $ + +PROG= ksrvtgt +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/ksrvtgt/ksrvtgt.1 b/eBones/ksrvtgt/ksrvtgt.1 new file mode 100644 index 0000000..25fd939 --- /dev/null +++ b/eBones/ksrvtgt/ksrvtgt.1 @@ -0,0 +1,51 @@ +.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $ +.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a +service key +.SH SYNOPSIS +.B ksrvtgt +name instance [[realm] srvtab] +.SH DESCRIPTION +.I ksrvtgt +retrieves a ticket-granting ticket with a lifetime of five (5) minutes +for the principal +.I name.instance@realm +(or +.I name.instance@localrealm +if +.I realm +is not supplied on the command line), decrypts the response using +the service key found in +.I srvtab +(or in +.B /etc/srvtab +if +.I srvtab +is not specified on the command line), and stores the ticket in the +standard ticket cache. +.PP +This command is intended primarily for use in shell scripts and other +batch-type facilities. +.SH DIAGNOSTICS +"Generic kerberos failure (kfailure)" can indicate a whole range of +problems, the most common of which is the inability to read the service +key file. +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm. +.TP +/tmp/tkt[uid] +The default ticket file. +.TP +/etc/srvtab +The default service key file. +.SH SEE ALSO +kerberos(1), kinit(1), kdestroy(1) diff --git a/eBones/ksrvtgt/ksrvtgt.c b/eBones/ksrvtgt/ksrvtgt.c new file mode 100644 index 0000000..46bbd56 --- /dev/null +++ b/eBones/ksrvtgt/ksrvtgt.c @@ -0,0 +1,60 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Get a ticket-granting-ticket given a service key file (srvtab) + * The lifetime is the shortest allowed [1 five-minute interval] + * + * from: ksrvtgt.c,v 4.3 89/07/28 10:17:28 jtkohl Exp $ + * $Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $ + */ + +#ifndef lint +const char rcsid[] = +"$Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <sys/param.h> +#include <krb.h> +#include <conf.h> + +main(argc,argv) + int argc; + char **argv; +{ + char realm[REALM_SZ + 1]; + register int code; + char srvtab[MAXPATHLEN + 1]; + + bzero(realm, sizeof(realm)); + bzero(srvtab, sizeof(srvtab)); + + if (argc < 3 || argc > 5) { + fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n", + argv[0]); + exit(1); + } + + if (argc == 4) + (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1); + + if (argc == 5) { + (void) strncpy(realm, argv[3], sizeof(realm) - 1); + (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1); + } + + if (srvtab[0] == 0) + (void) strcpy(srvtab, KEYFILE); + + if (realm[0] == 0) + if (krb_get_lrealm(realm) != KSUCCESS) + (void) strcpy(realm, KRB_REALM); + + code = krb_get_svc_in_tkt(argv[1], argv[2], realm, + "krbtgt", realm, 1, srvtab); + if (code) + fprintf(stderr, "%s\n", krb_err_txt[code]); + exit(code); +} diff --git a/eBones/ksrvutil/ksrvutil.8 b/eBones/ksrvutil/ksrvutil.8 new file mode 100644 index 0000000..a7fed82 --- /dev/null +++ b/eBones/ksrvutil/ksrvutil.8 @@ -0,0 +1,93 @@ +.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $ +.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvutil \- host kerberos keyfile (srvtab) manipulation utility +.SH SYNOPSIS +ksrvutil +.B operation +[ +.B \-k +] [ +.B \-i +] [ +.B \-f filename +] +.SH DESCRIPTION +.I ksrvutil +allows a system manager to list or change keys currently in his +keyfile or to add new keys to the keyfile. +.PP + +Operation must be one of the following: +.TP 10n +.I list +lists the keys in a keyfile showing version number and principal +name. If the \-k option is given, keys will also be shown. +.TP 10n +.I change +changes all the keys in the keyfile by using the regular admin +protocol. If the \-i flag is given, +.I ksrvutil +will prompt for yes or no before changing each key. If the \-k +option is used, the old and new keys will be displayed. +.TP 10n +.I add +allows the user to add a key. +.I add +prompts for name, instance, realm, and key version number, asks +for confirmation, and then asks for a password. +.I ksrvutil +then converts the password to a key and appends the keyfile with +the new information. If the \-k option is used, the key is +displayed. + +.PP +In all cases, the default file used is KEY_FILE as defined in +krb.h unless this is overridden by the \-f option. + +.PP +A good use for +.I ksrvutil +would be for adding keys to a keyfile. A system manager could +ask a kerberos administrator to create a new service key with +.IR kadmin (8) +and could supply an initial password. Then, he could use +.I ksrvutil +to add the key to the keyfile and then to change the key so that +it will be random and unknown to either the system manager or +the kerberos administrator. + +.I ksrvutil +always makes a backup copy of the keyfile before making any +changes. + +.SH DIAGNOSTICS +If +.I ksrvutil +should exit on an error condition at any time during a change or +add, a copy of the +original keyfile can be found in +.IR filename .old +where +.I filename +is the name of the keyfile, and a copy of the file with all new +keys changed or added so far can be found in +.IR filename .work. +The original keyfile is left unmodified until the program exits +at which point it is removed and replaced it with the workfile. +Appending the workfile to the backup copy and replacing the +keyfile with the result should always give a usable keyfile, +although the resulting keyfile will have some out of date keys +in it. + +.SH SEE ALSO +kadmin(8), ksrvtgt(1) + +.SH AUTHOR +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/kstash/Makefile b/eBones/kstash/Makefile new file mode 100644 index 0000000..8331c97a --- /dev/null +++ b/eBones/kstash/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.2 (Berkeley) 3/5/91 +# $Id: Makefile,v 1.2 1994/07/19 19:27:04 g89r4222 Exp $ + +PROG= kstash +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/kstash/kstash.8 b/eBones/kstash/kstash.8 new file mode 100644 index 0000000..d83379a --- /dev/null +++ b/eBones/kstash/kstash.8 @@ -0,0 +1,41 @@ +.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $ +.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kstash \- stash Kerberos key distribution center database master key +.SH SYNOPSIS +kstash +.SH DESCRIPTION +.I kstash +saves the Kerberos key distribution center (KDC) database master key in +the master key cache file. +.PP +The user is prompted to enter the key, to verify the authenticity of the +key and the authorization to store the key in the file. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.TP +"kstash: Unable to open master key file" +The attempt to open the cache file for writing failed (probably due to a +system or access permission error). +.TP +"kstash: Write I/O error on master key file" +The +.BR write (2) +system call returned an error while +.I kstash +was attempting to write the key to the file. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/kstash/kstash.c b/eBones/kstash/kstash.c new file mode 100644 index 0000000..696e4e1 --- /dev/null +++ b/eBones/kstash/kstash.c @@ -0,0 +1,92 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $ + * $Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +/* change this later, but krblib_dbm needs it for now */ +char *progname; + +static C_Block master_key; +static Key_schedule master_key_schedule; +static Principal s_name_data; /* for services requested */ +static unsigned char master_key_version; +int debug; +static int more; +static int kfile; +static void clear_secrets(); + +main(argc, argv) + int argc; + char **argv; +{ + long n; + if (n = kerb_init()) { + fprintf(stderr, "Kerberos db and cache init failed = %d\n", n); + exit(1); + } + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]); + fflush (stderr); + clear_secrets(); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets(); + exit (-1); + } + + kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600); + if (kfile < 0) { + clear_secrets(); + fprintf(stderr, "\n\07\07%s: Unable to open master key file\n", + argv[0]); + exit(1); + } + if (write(kfile, (char *) master_key, 8) < 0) { + clear_secrets(); + fprintf(stderr, "\n%s: Write I/O error on master key file\n", + argv[0]); + exit(1); + } + (void) close(kfile); + clear_secrets(); +} + +static void +clear_secrets() +{ + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(master_key, sizeof(master_key)); +} diff --git a/eBones/lib/libacl/Makefile b/eBones/lib/libacl/Makefile new file mode 100644 index 0000000..77c9a01 --- /dev/null +++ b/eBones/lib/libacl/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.3 1994/09/09 21:43:17 g89r4222 Exp $ + +LIB= acl +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 +CFLAGS+=-DDEBUG -DKERBEROS -I${.CURDIR}/../include +SRCS= acl_files.c + +.include <bsd.lib.mk> diff --git a/eBones/lib/libacl/acl_check.3 b/eBones/lib/libacl/acl_check.3 new file mode 100644 index 0000000..c142506 --- /dev/null +++ b/eBones/lib/libacl/acl_check.3 @@ -0,0 +1,183 @@ +.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $ +.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +acl_canonicalize_principal, acl_check, acl_exact_match, acl_add, +acl_delete, acl_initialize \- Access control list routines +.SH SYNOPSIS +.nf +.nj +.ft B +cc <files> \-lacl \-lkrb +.PP +.ft B +#include <krb.h> +.PP +.ft B +acl_canonicalize_principal(principal, buf) +char *principal; +char *buf; +.PP +.ft B +acl_check(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_exact_match(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_add(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_delete(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_initialize(acl_file, mode) +char *acl_file; +int mode; +.fi +.ft R +.SH DESCRIPTION +.SS Introduction +.PP +An access control list (ACL) is a list of principals, where each +principal is represented by a text string which cannot contain +whitespace. The library allows application programs to refer to named +access control lists to test membership and to atomically add and +delete principals using a natural and intuitive interface. At +present, the names of access control lists are required to be Unix +filenames, and refer to human-readable Unix files; in the future, when +a networked ACL server is implemented, the names may refer to a +different namespace specific to the ACL service. +.PP +.SS Principal Names +.PP +Principal names have the form +.nf +.in +5n +<name>[.<instance>][@<realm>] +.in -5n +e.g.: +.in +5n +asp +asp.root +asp@ATHENA.MIT.EDU +asp.@ATHENA.MIT.EDU +asp.root@ATHENA.MIT.EDU +.in -5n +.fi +It is possible for principals to be underspecified. If an instance is +missing, it is assumed to be "". If realm is missing, it is assumed +to be the local realm as determined by +.IR krb_get_lrealm (3). +The canonical form contains all of name, instance, +and realm; the acl_add and acl_delete routines will always +leave the file in that form. Note that the canonical form of +asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU. +.SS Routines +.PP +.I acl_canonicalize_principal +stores the canonical form of +.I principal +in +.IR buf . +.I Buf +must contain enough +space to store a principal, given the limits on the sizes of name, +instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ, +respectively, in +.IR /usr/include/krb.h . +.PP +.I acl_check +returns nonzero if +.I principal +appears in +.IR acl . +Returns 0 if principal +does not appear in acl, or if an error occurs. Canonicalizes +principal before checking, and allows the ACL to contain wildcards. The +only supported wildcards are entries of the form +name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the +its component field. For example, "jtkohl.*@*" would match principal +jtkohl, with any instance and any realm. +.PP +.I acl_exact_match +performs like +.IR acl_check , +but does no canonicalization or wildcard matching. +.PP +.I acl_add +atomically adds +.I principal +to +.IR acl . +Returns 0 if successful, nonzero otherwise. It is considered a failure +if +.I principal +is already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_delete +atomically deletes +.I principal +from +.IR acl . +Returns 0 if successful, +nonzero otherwise. It is considered a failure if +.I principal +is not +already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_initialize +initializes +.IR acl_file . +If the file +.I acl_file +does not exist, +.I acl_initialize +creates it with mode +.IR mode . +If the file +.I acl_file +exists, +.I acl_initialize +removes all members. Returns 0 if successful, +nonzero otherwise. WARNING: Mode argument is likely to change with +the eventual introduction of an ACL service. +.SH NOTES +In the presence of concurrency, there is a very small chance that +.I acl_add +or +.I acl_delete +could report success even though it would have +had no effect. This is a necessary side effect of using lock files +for concurrency control rather than flock(2), which is not supported +by NFS. +.PP +The current implementation caches ACLs in memory in a hash-table +format for increased efficiency in checking membership; one effect of +the caching scheme is that one file descriptor will be kept open for +each ACL cached, up to a maximum of 8. +.SH SEE ALSO +kerberos(3), krb_get_lrealm(3) +.SH AUTHOR +James Aspnes (MIT Project Athena) diff --git a/eBones/lib/libacl/acl_files.c b/eBones/lib/libacl/acl_files.c new file mode 100644 index 0000000..6f7f3fd --- /dev/null +++ b/eBones/lib/libacl/acl_files.c @@ -0,0 +1,541 @@ +/* + * + * Copyright 1987,1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $ + * $Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $"; +#endif lint + + +/*** Routines for manipulating access control list files ***/ + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/errno.h> +#include <ctype.h> +#include "krb.h" + +__BEGIN_DECLS +static int acl_abort __P((char *, FILE *)); +__END_DECLS + +#ifndef KRB_REALM +#define KRB_REALM "ATHENA.MIT.EDU" +#endif + +/* "aname.inst@realm" */ +#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3) +#define INST_SEP '.' +#define REALM_SEP '@' + +#define LINESIZE 2048 /* Maximum line length in an acl file */ + +#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */ +#define WAIT_TIME 300 /* Maximum time allowed write acl file */ + +#define CACHED_ACLS 8 /* How many acls to cache */ + /* Each acl costs 1 open file descriptor */ +#define ACL_LEN 16 /* Twice a reasonable acl length */ + +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +#define COR(a,b) ((a!=NULL)?(a):(b)) + +extern int errno; + +extern char *malloc(), *calloc(); +extern time_t time(); + +/* Canonicalize a principal name */ +/* If instance is missing, it becomes "" */ +/* If realm is missing, it becomes the local realm */ +/* Canonicalized form is put in canon, which must be big enough to hold + MAX_PRINCIPAL_SIZE characters */ +acl_canonicalize_principal(principal, canon) +char *principal; +char *canon; +{ + char *dot, *atsign, *end; + int len; + + dot = index(principal, INST_SEP); + atsign = index(principal, REALM_SEP); + + /* Maybe we're done already */ + if(dot != NULL && atsign != NULL) { + if(dot < atsign) { + /* It's for real */ + /* Copy into canon */ + strncpy(canon, principal, MAX_PRINCIPAL_SIZE); + canon[MAX_PRINCIPAL_SIZE-1] = '\0'; + return; + } else { + /* Nope, it's part of the realm */ + dot = NULL; + } + } + + /* No such luck */ + end = principal + strlen(principal); + + /* Get the principal name */ + len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal); + strncpy(canon, principal, len); + canon += len; + + /* Add INST_SEP */ + *canon++ = INST_SEP; + + /* Get the instance, if it exists */ + if(dot != NULL) { + ++dot; + len = MIN(INST_SZ, COR(atsign, end) - dot); + strncpy(canon, dot, len); + canon += len; + } + + /* Add REALM_SEP */ + *canon++ = REALM_SEP; + + /* Get the realm, if it exists */ + /* Otherwise, default to local realm */ + if(atsign != NULL) { + ++atsign; + len = MIN(REALM_SZ, end - atsign); + strncpy(canon, atsign, len); + canon += len; + *canon++ = '\0'; + } else if(krb_get_lrealm(canon, 1) != KSUCCESS) { + strcpy(canon, KRB_REALM); + } +} + +/* Get a lock to modify acl_file */ +/* Return new FILE pointer */ +/* or NULL if file cannot be modified */ +/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */ +static FILE *acl_lock_file(acl_file) +char *acl_file; +{ + struct stat s; + char new[LINESIZE]; + int nfd; + FILE *nf; + int mode; + + if(stat(acl_file, &s) < 0) return(NULL); + mode = s.st_mode; + sprintf(new, NEW_FILE, acl_file); + for(;;) { + /* Open the new file */ + if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) { + if(errno == EEXIST) { + /* Maybe somebody got here already, maybe it's just old */ + if(stat(new, &s) < 0) return(NULL); + if(time(0) - s.st_ctime > WAIT_TIME) { + /* File is stale, kill it */ + unlink(new); + continue; + } else { + /* Wait and try again */ + sleep(1); + continue; + } + } else { + /* Some other error, we lose */ + return(NULL); + } + } + + /* If we got to here, the lock file is ours and ok */ + /* Reopen it under stdio */ + if((nf = fdopen(nfd, "w")) == NULL) { + /* Oops, clean up */ + unlink(new); + } + return(nf); + } +} + +/* Commit changes to acl_file written onto FILE *f */ +/* Returns zero if successful */ +/* Returns > 0 if lock was broken */ +/* Returns < 0 if some other error occurs */ +/* Closes f */ +static int acl_commit(acl_file, f) +char *acl_file; +FILE *f; +{ + char new[LINESIZE]; + int ret; + struct stat s; + + sprintf(new, NEW_FILE, acl_file); + if(fflush(f) < 0 + || fstat(fileno(f), &s) < 0 + || s.st_nlink == 0) { + acl_abort(acl_file, f); + return(-1); + } + + ret = rename(new, acl_file); + fclose(f); + return(ret); +} + +/* + * Abort changes to acl_file written onto FILE *f + * Returns 0 if successful, < 0 otherwise + * Closes f + */ +static int +acl_abort(acl_file, f) +char *acl_file; +FILE *f; +{ + char new[LINESIZE]; + int ret; + struct stat s; + + /* make sure we aren't nuking someone else's file */ + if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) { + fclose(f); + return(-1); + } else { + sprintf(new, NEW_FILE, acl_file); + ret = unlink(new); + fclose(f); + return(ret); + } +} + +/* Initialize an acl_file */ +/* Creates the file with permissions perm if it does not exist */ +/* Erases it if it does */ +/* Returns return value of acl_commit */ +int acl_initialize(acl_file, perm) +char *acl_file; +int perm; +{ + FILE *new; + int fd; + + /* Check if the file exists already */ + if((new = acl_lock_file(acl_file)) != NULL) { + return(acl_commit(acl_file, new)); + } else { + /* File must be readable and writable by owner */ + if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) { + return(-1); + } else { + close(fd); + return(0); + } + } +} + +/* Eliminate all whitespace character in buf */ +/* Modifies its argument */ +static nuke_whitespace(buf) +char *buf; +{ + register char *pin, *pout; + + for(pin = pout = buf; *pin != '\0'; pin++) + if(!isspace(*pin)) *pout++ = *pin; + *pout = '\0'; /* Terminate the string */ +} + +/* Hash table stuff */ + +struct hashtbl { + int size; /* Max number of entries */ + int entries; /* Actual number of entries */ + char **tbl; /* Pointer to start of table */ +}; + +/* Make an empty hash table of size s */ +static struct hashtbl *make_hash(size) +int size; +{ + struct hashtbl *h; + + if(size < 1) size = 1; + h = (struct hashtbl *) malloc(sizeof(struct hashtbl)); + h->size = size; + h->entries = 0; + h->tbl = (char **) calloc(size, sizeof(char *)); + return(h); +} + +/* Destroy a hash table */ +static destroy_hash(h) +struct hashtbl *h; +{ + int i; + + for(i = 0; i < h->size; i++) { + if(h->tbl[i] != NULL) free(h->tbl[i]); + } + free(h->tbl); + free(h); +} + +/* Compute hash value for a string */ +static unsigned hashval(s) +register char *s; +{ + register unsigned hv; + + for(hv = 0; *s != '\0'; s++) { + hv ^= ((hv << 3) ^ *s); + } + return(hv); +} + +/* Add an element to a hash table */ +static add_hash(h, el) +struct hashtbl *h; +char *el; +{ + unsigned hv; + char *s; + char **old; + int i; + + /* Make space if it isn't there already */ + if(h->entries + 1 > (h->size >> 1)) { + old = h->tbl; + h->tbl = (char **) calloc(h->size << 1, sizeof(char *)); + for(i = 0; i < h->size; i++) { + if(old[i] != NULL) { + hv = hashval(old[i]) % (h->size << 1); + while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1); + h->tbl[hv] = old[i]; + } + } + h->size = h->size << 1; + free(old); + } + + hv = hashval(el) % h->size; + while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size; + s = malloc(strlen(el)+1); + strcpy(s, el); + h->tbl[hv] = s; + h->entries++; +} + +/* Returns nonzero if el is in h */ +static check_hash(h, el) +struct hashtbl *h; +char *el; +{ + unsigned hv; + + for(hv = hashval(el) % h->size; + h->tbl[hv] != NULL; + hv = (hv + 1) % h->size) { + if(!strcmp(h->tbl[hv], el)) return(1); + } + return(0); +} + +struct acl { + char filename[LINESIZE]; /* Name of acl file */ + int fd; /* File descriptor for acl file */ + struct stat status; /* File status at last read */ + struct hashtbl *acl; /* Acl entries */ +}; + +static struct acl acl_cache[CACHED_ACLS]; + +static int acl_cache_count = 0; +static int acl_cache_next = 0; + +/* Returns < 0 if unsuccessful in loading acl */ +/* Returns index into acl_cache otherwise */ +/* Note that if acl is already loaded, this is just a lookup */ +static int acl_load(name) +char *name; +{ + int i; + FILE *f; + struct stat s; + char buf[MAX_PRINCIPAL_SIZE]; + char canon[MAX_PRINCIPAL_SIZE]; + + /* See if it's there already */ + for(i = 0; i < acl_cache_count; i++) { + if(!strcmp(acl_cache[i].filename, name) + && acl_cache[i].fd >= 0) goto got_it; + } + + /* It isn't, load it in */ + /* maybe there's still room */ + if(acl_cache_count < CACHED_ACLS) { + i = acl_cache_count++; + } else { + /* No room, clean one out */ + i = acl_cache_next; + acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS; + close(acl_cache[i].fd); + if(acl_cache[i].acl) { + destroy_hash(acl_cache[i].acl); + acl_cache[i].acl = (struct hashtbl *) 0; + } + } + + /* Set up the acl */ + strcpy(acl_cache[i].filename, name); + if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1); + /* Force reload */ + acl_cache[i].acl = (struct hashtbl *) 0; + + got_it: + /* + * See if the stat matches + * + * Use stat(), not fstat(), as the file may have been re-created by + * acl_add or acl_delete. If this happens, the old inode will have + * no changes in the mod-time and the following test will fail. + */ + if(stat(acl_cache[i].filename, &s) < 0) return(-1); + if(acl_cache[i].acl == (struct hashtbl *) 0 + || s.st_nlink != acl_cache[i].status.st_nlink + || s.st_mtime != acl_cache[i].status.st_mtime + || s.st_ctime != acl_cache[i].status.st_ctime) { + /* Gotta reload */ + if(acl_cache[i].fd >= 0) close(acl_cache[i].fd); + if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1); + if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1); + if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl); + acl_cache[i].acl = make_hash(ACL_LEN); + while(fgets(buf, sizeof(buf), f) != NULL) { + nuke_whitespace(buf); + acl_canonicalize_principal(buf, canon); + add_hash(acl_cache[i].acl, canon); + } + fclose(f); + acl_cache[i].status = s; + } + return(i); +} + +/* Returns nonzero if it can be determined that acl contains principal */ +/* Principal is not canonicalized, and no wildcarding is done */ +acl_exact_match(acl, principal) +char *acl; +char *principal; +{ + int idx; + + return((idx = acl_load(acl)) >= 0 + && check_hash(acl_cache[idx].acl, principal)); +} + +/* Returns nonzero if it can be determined that acl contains principal */ +/* Recognizes wildcards in acl of the form + name.*@realm, *.*@realm, and *.*@* */ +acl_check(acl, principal) +char *acl; +char *principal; +{ + char buf[MAX_PRINCIPAL_SIZE]; + char canon[MAX_PRINCIPAL_SIZE]; + char *realm; + + acl_canonicalize_principal(principal, canon); + + /* Is it there? */ + if(acl_exact_match(acl, canon)) return(1); + + /* Try the wildcards */ + realm = index(canon, REALM_SEP); + *index(canon, INST_SEP) = '\0'; /* Chuck the instance */ + + sprintf(buf, "%s.*%s", canon, realm); + if(acl_exact_match(acl, buf)) return(1); + + sprintf(buf, "*.*%s", realm); + if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1); + + return(0); +} + +/* Adds principal to acl */ +/* Wildcards are interpreted literally */ +acl_add(acl, principal) +char *acl; +char *principal; +{ + int idx; + int i; + FILE *new; + char canon[MAX_PRINCIPAL_SIZE]; + + acl_canonicalize_principal(principal, canon); + + if((new = acl_lock_file(acl)) == NULL) return(-1); + if((acl_exact_match(acl, canon)) + || (idx = acl_load(acl)) < 0) { + acl_abort(acl, new); + return(-1); + } + /* It isn't there yet, copy the file and put it in */ + for(i = 0; i < acl_cache[idx].acl->size; i++) { + if(acl_cache[idx].acl->tbl[i] != NULL) { + if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL + || putc('\n', new) != '\n') { + acl_abort(acl, new); + return(-1); + } + } + } + fputs(canon, new); + putc('\n', new); + return(acl_commit(acl, new)); +} + +/* Removes principal from acl */ +/* Wildcards are interpreted literally */ +acl_delete(acl, principal) +char *acl; +char *principal; +{ + int idx; + int i; + FILE *new; + char canon[MAX_PRINCIPAL_SIZE]; + + acl_canonicalize_principal(principal, canon); + + if((new = acl_lock_file(acl)) == NULL) return(-1); + if((!acl_exact_match(acl, canon)) + || (idx = acl_load(acl)) < 0) { + acl_abort(acl, new); + return(-1); + } + /* It isn't there yet, copy the file and put it in */ + for(i = 0; i < acl_cache[idx].acl->size; i++) { + if(acl_cache[idx].acl->tbl[i] != NULL + && strcmp(acl_cache[idx].acl->tbl[i], canon)) { + fputs(acl_cache[idx].acl->tbl[i], new); + putc('\n', new); + } + } + return(acl_commit(acl, new)); +} + diff --git a/eBones/lib/libacl/acl_files.doc b/eBones/lib/libacl/acl_files.doc new file mode 100644 index 0000000..78c448a --- /dev/null +++ b/eBones/lib/libacl/acl_files.doc @@ -0,0 +1,107 @@ +PROTOTYPE ACL LIBRARY + +Introduction + +An access control list (ACL) is a list of principals, where each +principal is is represented by a text string which cannot contain +whitespace. The library allows application programs to refer to named +access control lists to test membership and to atomically add and +delete principals using a natural and intuitive interface. At +present, the names of access control lists are required to be Unix +filenames, and refer to human-readable Unix files; in the future, when +a networked ACL server is implemented, the names may refer to a +different namespace specific to the ACL service. + + +Usage + +cc <files> -lacl -lkrb. + + + +Principal Names + +Principal names have the form + +<name>[.<instance>][@<realm>] + +e.g. + +asp +asp.root +asp@ATHENA.MIT.EDU +asp.@ATHENA.MIT.EDU +asp.root@ATHENA.MIT.EDU + +It is possible for principals to be underspecified. If instance is +missing, it is assumed to be "". If realm is missing, it is assumed +to be local_realm. The canonical form contains all of name, instance, +and realm; the acl_add and acl_delete routines will always +leave the file in that form. Note that the canonical form of +asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU. + + +Routines + +acl_canonicalize_principal(principal, buf) +char *principal; +char *buf; /*RETVAL*/ + +Store the canonical form of principal in buf. Buf must contain enough +space to store a principal, given the limits on the sizes of name, +instance, and realm specified in /usr/include/krb.h. + +acl_check(acl, principal) +char *acl; +char *principal; + +Returns nonzero if principal appears in acl. Returns 0 if principal +does not appear in acl, or if an error occurs. Canonicalizes +principal before checking, and allows the ACL to contain wildcards. + +acl_exact_match(acl, principal) +char *acl; +char *principal; + +Like acl_check, but does no canonicalization or wildcarding. + +acl_add(acl, principal) +char *acl; +char *principal; + +Atomically adds principal to acl. Returns 0 if successful, nonzero +otherwise. It is considered a failure if principal is already in acl. +This routine will canonicalize principal, but will treat wildcards +literally. + +acl_delete(acl, principal) +char *acl; +char *principal; + +Atomically deletes principal from acl. Returns 0 if successful, +nonzero otherwise. It is consider a failure if principal is not +already in acl. This routine will canonicalize principal, but will +treat wildcards literally. + +acl_initialize(acl, mode) +char *acl; +int mode; + +Initialize acl. If acl file does not exist, creates it with mode +mode. If acl exists, removes all members. Returns 0 if successful, +nonzero otherwise. WARNING: Mode argument is likely to change with +the eventual introduction of an ACL service. + + +Known problems + +In the presence of concurrency, there is a very small chance that +acl_add or acl_delete could report success even though it would have +had no effect. This is a necessary side effect of using lock files +for concurrency control rather than flock(2), which is not supported +by NFS. + +The current implementation caches ACLs in memory in a hash-table +format for increased efficiency in checking membership; one effect of +the caching scheme is that one file descriptor will be kept open for +each ACL cached, up to a maximum of 8. diff --git a/eBones/lib/libkdb/Makefile b/eBones/lib/libkdb/Makefile new file mode 100644 index 0000000..b69c0d9 --- /dev/null +++ b/eBones/lib/libkdb/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.3 1994/09/09 21:43:41 g89r4222 Exp $ + +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 + +LIB= kdb +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c + +.include <bsd.lib.mk> diff --git a/eBones/lib/libkdb/krb_cache.c b/eBones/lib/libkdb/krb_cache.c new file mode 100644 index 0000000..4d8c594 --- /dev/null +++ b/eBones/lib/libkdb/krb_cache.c @@ -0,0 +1,193 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This is where a cache would be implemented, if it were necessary. + * + * from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $ + * $Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +extern char *strncpy(); + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +#endif +static init = 0; + +/* + * initialization routine for cache + */ + +int +kerb_cache_init() +{ + init = 1; + return (0); +} + +/* + * look up a principal in the cache returns number of principals found + */ + +int +kerb_cache_get_principal(serv, inst, principal, max) + char *serv; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + +{ + int found = 0; + u_long i; + + if (!init) + kerb_cache_init(); +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "cache_get_principal for %s %s max = %d\n", + serv, inst, max); +#endif DEBUG + +#ifdef DEBUG + if (kerb_debug & 2) { + if (found) { + fprintf(stderr, "cache get %s %s found %s %s sid = %d\n", + serv, inst, principal->name, principal->instance); + } else { + fprintf(stderr, "cache %s %s not found\n", serv, + inst); + } + } +#endif + return (found); +} + +/* + * insert/replace a principal in the cache returns number of principals + * inserted + */ + +int +kerb_cache_put_principal(principal, max) + Principal *principal; + unsigned int max; /* max number of principal structs to + * insert */ + +{ + int found = 0; + u_long i; + int count = 0; + + if (!init) + kerb_cache_init(); + +#ifdef DEBUG + if (kerb_debug & 2) { + fprintf(stderr, "kerb_cache_put_principal max = %d", + max); + } +#endif + + for (i = 0; i < max; i++) { +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "\n %s %s", + principal->name, principal->instance); +#endif + /* DO IT */ + count++; + principal++; + } + return count; +} + +/* + * look up a dba in the cache returns number of dbas found + */ + +int +kerb_cache_get_dba(serv, inst, dba, max) + char *serv; /* could have wild card */ + char *inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + +{ + int found = 0; + u_long i; + + if (!init) + kerb_cache_init(); + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "cache_get_dba for %s %s max = %d\n", + serv, inst, max); +#endif + +#ifdef DEBUG + if (kerb_debug & 2) { + if (found) { + fprintf(stderr, "cache get %s %s found %s %s sid = %d\n", + serv, inst, dba->name, dba->instance); + } else { + fprintf(stderr, "cache %s %s not found\n", serv, inst); + } + } +#endif + return (found); +} + +/* + * insert/replace a dba in the cache returns number of dbas inserted + */ + +int +kerb_cache_put_dba(dba, max) + Dba *dba; + unsigned int max; /* max number of dba structs to insert */ + +{ + int found = 0; + u_long i; + int count = 0; + + if (!init) + kerb_cache_init(); +#ifdef DEBUG + if (kerb_debug & 2) { + fprintf(stderr, "kerb_cache_put_dba max = %d", max); + } +#endif + for (i = 0; i < max; i++) { +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "\n %s %s", + dba->name, dba->instance); +#endif + /* DO IT */ + count++; + dba++; + } + return count; +} + diff --git a/eBones/lib/libkdb/krb_dbl.c b/eBones/lib/libkdb/krb_dbl.c new file mode 100644 index 0000000..7776298 --- /dev/null +++ b/eBones/lib/libkdb/krb_dbl.c @@ -0,0 +1 @@ +This file is now obsolete. diff --git a/eBones/lib/libkdb/krb_dbm.c b/eBones/lib/libkdb/krb_dbm.c new file mode 100644 index 0000000..754dd68 --- /dev/null +++ b/eBones/lib/libkdb/krb_dbm.c @@ -0,0 +1,741 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $ + * $Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $"; +#endif lint + +#if defined(__FreeBSD__) +#define NDBM +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/resource.h> +#include <sys/errno.h> +#include <strings.h> +#include <des.h> +#include <sys/file.h> +#ifdef NDBM +#include <ndbm.h> +#else /*NDBM*/ +#include <dbm.h> +#endif /*NDBM*/ +/* before krb_db.h */ +#include <krb.h> +#include <krb_db.h> + +#define KERB_DB_MAX_RETRY 5 + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +extern char *progname; +#endif +extern char *malloc(); +extern int errno; + +static init = 0; +static char default_db_name[] = DBM_FILE; +static char *current_db_name = default_db_name; +static void encode_princ_key(), decode_princ_key(); +static void encode_princ_contents(), decode_princ_contents(); +static void kerb_dbl_fini(); +static int kerb_dbl_lock(); +static void kerb_dbl_unlock(); + +static struct timeval timestamp;/* current time of request */ +static int non_blocking = 0; + +/* + * This module contains all of the code which directly interfaces to + * the underlying representation of the Kerberos database; this + * implementation uses a DBM or NDBM indexed "file" (actually + * implemented as two separate files) to store the relations, plus a + * third file as a semaphore to allow the database to be replaced out + * from underneath the KDC server. + */ + +/* + * Locking: + * + * There are two distinct locking protocols used. One is designed to + * lock against processes (the admin_server, for one) which make + * incremental changes to the database; the other is designed to lock + * against utilities (kdb_util, kpropd) which replace the entire + * database in one fell swoop. + * + * The first locking protocol is implemented using flock() in the + * krb_dbl_lock() and krb_dbl_unlock routines. + * + * The second locking protocol is necessary because DBM "files" are + * actually implemented as two separate files, and it is impossible to + * atomically rename two files simultaneously. It assumes that the + * database is replaced only very infrequently in comparison to the time + * needed to do a database read operation. + * + * A third file is used as a "version" semaphore; the modification + * time of this file is the "version number" of the database. + * At the start of a read operation, the reader checks the version + * number; at the end of the read operation, it checks again. If the + * version number changed, or if the semaphore was nonexistant at + * either time, the reader sleeps for a second to let things + * stabilize, and then tries again; if it does not succeed after + * KERB_DB_MAX_RETRY attempts, it gives up. + * + * On update, the semaphore file is deleted (if it exists) before any + * update takes place; at the end of the update, it is replaced, with + * a version number strictly greater than the version number which + * existed at the start of the update. + * + * If the system crashes in the middle of an update, the semaphore + * file is not automatically created on reboot; this is a feature, not + * a bug, since the database may be inconsistant. Note that the + * absence of a semaphore file does not prevent another _update_ from + * taking place later. Database replacements take place automatically + * only on slave servers; a crash in the middle of an update will be + * fixed by the next slave propagation. A crash in the middle of an + * update on the master would be somewhat more serious, but this would + * likely be noticed by an administrator, who could fix the problem and + * retry the operation. + */ + +/* Macros to convert ndbm names to dbm names. + * Note that dbm_nextkey() cannot be simply converted using a macro, since + * it is invoked giving the database, and nextkey() needs the previous key. + * + * Instead, all routines call "dbm_next" instead. + */ + +#ifndef NDBM +typedef char DBM; + +#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0)) +#define dbm_fetch(db, key) fetch(key) +#define dbm_store(db, key, content, flag) store(key, content) +#define dbm_firstkey(db) firstkey() +#define dbm_next(db,key) nextkey(key) +#define dbm_close(db) dbmclose() +#else +#define dbm_next(db,key) dbm_nextkey(db) +#endif + +/* + * Utility routine: generate name of database file. + */ + +static char *gen_dbsuffix(db_name, sfx) + char *db_name; + char *sfx; +{ + char *dbsuffix; + + if (sfx == NULL) + sfx = ".ok"; + + dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1); + strcpy(dbsuffix, db_name); + strcat(dbsuffix, sfx); + return dbsuffix; +} + +/* + * initialization for data base routines. + */ + +kerb_db_init() +{ + init = 1; + return (0); +} + +/* + * gracefully shut down database--must be called by ANY program that does + * a kerb_db_init + */ + +kerb_db_fini() +{ +} + +/* + * Set the "name" of the current database to some alternate value. + * + * Passing a null pointer as "name" will set back to the default. + * If the alternate database doesn't exist, nothing is changed. + */ + +kerb_db_set_name(name) + char *name; +{ + DBM *db; + + if (name == NULL) + name = default_db_name; + db = dbm_open(name, 0, 0); + if (db == NULL) + return errno; + dbm_close(db); + kerb_dbl_fini(); + current_db_name = name; + return 0; +} + +/* + * Return the last modification time of the database. + */ + +long kerb_get_db_age() +{ + struct stat st; + char *okname; + long age; + + okname = gen_dbsuffix(current_db_name, ".ok"); + + if (stat (okname, &st) < 0) + age = 0; + else + age = st.st_mtime; + + free (okname); + return age; +} + +/* + * Remove the semaphore file; indicates that database is currently + * under renovation. + * + * This is only for use when moving the database out from underneath + * the server (for example, during slave updates). + */ + +static long kerb_start_update(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + long age = kerb_get_db_age(); + + if (unlink(okname) < 0 + && errno != ENOENT) { + age = -1; + } + free (okname); + return age; +} + +static long kerb_end_update(db_name, age) + char *db_name; + long age; +{ + int fd; + int retval = 0; + char *new_okname = gen_dbsuffix(db_name, ".ok#"); + char *okname = gen_dbsuffix(db_name, ".ok"); + + fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + retval = errno; + else { + struct stat st; + struct timeval tv[2]; + /* make sure that semaphore is "after" previous value. */ + if (fstat (fd, &st) == 0 + && st.st_mtime <= age) { + tv[0].tv_sec = st.st_atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = age; + tv[1].tv_usec = 0; + /* set times.. */ + utimes (new_okname, tv); + fsync(fd); + } + close(fd); + if (rename (new_okname, okname) < 0) + retval = errno; + } + + free (new_okname); + free (okname); + + return retval; +} + +static long kerb_start_read() +{ + return kerb_get_db_age(); +} + +static long kerb_end_read(age) + u_long age; +{ + if (kerb_get_db_age() != age || age == -1) { + return -1; + } + return 0; +} + +/* + * Create the database, assuming it's not there. + */ + +kerb_db_create(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + int fd; + register int ret = 0; +#ifdef NDBM + DBM *db; + + db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (db == NULL) + ret = errno; + else + dbm_close(db); +#else + char *dirname = gen_dbsuffix(db_name, ".dir"); + char *pagname = gen_dbsuffix(db_name, ".pag"); + + fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else { + close(fd); + fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else + close(fd); + } + if (dbminit(db_name) < 0) + ret = errno; +#endif + if (ret == 0) { + fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + ret = errno; + close(fd); + } + return ret; +} + +/* + * "Atomically" rename the database in a way that locks out read + * access in the middle of the rename. + * + * Not perfect; if we crash in the middle of an update, we don't + * necessarily know to complete the transaction the rename, but... + */ + +kerb_db_rename(from, to) + char *from; + char *to; +{ + char *fromdir = gen_dbsuffix (from, ".dir"); + char *todir = gen_dbsuffix (to, ".dir"); + char *frompag = gen_dbsuffix (from , ".pag"); + char *topag = gen_dbsuffix (to, ".pag"); + char *fromok = gen_dbsuffix(from, ".ok"); + long trans = kerb_start_update(to); + int ok; + + if ((rename (fromdir, todir) == 0) + && (rename (frompag, topag) == 0)) { + (void) unlink (fromok); + ok = 1; + } + + free (fromok); + free (fromdir); + free (todir); + free (frompag); + free (topag); + if (ok) + return kerb_end_update(to, trans); + else + return -1; +} + +/* + * look up a principal in the data base returns number of principals + * found , and whether there were more than requested. + */ + +kerb_db_get_principal(name, inst, principal, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + int *more; /* where there more than 'max' tuples? */ + +{ + int found = 0, code; + extern int errorproc(); + int wildp, wildi; + datum key, contents; + char testname[ANAME_SZ], testinst[INST_SZ]; + u_long trans; + int try; + DBM *db; + + if (!init) + kerb_db_init(); /* initialize database routines */ + + for (try = 0; try < KERB_DB_MAX_RETRY; try++) { + trans = kerb_start_read(); + + if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0) + return -1; + + db = dbm_open(current_db_name, O_RDONLY, 0600); + + *more = 0; + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, + "%s: db_get_principal for %s %s max = %d", + progname, name, inst, max); +#endif + + wildp = !strcmp(name, "*"); + wildi = !strcmp(inst, "*"); + + if (!wildi && !wildp) { /* nothing's wild */ + encode_princ_key(&key, name, inst); + contents = dbm_fetch(db, key); + if (contents.dptr == NULL) { + found = 0; + goto done; + } + decode_princ_contents(&contents, principal); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n", + principal->name, principal->instance, + strlen(principal->name), + strlen(principal->instance)); + } +#endif + found = 1; + goto done; + } + /* process wild cards by looping through entire database */ + + for (key = dbm_firstkey(db); key.dptr != NULL; + key = dbm_next(db, key)) { + decode_princ_key(&key, testname, testinst); + if ((wildp || !strcmp(testname, name)) && + (wildi || !strcmp(testinst, inst))) { /* have a match */ + if (found >= max) { + *more = 1; + goto done; + } else { + found++; + contents = dbm_fetch(db, key); + decode_princ_contents(&contents, principal); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, + "\tfound %s %s p_n length %d t_n length %d\n", + principal->name, principal->instance, + strlen(principal->name), + strlen(principal->instance)); + } +#endif + principal++; /* point to next */ + } + } + } + + done: + kerb_dbl_unlock(); /* unlock read lock */ + dbm_close(db); + if (kerb_end_read(trans) == 0) + break; + found = -1; + if (!non_blocking) + sleep(1); + } + return (found); +} + +/* + * Update a name in the data base. Returns number of names + * successfully updated. + */ + +kerb_db_put_principal(principal, max) + Principal *principal; + unsigned int max; /* number of principal structs to + * update */ + +{ + int found = 0, code; + u_long i; + extern int errorproc(); + datum key, contents; + DBM *db; + + gettimeofday(×tamp, NULL); + + if (!init) + kerb_db_init(); + + if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0) + return -1; + + db = dbm_open(current_db_name, O_RDWR, 0600); + +#ifdef DEBUG + if (kerb_debug & 2) + fprintf(stderr, "%s: kerb_db_put_principal max = %d", + progname, max); +#endif + + /* for each one, stuff temps, and do replace/append */ + for (i = 0; i < max; i++) { + encode_princ_contents(&contents, principal); + encode_princ_key(&key, principal->name, principal->instance); + dbm_store(db, key, contents, DBM_REPLACE); +#ifdef DEBUG + if (kerb_debug & 1) { + fprintf(stderr, "\n put %s %s\n", + principal->name, principal->instance); + } +#endif + found++; + principal++; /* bump to next struct */ + } + + dbm_close(db); + kerb_dbl_unlock(); /* unlock database */ + return (found); +} + +static void +encode_princ_key(key, name, instance) + datum *key; + char *name, *instance; +{ + static char keystring[ANAME_SZ + INST_SZ]; + + bzero(keystring, ANAME_SZ + INST_SZ); + strncpy(keystring, name, ANAME_SZ); + strncpy(&keystring[ANAME_SZ], instance, INST_SZ); + key->dptr = keystring; + key->dsize = ANAME_SZ + INST_SZ; +} + +static void +decode_princ_key(key, name, instance) + datum *key; + char *name, *instance; +{ + strncpy(name, key->dptr, ANAME_SZ); + strncpy(instance, key->dptr + ANAME_SZ, INST_SZ); + name[ANAME_SZ - 1] = '\0'; + instance[INST_SZ - 1] = '\0'; +} + +static void +encode_princ_contents(contents, principal) + datum *contents; + Principal *principal; +{ + contents->dsize = sizeof(*principal); + contents->dptr = (char *) principal; +} + +static void +decode_princ_contents(contents, principal) + datum *contents; + Principal *principal; +{ + bcopy(contents->dptr, (char *) principal, sizeof(*principal)); +} + +kerb_db_get_stat(s) + DB_stat *s; +{ + gettimeofday(×tamp, NULL); + + + s->cpu = 0; + s->elapsed = 0; + s->dio = 0; + s->pfault = 0; + s->t_stamp = timestamp.tv_sec; + s->n_retrieve = 0; + s->n_replace = 0; + s->n_append = 0; + s->n_get_stat = 0; + s->n_put_stat = 0; + /* update local copy too */ +} + +kerb_db_put_stat(s) + DB_stat *s; +{ +} + +delta_stat(a, b, c) + DB_stat *a, *b, *c; +{ + /* c = a - b then b = a for the next time */ + + c->cpu = a->cpu - b->cpu; + c->elapsed = a->elapsed - b->elapsed; + c->dio = a->dio - b->dio; + c->pfault = a->pfault - b->pfault; + c->t_stamp = a->t_stamp - b->t_stamp; + c->n_retrieve = a->n_retrieve - b->n_retrieve; + c->n_replace = a->n_replace - b->n_replace; + c->n_append = a->n_append - b->n_append; + c->n_get_stat = a->n_get_stat - b->n_get_stat; + c->n_put_stat = a->n_put_stat - b->n_put_stat; + + bcopy(a, b, sizeof(DB_stat)); + return; +} + +/* + * look up a dba in the data base returns number of dbas found , and + * whether there were more than requested. + */ + +kerb_db_get_dba(dba_name, dba_inst, dba, max, more) + char *dba_name; /* could have wild card */ + char *dba_inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + int *more; /* where there more than 'max' tuples? */ + +{ + *more = 0; + return (0); +} + +kerb_db_iterate (func, arg) + int (*func)(); + char *arg; /* void *, really */ +{ + datum key, contents; + Principal *principal; + int code; + DBM *db; + + kerb_db_init(); /* initialize and open the database */ + if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0) + return code; + + db = dbm_open(current_db_name, O_RDONLY, 0600); + + for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) { + contents = dbm_fetch (db, key); + /* XXX may not be properly aligned */ + principal = (Principal *) contents.dptr; + if ((code = (*func)(arg, principal)) != 0) + return code; + } + dbm_close(db); + kerb_dbl_unlock(); + return 0; +} + +static int dblfd = -1; +static int mylock = 0; +static int inited = 0; + +static kerb_dbl_init() +{ + if (!inited) { + char *filename = gen_dbsuffix (current_db_name, ".ok"); + if ((dblfd = open(filename, 0)) < 0) { + fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename); + fflush(stderr); + perror("open"); + exit(1); + } + free(filename); + inited++; + } + return (0); +} + +static void kerb_dbl_fini() +{ + close(dblfd); + dblfd = -1; + inited = 0; + mylock = 0; +} + +static int kerb_dbl_lock(mode) + int mode; +{ + int flock_mode; + + if (!inited) + kerb_dbl_init(); + if (mylock) { /* Detect lock call when lock already + * locked */ + fprintf(stderr, "Kerberos locking error (mylock)\n"); + fflush(stderr); + exit(1); + } + switch (mode) { + case KERB_DBL_EXCLUSIVE: + flock_mode = LOCK_EX; + break; + case KERB_DBL_SHARED: + flock_mode = LOCK_SH; + break; + default: + fprintf(stderr, "invalid lock mode %d\n", mode); + abort(); + } + if (non_blocking) + flock_mode |= LOCK_NB; + + if (flock(dblfd, flock_mode) < 0) + return errno; + mylock++; + return 0; +} + +static void kerb_dbl_unlock() +{ + if (!mylock) { /* lock already unlocked */ + fprintf(stderr, "Kerberos database lock not locked when unlocking.\n"); + fflush(stderr); + exit(1); + } + if (flock(dblfd, LOCK_UN) < 0) { + fprintf(stderr, "Kerberos database lock error. (unlocking)\n"); + fflush(stderr); + perror("flock"); + exit(1); + } + mylock = 0; +} + +int kerb_db_set_lockmode(mode) + int mode; +{ + int old = non_blocking; + non_blocking = mode; + return old; +} diff --git a/eBones/lib/libkdb/krb_kdb_utils.c b/eBones/lib/libkdb/krb_kdb_utils.c new file mode 100644 index 0000000..5fccc53 --- /dev/null +++ b/eBones/lib/libkdb/krb_kdb_utils.c @@ -0,0 +1,141 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Utility routines for Kerberos programs which directly access + * the database. This code was duplicated in too many places + * before I gathered it here. + * + * Jon Rochlis, MIT Telecom, March 1988 + * + * from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $ + * $Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $"; +#endif lint + +#include <des.h> +#include <krb.h> +#include <krb_db.h> +#include <kdc.h> +#include <stdio.h> +#include <sys/file.h> + +long kdb_get_master_key(prompt, master_key, master_key_sched) + int prompt; + C_Block master_key; + Key_schedule master_key_sched; +{ + int kfile; + + if (prompt) { +#ifdef NOENCRYPTION + placebo_read_password(master_key, + "\nEnter Kerberos master key: ", 0); +#else + des_read_password(master_key, + "\nEnter Kerberos master key: ", 0); +#endif + printf ("\n"); + } + else { + kfile = open(MKEYFILE, O_RDONLY, 0600); + if (kfile < 0) { + /* oh, for com_err_ */ + return (-1); + } + if (read(kfile, (char *) master_key, 8) != 8) { + return (-1); + } + close(kfile); + } + +#ifndef NOENCRYPTION + key_sched(master_key,master_key_sched); +#endif + return (0); +} + +/* The caller is reasponsible for cleaning up the master key and sched, + even if we can't verify the master key */ + +/* Returns master key version if successful, otherwise -1 */ + +long kdb_verify_master_key (master_key, master_key_sched, out) + C_Block master_key; + Key_schedule master_key_sched; + FILE *out; /* setting this to non-null be do output */ +{ + C_Block key_from_db; + Principal principal_data[1]; + int n, more = 0; + long master_key_version; + + /* lookup the master key version */ + n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data, + 1 /* only one please */, &more); + if ((n != 1) || more) { + if (out != (FILE *) NULL) + fprintf(out, + "verify_master_key: %s, %d found.\n", + "Kerberos error on master key version lookup", + n); + return (-1); + } + + master_key_version = (long) principal_data[0].key_version; + + /* set up the master key */ + if (out != (FILE *) NULL) /* should we punt this? */ + fprintf(out, "Current Kerberos master key version is %d.\n", + principal_data[0].kdc_key_ver); + + /* + * now use the master key to decrypt the key in the db, had better + * be the same! + */ + bcopy(&principal_data[0].key_low, key_from_db, 4); + bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4); + kdb_encrypt_key (key_from_db, key_from_db, + master_key, master_key_sched, DECRYPT); + + /* the decrypted database key had better equal the master key */ + n = bcmp((char *) master_key, (char *) key_from_db, + sizeof(master_key)); + /* this used to zero the master key here! */ + bzero(key_from_db, sizeof(key_from_db)); + bzero(principal_data, sizeof (principal_data)); + + if (n && (out != (FILE *) NULL)) { + fprintf(out, "\n\07\07verify_master_key: Invalid master key; "); + fprintf(out, "does not match database.\n"); + return (-1); + } + if (out != (FILE *) NULL) { + fprintf(out, "\nMaster key entered. BEWARE!\07\07\n"); + fflush(out); + } + + return (master_key_version); +} + +/* The old algorithm used the key schedule as the initial vector which + was byte order depedent ... */ + +kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag) + C_Block in, out, master_key; + Key_schedule master_key_sched; + int e_d_flag; +{ + +#ifdef NOENCRYPTION + bcopy(in, out, sizeof(C_Block)); +#else + pcbc_encrypt(in,out,(long)sizeof(C_Block),master_key_sched,master_key, + e_d_flag); +#endif +} diff --git a/eBones/lib/libkdb/krb_lib.c b/eBones/lib/libkdb/krb_lib.c new file mode 100644 index 0000000..f0f1f6f --- /dev/null +++ b/eBones/lib/libkdb/krb_lib.c @@ -0,0 +1,242 @@ +/* + * $Source: /home/CVS/src/eBones/kdb/krb_lib.c,v $ + * $Author: g89r4222 $ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_lib.c,v 1.2 1994/07/19 19:23:39 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +#ifdef DEBUG +extern int debug; +extern char *progname; +long kerb_debug; +#endif + +extern char *strncpy(); +extern char *ctime(); +extern char *getenv(); + +static init = 0; + +/* + * initialization routine for data base + */ + +int +kerb_init() +{ +#ifdef DEBUG + if (!init) { + char *dbg = getenv("KERB_DBG"); + if (dbg) + sscanf(dbg, "%d", &kerb_debug); + init = 1; + } +#endif + kerb_db_init(); + +#ifdef CACHE + kerb_cache_init(); +#endif + + /* successful init, return 0, else errcode */ + return (0); +} + +/* + * finalization routine for database -- NOTE: MUST be called by any + * program using kerb_init. ALSO will have to be modified to finalize + * caches, if they're ever really implemented. + */ + +int +kerb_fini() +{ + kerb_db_fini(); +} + +/* + * look up a principal in the cache or data base returns number of + * principals found + */ + +int +kerb_get_principal(name, inst, principal, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; + unsigned int max; /* max number of name structs to return */ + int *more; /* more tuples than room for */ + +{ + int found = 0; +#ifdef CACHE + static int wild = 0; +#endif + if (!init) + kerb_init(); + +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n", + progname, name, inst, max); +#endif + + /* + * if this is a request including a wild card, have to go to db + * since the cache may not be exhaustive. + */ + + /* clear the principal area */ + bzero((char *) principal, max * sizeof(Principal)); + +#ifdef CACHE + /* + * so check to see if the name contains a wildcard "*" or "?", not + * preceeded by a backslash. + */ + wild = 0; + if (index(name, '*') || index(name, '?') || + index(inst, '*') || index(inst, '?')) + wild = 1; + + if (!wild) { + /* try the cache first */ + found = kerb_cache_get_principal(name, inst, principal, max, more); + if (found) + return (found); + } +#endif + /* If we didn't try cache, or it wasn't there, try db */ + found = kerb_db_get_principal(name, inst, principal, max, more); + /* try to insert principal(s) into cache if it was found */ +#ifdef CACHE + if (found) { + kerb_cache_put_principal(principal, found); + } +#endif + return (found); +} + +/* principals */ +kerb_put_principal(principal, n) + Principal *principal; + unsigned int n; /* number of principal structs to write */ +{ + long time(); + struct tm *tp, *localtime(); + + /* set mod date */ + principal->mod_date = time((long *)0); + /* and mod date string */ + + tp = localtime(&principal->mod_date); + (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d", + tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900, + tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */ +#ifdef DEBUG + if (kerb_debug & 1) { + int i; + fprintf(stderr, "\nkerb_put_principal..."); + for (i = 0; i < n; i++) { + krb_print_principal(&principal[i]); + } + } +#endif + /* write database */ + if (kerb_db_put_principal(principal, n) < 0) { +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_db_put_principal err", progname); + /* watch out for cache */ +#endif + return -1; + } +#ifdef CACHE + /* write cache */ + if (!kerb_cache_put_principal(principal, n)) { +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname); +#endif + return -1; + } +#endif + return 0; +} + +int +kerb_get_dba(name, inst, dba, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Dba *dba; + unsigned int max; /* max number of name structs to return */ + int *more; /* more tuples than room for */ + +{ + int found = 0; +#ifdef CACHE + static int wild = 0; +#endif + if (!init) + kerb_init(); + +#ifdef DEBUG + if (kerb_debug & 1) + fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n", + progname, name, inst, max); +#endif + /* + * if this is a request including a wild card, have to go to db + * since the cache may not be exhaustive. + */ + + /* clear the dba area */ + bzero((char *) dba, max * sizeof(Dba)); + +#ifdef CACHE + /* + * so check to see if the name contains a wildcard "*" or "?", not + * preceeded by a backslash. + */ + + wild = 0; + if (index(name, '*') || index(name, '?') || + index(inst, '*') || index(inst, '?')) + wild = 1; + + if (!wild) { + /* try the cache first */ + found = kerb_cache_get_dba(name, inst, dba, max, more); + if (found) + return (found); + } +#endif + /* If we didn't try cache, or it wasn't there, try db */ + found = kerb_db_get_dba(name, inst, dba, max, more); +#ifdef CACHE + /* try to insert dba(s) into cache if it was found */ + if (found) { + kerb_cache_put_dba(dba, found); + } +#endif + return (found); +} diff --git a/eBones/lib/libkdb/print_princ.c b/eBones/lib/libkdb/print_princ.c new file mode 100644 index 0000000..730cfb7 --- /dev/null +++ b/eBones/lib/libkdb/print_princ.c @@ -0,0 +1,50 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: $Header: /home/CVS/src/eBones/kdb/print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $ + * $Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <strings.h> +#include <krb.h> +#include <krb_db.h> + +extern int debug; +extern char *strncpy(); +extern char *ctime(); +extern struct tm *localtime(); +struct tm *time_p; + +long kerb_debug; + +krb_print_principal(a_n) + Principal *a_n; +{ + /* run-time database does not contain string versions */ + time_p = localtime(&(a_n->exp_date)); + + fprintf(stderr, + "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x", + a_n->name, a_n->instance, + time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900, + time_p->tm_mon + 1, time_p->tm_mday, + time_p->tm_hour, time_p->tm_min, + a_n->max_life, 5 * a_n->max_life, a_n->attributes); + + fprintf(stderr, + "\n\tkey_ver %d k_low 0x%08x k_high 0x%08x akv %d exists %d\n", + a_n->key_version, a_n->key_low, a_n->key_high, + a_n->kdc_key_ver, a_n->old); + + fflush(stderr); +} diff --git a/eBones/lib/libkrb/Makefile b/eBones/lib/libkrb/Makefile new file mode 100644 index 0000000..8336132 --- /dev/null +++ b/eBones/lib/libkrb/Makefile @@ -0,0 +1,31 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.4 1994/09/07 16:10:17 g89r4222 Exp $ + +LIB= krb +SHLIB_MAJOR= 2 +SHLIB_MINOR= 0 +CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42 +SRCS= create_auth_reply.c create_ciph.c \ + create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \ + des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \ + get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \ + get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \ + get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \ + k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \ + krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \ + mk_priv.c mk_req.c mk_safe.c month_sname.c \ + netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \ + rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \ + save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \ + tkt_string.c util.c + +TDIR= ${.CURDIR}/.. +krb_err.et.c: ${COMPILE_ET} + (cd ${TDIR}/compile_et; make) + ${COMPILE_ET} ${.CURDIR}/krb_err.et -n + +beforedepend: krb_err.et.c + +CLEANFILES+= krb_err.et.c krb_err.h + +.include <bsd.lib.mk> diff --git a/eBones/lib/libkrb/add_ticket.c b/eBones/lib/libkrb/add_ticket.c new file mode 100644 index 0000000..cb79a18 --- /dev/null +++ b/eBones/lib/libkrb/add_ticket.c @@ -0,0 +1,88 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $ + * $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is now obsolete. It used to be possible to request + * more than one ticket at a time from the authentication server, and + * it looks like this routine was used by the server to package the + * tickets to be returned to the client. + */ + +/* + * This routine adds a new ticket to the ciphertext to be returned to + * the client. The routine takes the ciphertext (which doesn't get + * encrypted till later), the number of the ticket (i.e. 1st, 2nd, + * etc) the session key which goes in the ticket and is sent back to + * the user, the lifetime for the ticket, the service name, the + * instance, the realm, the key version number, and the ticket itself. + * + * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on + * failure. On failure, which occurs when there isn't enough room + * for the ticket, a 0 length ticket is added. + * + * Notes: This routine must be called with successive values of n. + * i.e. the ticket must be added in order. The corresponding routine + * on the client side is extract ticket. + */ + +/* XXX they aren't all used; to avoid incompatible changes we will + * fool lint for the moment */ +/*ARGSUSED */ +add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket) + KTEXT cipher; /* Ciphertext info for ticket */ + char *sname; /* Service name */ + char *instance; /* Instance */ + int n; /* Relative position of this ticket */ + char *session; /* Session key for this tkt */ + int lifetime; /* Lifetime of this ticket */ + char *realm; /* Realm in which ticket is valid */ + int kvno; /* Key version number of service key */ + KTEXT ticket; /* The ticket itself */ +{ + + /* Note, the 42 is a temporary hack; it will have to be changed. */ + + /* Begin check of ticket length */ + if ((cipher->length + ticket->length + 4 + 42 + + (*(cipher->dat)+1-n)*(11+strlen(realm))) > + MAX_KTXT_LEN) { + bcopy(session,(char *)(cipher->dat+cipher->length),8); + *(cipher->dat+cipher->length+8) = (char) lifetime; + *(cipher->dat+cipher->length+9) = (char) kvno; + (void) strcpy((char *)(cipher->dat+cipher->length+10),realm); + cipher->length += 11 + strlen(realm); + *(cipher->dat+n) = 0; + return(KFAILURE); + } + /* End check of ticket length */ + + /* Add the session key, lifetime, kvno, ticket to the ciphertext */ + bcopy(session,(char *)(cipher->dat+cipher->length),8); + *(cipher->dat+cipher->length+8) = (char) lifetime; + *(cipher->dat+cipher->length+9) = (char) kvno; + (void) strcpy((char *)(cipher->dat+cipher->length+10),realm); + cipher->length += 11 + strlen(realm); + bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length), + ticket->length); + cipher->length += ticket->length; + + /* Set the ticket length at beginning of ciphertext */ + *(cipher->dat+n) = ticket->length; + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/create_auth_reply.c b/eBones/lib/libkrb/create_auth_reply.c new file mode 100644 index 0000000..e47d4df --- /dev/null +++ b/eBones/lib/libkrb/create_auth_reply.c @@ -0,0 +1,116 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $ + * $Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is called by the Kerberos authentication server + * to create a reply to an authentication request. The routine + * takes the user's name, instance, and realm, the client's + * timestamp, the number of tickets, the user's key version + * number and the ciphertext containing the tickets themselves. + * It constructs a packet and returns a pointer to it. + * + * Notes: The packet returned by this routine is static. Thus, if you + * intend to keep the result beyond the next call to this routine, you + * must copy it elsewhere. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_KDC_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned char n number of tickets + * + * unsigned long x_date expiration date + * + * unsigned char kvno master key version + * + * short w_1 cipher length + * + * --- cipher->dat cipher data + */ + +KTEXT +create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher) + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long time_ws; /* Workstation time */ + int n; /* Number of tickets */ + unsigned long x_date; /* Principal's expiration date */ + int kvno; /* Principal's key version number */ + KTEXT cipher; /* Cipher text with tickets and + * session keys */ +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + unsigned char *v = pkt->dat; /* Prot vers number */ + unsigned char *t = (pkt->dat+1); /* Prot message type */ + short w_l; /* Cipher length */ + + /* Create fixed part of packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REPLY; + *t |= HOST_BYTE_ORDER; + + if (n != 0) + *v = 3; + + /* Add the basic info */ + (void) strcpy((char *) (pkt->dat+2), pname); + pkt->length = 3 + strlen(pname); + (void) strcpy((char *) (pkt->dat+pkt->length),pinst); + pkt->length += 1 + strlen(pinst); + (void) strcpy((char *) (pkt->dat+pkt->length),prealm); + pkt->length += 1 + strlen(prealm); + /* Workstation timestamp */ + bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (unsigned char) n; + /* Expiration date */ + bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + + /* Now send the ciphertext and info to help decode it */ + *(pkt->dat+(pkt->length)++) = (unsigned char) kvno; + w_l = (short) cipher->length; + bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2); + pkt->length += 2; + bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length), + cipher->length); + pkt->length += cipher->length; + + /* And return the packet */ + return pkt; +} diff --git a/eBones/lib/libkrb/create_ciph.c b/eBones/lib/libkrb/create_ciph.c new file mode 100644 index 0000000..c3bc0db --- /dev/null +++ b/eBones/lib/libkrb/create_ciph.c @@ -0,0 +1,109 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $ + * $Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <strings.h> + +/* + * This routine is used by the authentication server to create + * a packet for its client, containing a ticket for the requested + * service (given in "tkt"), and some information about the ticket, + * + * Returns KSUCCESS no matter what. + * + * The length of the cipher is stored in c->length; the format of + * c->dat is as follows: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * + * 8 bytes session session key for client, service + * + * string service service name + * + * string instance service instance + * + * string realm KDC realm + * + * unsigned char life ticket lifetime + * + * unsigned char kvno service key version number + * + * unsigned char tkt->length length of following ticket + * + * data tkt->dat ticket for service + * + * 4 bytes kdc_time KDC's timestamp + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +create_ciph(c, session, service, instance, realm, life, kvno, tkt, + kdc_time, key) + KTEXT c; /* Text block to hold ciphertext */ + C_Block session; /* Session key to send to user */ + char *service; /* Service name on ticket */ + char *instance; /* Instance name on ticket */ + char *realm; /* Realm of this KDC */ + unsigned long life; /* Lifetime of the ticket */ + int kvno; /* Key version number for service */ + KTEXT tkt; /* The ticket for the service */ + unsigned long kdc_time; /* KDC time */ + C_Block key; /* Key to encrypt ciphertext with */ +{ + char *ptr; + Key_schedule key_s; + + ptr = (char *) c->dat; + + bcopy((char *) session, ptr, 8); + ptr += 8; + + (void) strcpy(ptr,service); + ptr += strlen(service) + 1; + + (void) strcpy(ptr,instance); + ptr += strlen(instance) + 1; + + (void) strcpy(ptr,realm); + ptr += strlen(realm) + 1; + + *(ptr++) = (unsigned char) life; + *(ptr++) = (unsigned char) kvno; + *(ptr++) = (unsigned char) tkt->length; + + bcopy((char *)(tkt->dat),ptr,tkt->length); + ptr += tkt->length; + + bcopy((char *) &kdc_time,ptr,4); + ptr += 4; + + /* guarantee null padded encrypted data to multiple of 8 bytes */ + bzero(ptr, 7); + + c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8; + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s, + key,ENCRYPT); +#endif /* NOENCRYPTION */ + + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/create_death_packet.c b/eBones/lib/libkrb/create_death_packet.c new file mode 100644 index 0000000..f747d6b --- /dev/null +++ b/eBones/lib/libkrb/create_death_packet.c @@ -0,0 +1,63 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $ + * $Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine creates a packet to type AUTH_MSG_DIE which is sent to + * the Kerberos server to make it shut down. It is used only in the + * development environment. + * + * It takes a string "a_name" which is sent in the packet. A pointer + * to the packet is returned. + * + * The format of the killer packet is: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_DIE message type + * + * [least significant HOST_BYTE_ORDER byte order of sender + * bit of above field] + * + * string a_name presumably, name of + * principal sending killer + * packet + */ + +#ifdef DEBUG +KTEXT +krb_create_death_packet(a_name) + char *a_name; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + + unsigned char *v = pkt->dat; + unsigned char *t = (pkt->dat+1); + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_DIE; + *t |= HOST_BYTE_ORDER; + (void) strcpy((char *) (pkt->dat+2),a_name); + pkt->length = 3 + strlen(a_name); + return pkt; +} +#endif /* DEBUG */ diff --git a/eBones/lib/libkrb/create_ticket.c b/eBones/lib/libkrb/create_ticket.c new file mode 100644 index 0000000..984d8e9 --- /dev/null +++ b/eBones/lib/libkrb/create_ticket.c @@ -0,0 +1,130 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $ + * $Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * Create ticket takes as arguments information that should be in a + * ticket, and the KTEXT object in which the ticket should be + * constructed. It then constructs a ticket and returns, leaving the + * newly created ticket in tkt. + * The length of the ticket is a multiple of + * eight bytes and is in tkt->length. + * + * If the ticket is too long, the ticket will contain nulls. + * The return value of the routine is undefined. + * + * The corresponding routine to extract information from a ticket it + * decomp_ticket. When changes are made to this routine, the + * corresponding changes should also be made to that file. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * tkt->length length of ticket (multiple of 8 bytes) + * + * tkt->dat: + * + * unsigned char flags namely, HOST_BYTE_ORDER + * + * string pname client's name + * + * string pinstance client's instance + * + * string prealm client's realm + * + * 4 bytes paddress client's address + * + * 8 bytes session session key + * + * 1 byte life ticket lifetime + * + * 4 bytes time_sec KDC timestamp + * + * string sname service's name + * + * string sinstance service's instance + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + C_Block key; /* Service's secret key */ +{ + Key_schedule key_s; + register char *data; /* running index into ticket */ + + tkt->length = 0; /* Clear previous data */ + flags |= HOST_BYTE_ORDER; /* ticket byte order */ + bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags)); + data = ((char *)tkt->dat) + sizeof(flags); + (void) strcpy(data, pname); + data += 1 + strlen(pname); + (void) strcpy(data, pinstance); + data += 1 + strlen(pinstance); + (void) strcpy(data, prealm); + data += 1 + strlen(prealm); + bcopy((char *) &paddress, data, 4); + data += 4; + + bcopy((char *) session, data, 8); + data += 8; + *(data++) = (char) life; + /* issue time */ + bcopy((char *) &time_sec, data, 4); + data += 4; + (void) strcpy(data, sname); + data += 1 + strlen(sname); + (void) strcpy(data, sinstance); + data += 1 + strlen(sinstance); + + /* guarantee null padded ticket to multiple of 8 bytes */ + bzero(data, 7); + tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8; + + /* Check length of ticket */ + if (tkt->length > (sizeof(KTEXT_ST) - 7)) { + bzero(tkt->dat, tkt->length); + tkt->length = 0; + return KFAILURE /* XXX */; + } + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length, + key_s,key,ENCRYPT); +#endif + return 0; +} diff --git a/eBones/lib/libkrb/debug_decl.c b/eBones/lib/libkrb/debug_decl.c new file mode 100644 index 0000000..1a0f6df --- /dev/null +++ b/eBones/lib/libkrb/debug_decl.c @@ -0,0 +1,18 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $ + * $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $"; +#endif lint + +/* Declare global debugging variables. */ + +int krb_ap_req_debug = 0; +int krb_debug = 0; diff --git a/eBones/lib/libkrb/decomp_ticket.c b/eBones/lib/libkrb/decomp_ticket.c new file mode 100644 index 0000000..181864c --- /dev/null +++ b/eBones/lib/libkrb/decomp_ticket.c @@ -0,0 +1,123 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $ + * $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine takes a ticket and pointers to the variables that + * should be filled in based on the information in the ticket. It + * fills in values for its arguments. + * + * Note: if the client realm field in the ticket is the null string, + * then the "prealm" variable is filled in with the local realm (as + * defined by KRB_REALM). + * + * If the ticket byte order is different than the host's byte order + * (as indicated by the byte order bit of the "flags" field), then + * the KDC timestamp "time_sec" is byte-swapped. The other fields + * potentially affected by byte order, "paddress" and "session" are + * not byte-swapped. + * + * The routine returns KFAILURE if any of the "pname", "pinstance", + * or "prealm" fields is too big, otherwise it returns KSUCCESS. + * + * The corresponding routine to generate tickets is create_ticket. + * When changes are made to this routine, the corresponding changes + * should also be made to that file. + * + * See create_ticket.c for the format of the ticket packet. + */ + +decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned long *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned long *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + C_Block key; /* Service's secret key + * (to decrypt the ticket) */ + Key_schedule key_s; /* The precomputed key schedule */ +{ + static int tkt_swap_bytes; + unsigned char *uptr; + char *ptr = (char *)tkt->dat; + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length, + key_s,key,DECRYPT); +#endif /* ! NOENCRYPTION */ + + *flags = *ptr; /* get flags byte */ + ptr += sizeof(*flags); + tkt_swap_bytes = 0; + if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1)) + tkt_swap_bytes++; + + if (strlen(ptr) > ANAME_SZ) + return(KFAILURE); + (void) strcpy(pname,ptr); /* pname */ + ptr += strlen(pname) + 1; + + if (strlen(ptr) > INST_SZ) + return(KFAILURE); + (void) strcpy(pinstance,ptr); /* instance */ + ptr += strlen(pinstance) + 1; + + if (strlen(ptr) > REALM_SZ) + return(KFAILURE); + (void) strcpy(prealm,ptr); /* realm */ + ptr += strlen(prealm) + 1; + /* temporary hack until realms are dealt with properly */ + if (*prealm == 0) + (void) strcpy(prealm,KRB_REALM); + + bcopy(ptr,(char *)paddress,4); /* net address */ + ptr += 4; + + bcopy(ptr,(char *)session,8); /* session key */ + ptr+= 8; +#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */ + if (tkt_swap_bytes) + swap_C_Block(session); +#endif + + /* get lifetime, being certain we don't get negative lifetimes */ + uptr = (unsigned char *) ptr++; + *life = (int) *uptr; + + bcopy(ptr,(char *) time_sec,4); /* issue time */ + ptr += 4; + if (tkt_swap_bytes) + swap_u_long(*time_sec); + + (void) strcpy(sname,ptr); /* service name */ + ptr += 1 + strlen(sname); + + (void) strcpy(sinstance,ptr); /* instance */ + ptr += 1 + strlen(sinstance); + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/des_rw.c b/eBones/lib/libkrb/des_rw.c new file mode 100644 index 0000000..c958355 --- /dev/null +++ b/eBones/lib/libkrb/des_rw.c @@ -0,0 +1,265 @@ +/* - + * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University + * All rights reserved. + * + * This code is derived from a specification based on software + * which forms part of the 4.4BSD-Lite distribution, which was developed + * by the University of California and its contributors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the entire comment, + * including the above copyright notice, this list of conditions + * and the following disclaimer, verbatim, at the beginning of + * the source file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Geoffrey M. Rehmet + * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $ + */ + +/* + * + * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED. + * + */ + +/* + * Routines for reading and writing DES encrypted messages onto sockets. + * (These routines will fail if non-blocking I/O is used.) + * + * When a message is written, its length is first transmitted as an int, + * in network byte order. The encrypted message is then transmitted, + * to a multiple of 8 bytes. Messages shorter than 8 bytes are right + * justified into a buffer of length 8 bytes, and the remainder of the + * buffer is filled with random garbage (before encryption): + * + * DDD -------->--+--------+ + * | | + * +--+--+--+--+--+--+--+--+ + * |x |x |x |x |x |D |D |D | + * +--+--+--+--+--+--+--+--+ + * | garbage | data | + * | | + * +-----------------------+----> des_pcbc_encrypt() --> + * + * (Note that the length field sent before the actual message specifies + * the number of data bytes, not the length of the entire padded message. + * + * When data is read, if the message received is longer than the number + * of bytes requested, then the remaining bytes are stored until the + * following call to des_read(). If the number of bytes received is + * less then the number of bytes received, then only the number of bytes + * actually received is returned. + * + * This interface corresponds with the original des_rw.c, except for the + * bugs in des_read() in the original 4.4BSD version. (One bug is + * normally not visible, due to undocumented behaviour of + * des_pcbc_encrypt() in the original MIT libdes.) + * + * XXX Todo: + * 1) Give better error returns on writes + * 2) Improve error checking on reads + * 3) Get rid of need for extern decl. of krb_net_read() + * 4) Tidy garbage generation a bit + * 5) Make the above comment more readable + */ + +#ifdef CRYPT +#ifdef KERBEROS + +#ifndef BUFFER_LEN +#define BUFFER_LEN 10240 +#endif + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/param.h> +#include <sys/types.h> + +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +extern int krb_net_read(int fd, void * data, size_t length); +extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output, + register long length, + des_key_schedule schedule, + des_cblock *ivec, + int encrypt); + +static bit_64 des_key; +static des_key_schedule key_sched; + +/* + * Buffer for storing extra data when more data is received, then was + * actually requested in des_read(). + */ +static u_char des_buff[BUFFER_LEN]; +static u_char buffer[BUFFER_LEN]; +static unsigned stored = 0; +static u_char *buff_ptr = buffer; + +/* + * Set the encryption key for des_read() and des_write(). + * inkey is the initial vector for the DES encryption, while insched is + * the DES key, in unwrapped form. + */ +void des_set_key(inkey, insched) + bit_64 *inkey; + u_char *insched; +{ + bcopy(inkey, &des_key, sizeof(bit_64)); + bcopy(insched, &key_sched, sizeof(des_key_schedule)); +} + +/* + * Clear the key schedule, and initial vector, which were previously + * stored in static vars by des_set_key(). + */ +void des_clear_key() +{ + bzero(&des_key, sizeof(des_cblock)); + bzero(&key_sched, sizeof(des_key_schedule)); +} + +int des_read(fd, buf, len) + int fd; + register char * buf; + int len; +{ + int msg_length; /* length of actual message data */ + int pad_length; /* length of padded message */ + int nread; /* number of bytes actually read */ + int nreturned = 0; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + return(len); + } else { + if (stored) { + bcopy(buff_ptr, buf, stored); + nreturned = stored; + len -= stored; + stored = 0; + buff_ptr = buffer; + } else { + nreturned = 0; + buff_ptr = buffer; + } + } + + nread = krb_net_read(fd, &msg_length, sizeof(msg_length)); + if(nread != (int)(sizeof(msg_length))) + return(0); + + msg_length = ntohl(msg_length); + pad_length = roundup(msg_length, 8); + + nread = krb_net_read(fd, des_buff, pad_length); + if(nread != pad_length) + return(0); + + des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr, + (msg_length < 8 ? 8 : msg_length), + key_sched, (des_cblock*) &des_key, DES_DECRYPT); + + + if(msg_length < 8) + buff_ptr += (8 - msg_length); + stored = msg_length; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + nreturned += len; + } else { + bcopy(buff_ptr, buf, stored); + nreturned += stored; + stored = 0; + } + + return(nreturned); +} + + +/* + * Write a message onto a file descriptor (generally a socket), using + * DES to encrypt the message. + */ +int des_write(fd, buf, len) + int fd; + char * buf; + int len; +{ + static int seeded = 0; + char garbage[8]; + long rnd; + int pad_len; + int write_len; + int nwritten = 0; + int i; + char *data; + + if(len < 8) { + /* + * Right justify the message in 8 bytes of random garbage. + */ + if(!seeded) { + seeded = 1; + srandom((unsigned)time(NULL)); + } + + for(i = 0 ; i < 8 ; i+= sizeof(long)) { + rnd = random(); + bcopy(&rnd, garbage+i, + (i <= (8 - sizeof(long)))?sizeof(long):(8-i)); + } + bcopy(buf, garbage + 8 - len, len); + data = garbage; + pad_len = 8; + } else { + data = buf; + pad_len = roundup(len, 8); + } + + des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff, + (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT); + + + write_len = htonl(len); + if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len)) + return(-1); + if(write(fd, des_buff, pad_len) != pad_len) + return(-1); + + return(len); +} + +#endif /* KERBEROS */ +#endif /* CRYPT */ diff --git a/eBones/lib/libkrb/dest_tkt.c b/eBones/lib/libkrb/dest_tkt.c new file mode 100644 index 0000000..17c7855 --- /dev/null +++ b/eBones/lib/libkrb/dest_tkt.c @@ -0,0 +1,87 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $ + * $Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif +#include <errno.h> + +/* + * dest_tkt() is used to destroy the ticket store upon logout. + * If the ticket file does not exist, dest_tkt() returns RET_TKFIL. + * Otherwise the function returns RET_OK on success, KFAILURE on + * failure. + * + * The ticket file (TKT_FILE) is defined in "krb.h". + */ + +dest_tkt() +{ + char *file = TKT_FILE; + int i,fd; + extern int errno; + struct stat statb; + char buf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; +#endif /* TKT_SHMEM */ + + errno = 0; + if (lstat(file,&statb) < 0) + goto out; + + if (!(statb.st_mode & S_IFREG) +#ifdef notdef + || statb.st_mode & 077 +#endif + ) + goto out; + + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; + + bzero(buf, BUFSIZ); + + for (i = 0; i < statb.st_size; i += BUFSIZ) + if (write(fd, buf, BUFSIZ) != BUFSIZ) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + + (void) unlink(file); + +out: + if (errno == ENOENT) return RET_TKFIL; + else if (errno != 0) return KFAILURE; +#ifdef TKT_SHMEM + /* + * handle the shared memory case + */ + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + if ((i = krb_shm_dest(shmidname)) != KSUCCESS) + return(i); +#endif /* TKT_SHMEM */ + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/extract_ticket.c b/eBones/lib/libkrb/extract_ticket.c new file mode 100644 index 0000000..571d5da --- /dev/null +++ b/eBones/lib/libkrb/extract_ticket.c @@ -0,0 +1,58 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $ + * $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine is obsolete. + * + * This routine accepts the ciphertext returned by kerberos and + * extracts the nth ticket. It also fills in the variables passed as + * session, liftime and kvno. + */ + +extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket) + KTEXT cipher; /* The ciphertext */ + int n; /* Which ticket */ + char *session; /* The session key for this tkt */ + int *lifetime; /* The life of this ticket */ + int *kvno; /* The kvno for the service */ + char *realm; /* Realm in which tkt issued */ + KTEXT ticket; /* The ticket itself */ +{ + char *ptr; + int i; + + /* Start after the ticket lengths */ + ptr = (char *) cipher->dat; + ptr = ptr + 1 + (int) *(cipher->dat); + + /* Step through earlier tickets */ + for (i = 1; i < n; i++) + ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i); + bcopy(ptr, (char *) session, 8); /* Save the session key */ + ptr += 8; + *lifetime = *(ptr++); /* Save the life of the ticket */ + *kvno = *(ptr++); /* Save the kvno */ + (void) strcpy(realm,ptr); /* instance */ + ptr += strlen(realm) + 1; + + /* Save the ticket if its length is non zero */ + ticket->length = *(cipher->dat+n); + if (ticket->length) + bcopy(ptr, (char *) (ticket->dat), ticket->length); +} diff --git a/eBones/lib/libkrb/fgetst.c b/eBones/lib/libkrb/fgetst.c new file mode 100644 index 0000000..d938013 --- /dev/null +++ b/eBones/lib/libkrb/fgetst.c @@ -0,0 +1,39 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $ + * $Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> + +/* + * fgetst takes a file descriptor, a character pointer, and a count. + * It reads from the file it has either read "count" characters, or + * until it reads a null byte. When finished, what has been read exists + * in "s". If "count" characters were actually read, the last is changed + * to a null, so the returned string is always null-terminated. fgetst + * returns the number of characters read, including the null terminator. + */ + +fgetst(f, s, n) + FILE *f; + register char *s; + int n; +{ + register count = n; + int ch; /* NOT char; otherwise you don't see EOF */ + + while ((ch = getc(f)) != EOF && ch && --count) { + *s++ = ch; + } + *s = '\0'; + return (n - count); +} diff --git a/eBones/lib/libkrb/get_ad_tkt.c b/eBones/lib/libkrb/get_ad_tkt.c new file mode 100644 index 0000000..d8e1283 --- /dev/null +++ b/eBones/lib/libkrb/get_ad_tkt.c @@ -0,0 +1,234 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $ + * $Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <prot.h> +#include <strings.h> + +#include <stdio.h> +#include <errno.h> + +/* use the bsd time.h struct defs for PC too! */ +#include <sys/time.h> +#include <sys/types.h> + +extern int krb_debug; + +struct timeval tt_local = { 0, 0 }; + +int swap_bytes; +unsigned long rep_err_code; + +/* + * get_ad_tkt obtains a new service ticket from Kerberos, using + * the ticket-granting ticket which must be in the ticket file. + * It is typically called by krb_mk_req() when the client side + * of an application is creating authentication information to be + * sent to the server side. + * + * get_ad_tkt takes four arguments: three pointers to strings which + * contain the name, instance, and realm of the service for which the + * ticket is to be obtained; and an integer indicating the desired + * lifetime of the ticket. + * + * It returns an error status if the ticket couldn't be obtained, + * or AD_OK if all went well. The ticket is stored in the ticket + * cache. + * + * The request sent to the Kerberos ticket-granting service looks + * like this: + * + * pkt->dat + * + * TEXT original contents of authenticator+ticket + * pkt->dat built in krb_mk_req call + * + * 4 bytes time_ws always 0 (?) + * char lifetime lifetime argument passed + * string service service name argument + * string sinstance service instance arg. + * + * See "prot.h" for the reply packet layout and definitions of the + * extraction macros like pkt_version(), pkt_msg_type(), etc. + */ + +get_ad_tkt(service,sinstance,realm,lifetime) + char *service; + char *sinstance; + char *realm; + int lifetime; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = & pkt_st; /* Packet to KDC */ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + static KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + static KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + C_Block ses; /* Session key for tkt */ + CREDENTIALS cr; + int kvno; /* Kvno for session key */ + char lrealm[REALM_SZ]; + C_Block key; /* Key for decrypting cipher */ + Key_schedule key_s; + long time_ws = 0; + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + int msg_byte_order; + int kerror; + char rlm[REALM_SZ]; + char *ptr; + + unsigned long kdc_time; /* KDC time */ + + if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS) + return(kerror); + + /* Create skeleton of packet to be sent */ + (void) gettimeofday(&tt_local,(struct timezone *) 0); + + pkt->length = 0; + + /* + * Look for the session key (and other stuff we don't need) + * in the ticket file for krbtgt.realm@lrealm where "realm" + * is the service's realm (passed in "realm" argument) and + * lrealm is the realm of our initial ticket. If we don't + * have this, we will try to get it. + */ + + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) { + /* + * If realm == lrealm, we have no hope, so let's not even try. + */ + if ((strncmp(realm, lrealm, REALM_SZ)) == 0) + return(AD_NOTGT); + else{ + if ((kerror = + get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS) + return(kerror); + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) + return(kerror); + } + } + + /* + * Make up a request packet to the "krbtgt.realm@lrealm". + * Start by calling krb_mk_req() which puts ticket+authenticator + * into "pkt". Then tack other stuff on the end. + */ + + kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L); + + if (kerror) + return(AD_NOTGT); + + /* timestamp */ + bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (char) lifetime; + (void) strcpy((char *) (pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* Send the request to the local ticket-granting server */ + if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION ) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) + swap_bytes++; + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4); + if (swap_bytes) + swap_u_long(rep_err_code); + return(rep_err_code); + + default: + return(INTK_PROT); + } + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length); + +#ifndef NOENCRYPTION + key_sched(cr.session,key_s); + pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length, + key_s,cr.session,DECRYPT); +#endif + /* Get rid of all traces of key */ + bzero((char *) cr.session, sizeof(key)); + bzero((char *) key_s, sizeof(key_s)); + + ptr = (char *) cip->dat; + + bcopy(ptr,(char *)ses,8); + ptr += 8; + + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + lifetime = (unsigned long) ptr[0]; + kvno = (unsigned long) ptr[1]; + tkt->length = (int) ptr[2]; + ptr += 3; + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&tt_local,(struct timezone *) 0); + if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime, + kvno,tkt,tt_local.tv_sec)) + return(kerror); + + return(AD_OK); +} diff --git a/eBones/lib/libkrb/get_admhst.c b/eBones/lib/libkrb/get_admhst.c new file mode 100644 index 0000000..c36e997 --- /dev/null +++ b/eBones/lib/libkrb/get_admhst.c @@ -0,0 +1,79 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $ + * $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <string.h> + +/* + * Given a Kerberos realm, find a host on which the Kerberos database + * administration server can be found. + * + * krb_get_admhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer n, and + * returns (in h) the nth administrative host entry from the configuration + * file (KRB_CONF, defined in "krb.h") associated with the specified realm. + * + * On error, get_admhst returns KFAILURE. If all goes well, the routine + * returns KSUCCESS. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + * + * This is a temporary hack to allow us to find the nearest system running + * a Kerberos admin server. In the long run, this functionality will be + * provided by a nameserver. + */ + +krb_get_admhst(h, r, n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + char scratch[64]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + return(KFAILURE); + } + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + /* error reading */ + (void) fclose(cnffile); + return(KFAILURE); + } + if (!index(linebuf, '\n')) { + /* didn't all fit into buffer, punt */ + (void) fclose(cnffile); + return(KFAILURE); + } + for (i = 0; i < n; ) { + /* run through the file, looking for admin host */ + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + /* need to scan for a token after 'admin' to make sure that + admin matched correctly */ + if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/get_cred.c b/eBones/lib/libkrb/get_cred.c new file mode 100644 index 0000000..baf7ae2 --- /dev/null +++ b/eBones/lib/libkrb/get_cred.c @@ -0,0 +1,60 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $ + * $Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> + +/* + * krb_get_cred takes a service name, instance, and realm, and a + * structure of type CREDENTIALS to be filled in with ticket + * information. It then searches the ticket file for the appropriate + * ticket and fills in the structure with the corresponding + * information from the file. If successful, it returns KSUCCESS. + * On failure it returns a Kerberos error code. + */ + +krb_get_cred(service,instance,realm,c) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + CREDENTIALS *c; /* Credentials struct */ +{ + int tf_status; /* return value of tf function calls */ + + /* Open ticket file and lock it for shared reading */ + if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Copy principal's name and instance into the CREDENTIALS struc c */ + + if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS || + (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS ) + return (tf_status); + + /* Search for requested service credentials and copy into c */ + + while ((tf_status = tf_get_cred(c)) == KSUCCESS) { + /* Is this the right ticket? */ + if ((strcmp(c->service,service) == 0) && + (strcmp(c->instance,instance) == 0) && + (strcmp(c->realm,realm) == 0)) + break; + } + (void) tf_close(); + + if (tf_status == EOF) + return (GC_NOTKT); + return(tf_status); +} diff --git a/eBones/lib/libkrb/get_in_tkt.c b/eBones/lib/libkrb/get_in_tkt.c new file mode 100644 index 0000000..5fb1560 --- /dev/null +++ b/eBones/lib/libkrb/get_in_tkt.c @@ -0,0 +1,288 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $ + * $Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#ifndef NULL +#define NULL 0 +#endif + +/* + * This file contains two routines: passwd_to_key() converts + * a password into a DES key (prompting for the password if + * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for + * a user. + */ + +/* + * passwd_to_key(): given a password, return a DES key. + * There are extra arguments here which (used to be?) + * used by srvtab_to_key(). + * + * If the "passwd" argument is not null, generate a DES + * key from it, using string_to_key(). + * + * If the "passwd" argument is null, call des_read_password() + * to prompt for a password and then convert it into a DES key. + * + * In either case, the resulting key is put in the "key" argument, + * and 0 is returned. + */ + +/*ARGSUSED */ +static int passwd_to_key(user,instance,realm,passwd,key) + char *user, *instance, *realm, *passwd; + C_Block key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else + if (passwd) + string_to_key(passwd,key); + else + des_read_password(key,"Password: ",0); +#endif + return (0); +} + +/* + * krb_get_pw_in_tkt() takes the name of the server for which the initial + * ticket is to be obtained, the name of the principal the ticket is + * for, the desired lifetime of the ticket, and the user's password. + * It passes its arguments on to krb_get_in_tkt(), which contacts + * Kerberos to get the ticket, decrypts it using the password provided, + * and stores it away for future use. + * + * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt(): + * the name of a routine (passwd_to_key()) to be used to get the + * password in case the "password" argument is null and NULL for the + * decryption procedure indicating that krb_get_in_tkt should use the + * default method of decrypting the response from the KDC. + * + * The result of the call to krb_get_in_tkt() is returned. + */ + +krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *password; +{ + return(krb_get_in_tkt(user,instance,realm,service,sinstance,life, + passwd_to_key, NULL, password)); +} + +#ifdef NOENCRYPTION +/* + * $Source: /home/CVS/src/eBones/krb/get_in_tkt.c,v $ + * $Author: g89r4222 $ + * + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * This routine prints the supplied string to standard + * output as a prompt, and reads a password string without + * echoing. + */ + +#ifndef lint +static char rcsid_read_password_c[] = +"Bones$Header: /home/CVS/src/eBones/krb/get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $"; +#endif lint + +#include <des.h> +#include "conf.h" + +#include <stdio.h> +#ifdef BSDUNIX +#include <strings.h> +#include <sys/ioctl.h> +#include <signal.h> +#include <setjmp.h> +#else +char *strcpy(); +int strcmp(); +#endif + +#ifdef BSDUNIX +static jmp_buf env; +#endif + +#ifdef BSDUNIX +static void sig_restore(); +static push_signals(), pop_signals(); +int placebo_read_pw_string(); +#endif + +/*** Routines ****************************************************** */ +int +placebo_read_password(k,prompt,verify) + des_cblock *k; + char *prompt; + int verify; +{ + int ok; + char key_string[BUFSIZ]; + +#ifdef BSDUNIX + if (setjmp(env)) { + ok = -1; + goto lose; + } +#endif + + ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify); + if (ok == 0) + bzero(k, sizeof(C_Block)); + +lose: + bzero(key_string, sizeof (key_string)); + return ok; +} + +/* + * This version just returns the string, doesn't map to key. + * + * Returns 0 on success, non-zero on failure. + */ + +int +placebo_read_pw_string(s,max,prompt,verify) + char *s; + int max; + char *prompt; + int verify; +{ + int ok = 0; + char *ptr; + +#ifdef BSDUNIX + jmp_buf old_env; + struct sgttyb tty_state; +#endif + char key_string[BUFSIZ]; + + if (max > BUFSIZ) { + return -1; + } + +#ifdef BSDUNIX + bcopy(old_env, env, sizeof(env)); + if (setjmp(env)) + goto lose; + + /* save terminal state*/ + if (ioctl(0,TIOCGETP,&tty_state) == -1) + return -1; + + push_signals(); + /* Turn off echo */ + tty_state.sg_flags &= ~ECHO; + if (ioctl(0,TIOCSETP,&tty_state) == -1) + return -1; +#endif + while (!ok) { + printf(prompt); + fflush(stdout); +#ifdef CROSSMSDOS + h19line(s,sizeof(s),0); + if (!strlen(s)) + continue; +#else + if (!fgets(s, max, stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(s, '\n'))) + *ptr = '\0'; +#endif + if (verify) { + printf("\nVerifying, please re-enter %s",prompt); + fflush(stdout); +#ifdef CROSSMSDOS + h19line(key_string,sizeof(key_string),0); + if (!strlen(key_string)) + continue; +#else + if (!fgets(key_string, sizeof(key_string), stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(key_string, '\n'))) + *ptr = '\0'; +#endif + if (strcmp(s,key_string)) { + printf("\n\07\07Mismatch - try again\n"); + fflush(stdout); + continue; + } + } + ok = 1; + } + +#ifdef BSDUNIX +lose: + if (!ok) + bzero(s, max); + printf("\n"); + /* turn echo back on */ + tty_state.sg_flags |= ECHO; + if (ioctl(0,TIOCSETP,&tty_state)) + ok = 0; + pop_signals(); + bcopy(env, old_env, sizeof(env)); +#endif + if (verify) + bzero(key_string, sizeof (key_string)); + s[max-1] = 0; /* force termination */ + return !ok; /* return nonzero if not okay */ +} + +#ifdef BSDUNIX +/* + * this can be static since we should never have more than + * one set saved.... + */ +#ifdef POSIX +static void (*old_sigfunc[NSIG])(); +#else +static int (*old_sigfunc[NSIG])(); +#endif POSIX + +static push_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + old_sigfunc[i] = signal(i,sig_restore); +} + +static pop_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + signal(i,old_sigfunc[i]); +} + +static void sig_restore(sig,code,scp) + int sig,code; + struct sigcontext *scp; +{ + longjmp(env,1); +} +#endif +#endif /* NOENCRYPTION */ diff --git a/eBones/lib/libkrb/get_krbhst.c b/eBones/lib/libkrb/get_krbhst.c new file mode 100644 index 0000000..16c4ff2 --- /dev/null +++ b/eBones/lib/libkrb/get_krbhst.c @@ -0,0 +1,84 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $ + * $Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* + * Given a Kerberos realm, find a host on which the Kerberos authenti- + * cation server can be found. + * + * krb_get_krbhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer, n, and + * returns (in h) the nth entry from the configuration file (KRB_CONF, + * defined in "krb.h") associated with the specified realm. + * + * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the + * configuration file does not exist, krb_get_krbhst will return KRB_HOST + * (also defined in "krb.h"). If all goes well, the routine returnes + * KSUCCESS. + * + * The KRB_CONF file contains the name of the local realm in the first + * line (not used by this routine), followed by lines indicating realm/host + * entries. The words "admin server" following the hostname indicate that + * the host provides an administrative database server. + * + * For example: + * + * ATHENA.MIT.EDU + * ATHENA.MIT.EDU kerberos-1.mit.edu admin server + * ATHENA.MIT.EDU kerberos-2.mit.edu + * LCS.MIT.EDU kerberos.lcs.mit.edu admin server + * + * This is a temporary hack to allow us to find the nearest system running + * kerberos. In the long run, this functionality will be provided by a + * nameserver. + */ + +krb_get_krbhst(h,r,n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + if (n==1) { + (void) strcpy(h,KRB_HOST); + return(KSUCCESS); + } + else + return(KFAILURE); + } + if (fscanf(cnffile,"%s",tr) == EOF) + return(KFAILURE); + /* run through the file, looking for the nth server for this realm */ + for (i = 1; i <= n;) { + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + if (sscanf(linebuf, "%s %s", tr, h) != 2) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/get_krbrlm.c b/eBones/lib/libkrb/get_krbrlm.c new file mode 100644 index 0000000..7df073d --- /dev/null +++ b/eBones/lib/libkrb/get_krbrlm.c @@ -0,0 +1,59 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $ + * $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* + * krb_get_lrealm takes a pointer to a string, and a number, n. It fills + * in the string, r, with the name of the nth realm specified on the + * first line of the kerberos config file (KRB_CONF, defined in "krb.h"). + * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the + * config file does not exist, and if n=1, a successful return will occur + * with r = KRB_REALM (also defined in "krb.h"). + * + * NOTE: for archaic & compatibility reasons, this routine will only return + * valid results when n = 1. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + */ + +krb_get_lrealm(r,n) + char *r; + int n; +{ + FILE *cnffile, *fopen(); + + if (n > 1) + return(KFAILURE); /* Temporary restriction */ + + if ((cnffile = fopen(KRB_CONF, "r")) == NULL) { + if (n == 1) { + (void) strcpy(r, KRB_REALM); + return(KSUCCESS); + } + else + return(KFAILURE); + } + + if (fscanf(cnffile,"%s",r) != 1) { + (void) fclose(cnffile); + return(KFAILURE); + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/get_phost.c b/eBones/lib/libkrb/get_phost.c new file mode 100644 index 0000000..9b12d10 --- /dev/null +++ b/eBones/lib/libkrb/get_phost.c @@ -0,0 +1,53 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $ + * $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <ctype.h> +#include <netdb.h> + +char *index(); + +/* + * This routine takes an alias for a host name and returns the first + * field, lower case, of its domain name. For example, if "menel" is + * an alias for host officially named "menelaus" (in /etc/hosts), for + * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus" + * is returned. + * + * This is done for historical Athena reasons: the Kerberos name of + * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm" + * where "host"is the lowercase for of the host name ("menelaus"). + * This should go away: the instance should be the domain name + * (MENELAUS.MIT.EDU). But for now we need this routine... + * + * A pointer to the name is returned, if found, otherwise a pointer + * to the original "alias" argument is returned. + */ + +char * krb_get_phost(alias) + char *alias; +{ + struct hostent *h; + char *phost = alias; + if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) { + char *p = index( h->h_name, '.' ); + if (p) + *p = NULL; + p = phost = h->h_name; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/eBones/lib/libkrb/get_pw_tkt.c b/eBones/lib/libkrb/get_pw_tkt.c new file mode 100644 index 0000000..48a003c --- /dev/null +++ b/eBones/lib/libkrb/get_pw_tkt.c @@ -0,0 +1,72 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $ + * $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $"; +#endif /* lint */ + + +#include <krb.h> + +/* + * Get a ticket for the password-changing server ("changepw.KRB_MASTER"). + * + * Given the name, instance, realm, and current password of the + * principal for which the user wants a password-changing-ticket, + * return either: + * + * GT_PW_BADPW if current password was wrong, + * GT_PW_NULL if principal had a NULL password, + * or the result of the krb_get_pw_in_tkt() call. + * + * First, try to get a ticket for "user.instance@realm" to use the + * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h"). + * The requested lifetime for the ticket is "1", and the current + * password is the "cpw" argument given. + * + * If the password was bad, give up. + * + * If the principal had a NULL password in the Kerberos database + * (indicating that the principal is known to Kerberos, but hasn't + * got a password yet), try instead to get a ticket for the principal + * "default.changepw@realm" to use the "changepw.KRB_MASTER" server. + * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL + * if all goes well, otherwise the error. + * + * If this routine succeeds, a ticket and session key for either the + * principal "user.instance@realm" or "default.changepw@realm" to use + * the password-changing server will be in the user's ticket file. + */ + +get_pw_tkt(user,instance,realm,cpw) + char *user; + char *instance; + char *realm; + char *cpw; +{ + int kerror; + + kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw", + KRB_MASTER, 1, cpw); + + if (kerror == INTK_BADPW) + return(GT_PW_BADPW); + + if (kerror == KDC_NULL_KEY) { + kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw", + KRB_MASTER,1,"changepwkrb"); + if (kerror) + return(kerror); + return(GT_PW_NULL); + } + + return(kerror); +} diff --git a/eBones/lib/libkrb/get_request.c b/eBones/lib/libkrb/get_request.c new file mode 100644 index 0000000..131ffd5 --- /dev/null +++ b/eBones/lib/libkrb/get_request.c @@ -0,0 +1,52 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $ + * $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +/* + * This procedure is obsolete. It is used in the kerberos_slave + * code for Version 3 tickets. + * + * This procedure sets s_name, and instance to point to + * the corresponding fields from tne nth request in the packet. + * it returns the lifetime requested. Garbage will be returned + * if there are less than n requests in the packet. + */ + +get_request(pkt, n, s_name, instance) + KTEXT pkt; /* The packet itself */ + int n; /* Which request do we want */ + char **s_name; /* Service name to be filled in */ + char **instance; /* Instance name to be filled in */ +{ + /* Go to the beginning of the request list */ + char *ptr = (char *) pkt_a_realm(pkt) + 6 + + strlen((char *)pkt_a_realm(pkt)); + + /* Read requests until we hit the right one */ + while (n-- > 1) { + ptr++; + ptr += 1 + strlen(ptr); + ptr += 1 + strlen(ptr); + } + + /* Set the arguments to point to the right place */ + *s_name = 1 + ptr; + *instance = 2 + ptr + strlen(*s_name); + + /* Return the requested lifetime */ + return((int) *ptr); +} diff --git a/eBones/lib/libkrb/get_svc_in_tkt.c b/eBones/lib/libkrb/get_svc_in_tkt.c new file mode 100644 index 0000000..6d9702f --- /dev/null +++ b/eBones/lib/libkrb/get_svc_in_tkt.c @@ -0,0 +1,73 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $ + * $Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#ifndef NULL +#define NULL 0 +#endif + +/* + * This file contains two routines: srvtab_to_key(), which gets + * a server's key from a srvtab file, and krb_get_svc_in_tkt() which + * gets an initial ticket for a server. + */ + +/* + * srvtab_to_key(): given a "srvtab" file (where the keys for the + * service on a host are stored), return the private key of the + * given service (user.instance@realm). + * + * srvtab_to_key() passes its arguments on to read_service_key(), + * plus one additional argument, the key version number. + * (Currently, the key version number is always 0; this value + * is treated as a wildcard by read_service_key().) + * + * If the "srvtab" argument is null, KEYFILE (defined in "krb.h") + * is passed in its place. + * + * It returns the return value of the read_service_key() call. + * The service key is placed in "key". + */ + +static int srvtab_to_key(user, instance, realm, srvtab, key) + char *user, *instance, *realm, *srvtab; + C_Block key; +{ + if (!srvtab) + srvtab = KEYFILE; + + return(read_service_key(user, instance, realm, 0, srvtab, + (char *)key)); +} + +/* + * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(), + * plus two additional arguments: a pointer to the srvtab_to_key() + * function to be used to get the key from the key file and a NULL + * for the decryption procedure indicating that krb_get_in_tkt should + * use the default method of decrypting the response from the KDC. + * + * It returns the return value of the krb_get_in_tkt() call. + */ + +krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *srvtab; +{ + return(krb_get_in_tkt(user, instance, realm, service, sinstance, + life, srvtab_to_key, NULL, srvtab)); +} diff --git a/eBones/lib/libkrb/get_tf_fullname.c b/eBones/lib/libkrb/get_tf_fullname.c new file mode 100644 index 0000000..753ad1e --- /dev/null +++ b/eBones/lib/libkrb/get_tf_fullname.c @@ -0,0 +1,66 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $ + * $Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> +#include <stdio.h> + +/* + * This file contains a routine to extract the fullname of a user + * from the ticket file. + */ + +/* + * krb_get_tf_fullname() takes four arguments: the name of the + * ticket file, and variables for name, instance, and realm to be + * returned in. Since the realm of a ticket file is not really fully + * supported, the realm used will be that of the the first ticket in + * the file as this is the one that was obtained with a password by + * krb_get_in_tkt(). + */ + +krb_get_tf_fullname(ticket_file, name, instance, realm) + char *ticket_file; + char *name; + char *instance; + char *realm; +{ + int tf_status; + CREDENTIALS c; + + if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) || + ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS)) + return (tf_status); + + if (name) + strcpy(name, c.pname); + if (instance) + strcpy(instance, c.pinst); + if ((tf_status = tf_get_cred(&c)) == KSUCCESS) { + if (realm) + strcpy(realm, c.realm); + } + else { + if (tf_status == EOF) + return(KFAILURE); + else + return(tf_status); + } + (void) tf_close(); + + return(tf_status); +} diff --git a/eBones/lib/libkrb/get_tf_realm.c b/eBones/lib/libkrb/get_tf_realm.c new file mode 100644 index 0000000..f405dcb --- /dev/null +++ b/eBones/lib/libkrb/get_tf_realm.c @@ -0,0 +1,34 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $ + * $Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> + +/* + * This file contains a routine to extract the realm of a kerberos + * ticket file. + */ + +/* + * krb_get_tf_realm() takes two arguments: the name of a ticket + * and a variable to store the name of the realm in. + * + */ + +krb_get_tf_realm(ticket_file, realm) + char *ticket_file; + char *realm; +{ + return(krb_get_tf_fullname(ticket_file, 0, 0, realm)); +} diff --git a/eBones/lib/libkrb/getrealm.c b/eBones/lib/libkrb/getrealm.c new file mode 100644 index 0000000..96e9588 --- /dev/null +++ b/eBones/lib/libkrb/getrealm.c @@ -0,0 +1,104 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * routine to convert hostname into realm name. + * + * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $ + * $Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $"; +#endif lint + +#include <strings.h> +#include <stdio.h> +#include <ctype.h> +#include <krb.h> +#include <sys/param.h> + +/* for Ultrix and friends ... */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +/* + * krb_realmofhost. + * Given a fully-qualified domain-style primary host name, + * return the name of the Kerberos realm for the host. + * If the hostname contains no discernable domain, or an error occurs, + * return the local realm name, as supplied by get_krbrlm(). + * If the hostname contains a domain, but no translation is found, + * the hostname's domain is converted to upper-case and returned. + * + * The format of each line of the translation file is: + * domain_name kerberos_realm + * -or- + * host_name kerberos_realm + * + * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU) + * host names should be in the usual form (e.g. FOO.BAR.BAZ) + */ + +static char ret_realm[REALM_SZ+1]; + +char * +krb_realmofhost(host) +char *host; +{ + char *domain; + FILE *trans_file; + char trans_host[MAXHOSTNAMELEN+1]; + char trans_realm[REALM_SZ+1]; + int retval; + + domain = index(host, '.'); + + /* prepare default */ + if (domain) { + char *cp; + + strncpy(ret_realm, &domain[1], REALM_SZ); + ret_realm[REALM_SZ] = '\0'; + /* Upper-case realm */ + for (cp = ret_realm; *cp; cp++) + if (islower(*cp)) + *cp = toupper(*cp); + } else { + krb_get_lrealm(ret_realm, 1); + } + + if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) { + /* krb_errno = KRB_NO_TRANS */ + return(ret_realm); + } + while (1) { + if ((retval = fscanf(trans_file, "%s %s", + trans_host, trans_realm)) != 2) { + if (retval == EOF) { + fclose(trans_file); + return(ret_realm); + } + continue; /* ignore broken lines */ + } + trans_host[MAXHOSTNAMELEN] = '\0'; + trans_realm[REALM_SZ] = '\0'; + if (!strcasecmp(trans_host, host)) { + /* exact match of hostname, so return the realm */ + (void) strcpy(ret_realm, trans_realm); + fclose(trans_file); + return(ret_realm); + } + if ((trans_host[0] == '.') && domain) { + /* this is a domain match */ + if (!strcasecmp(trans_host, domain)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } + } + } +} diff --git a/eBones/lib/libkrb/getst.c b/eBones/lib/libkrb/getst.c new file mode 100644 index 0000000..edd55ec --- /dev/null +++ b/eBones/lib/libkrb/getst.c @@ -0,0 +1,35 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $ + * $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $"; +#endif /* lint */ + +/* + * getst() takes a file descriptor, a string and a count. It reads + * from the file until either it has read "count" characters, or until + * it reads a null byte. When finished, what has been read exists in + * the given string "s". If "count" characters were actually read, the + * last is changed to a null, so the returned string is always null- + * terminated. getst() returns the number of characters read, including + * the null terminator. + */ + +getst(fd, s, n) + int fd; + register char *s; +{ + register count = n; + while (read(fd, s, 1) > 0 && --count) + if (*s++ == '\0') + return (n - count); + *s = '\0'; + return (n - count); +} diff --git a/eBones/lib/libkrb/in_tkt.c b/eBones/lib/libkrb/in_tkt.c new file mode 100644 index 0000000..53510da --- /dev/null +++ b/eBones/lib/libkrb/in_tkt.c @@ -0,0 +1,142 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $ + * $Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $"; +#endif /* lint */ + +#include <unistd.h> +#include <stdio.h> +#include <krb.h> +#include <sys/file.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef TKT_SHMEM +#include <sys/param.h> +#endif + +extern int krb_debug; + +/* + * in_tkt() is used to initialize the ticket store. It creates the + * file to contain the tickets and writes the given user's name "pname" + * and instance "pinst" in the file. in_tkt() returns KSUCCESS on + * success, or KFAILURE if something goes wrong. + */ + +in_tkt(pname,pinst) + char *pname; + char *pinst; +{ + int tktfile; + uid_t me, metoo; + struct stat buf; + int count; + char *file = TKT_FILE; + int fd; + register int i; + char charbuf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; +#endif /* TKT_SHMEM */ + + me = getuid (); + metoo = geteuid(); + if (lstat(file,&buf) == 0) { + if (buf.st_uid != me && me == 0) { + unlink(file); + } else { + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",file); + return(KFAILURE); + } + /* file already exists, and permissions appear ok, so nuke it */ + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; /* can't zero it, but we can still try truncating it */ + + bzero(charbuf, sizeof(charbuf)); + + for (i = 0; i < buf.st_size; i += sizeof(charbuf)) + if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + } + } + out: + /* arrange so the file is owned by the ruid + (swap real & effective uid if necessary). + This isn't a security problem, since the ticket file, if it already + exists, has the right uid (== ruid) and mode. */ + if (me != metoo) { + if (setreuid(metoo, me) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",metoo,me); + } + if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + if (me != metoo) { + if (setreuid(me, metoo) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid2"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",me,metoo); + } + if (lstat(file,&buf) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + count = strlen(pname)+1; + if (write(tktfile,pname,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + count = strlen(pinst)+1; + if (write(tktfile,pinst,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + (void) close(tktfile); +#ifdef TKT_SHMEM + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + return(krb_shm_create(shmidname)); +#else /* !TKT_SHMEM */ + return(KSUCCESS); +#endif /* TKT_SHMEM */ +} diff --git a/eBones/lib/libkrb/k_gethostname.c b/eBones/lib/libkrb/k_gethostname.c new file mode 100644 index 0000000..e5c11ca --- /dev/null +++ b/eBones/lib/libkrb/k_gethostname.c @@ -0,0 +1,65 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $ + * $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $"; +#endif /* lint */ + +#ifndef PC +#ifndef BSD42 +/* teach me how to k_gethostname for your system here */ +#endif +#endif + +#ifdef PC +#include <stdio.h> +typedef long in_name; +#include "custom.h" /* where is this file? */ +extern get_custom(); +#define LEN 64 /* just a guess */ +#endif /* PC */ + +/* + * Return the local host's name in "name", up to "namelen" characters. + * "name" will be null-terminated if "namelen" is big enough. + * The return code is 0 on success, -1 on failure. (The calling + * interface is identical to gethostname(2).) + * + * Currently defined for BSD 4.2 and PC. The BSD version just calls + * gethostname(); the PC code was taken from "kinit.c", and may or may + * not work. + */ + +k_gethostname(name, namelen) + char *name; +{ +#ifdef BSD42 + return gethostname(name, namelen); +#endif + +#ifdef PC + char buf[LEN]; + char b1, b2, b3, b4; + register char *ptr; + + get_custom(); /* should check for errors, + * return -1 on failure */ + ptr = (char *) &(custom.c_me); + b1 = *ptr++; + b2 = *ptr++; + b3 = *ptr++; + b4 = *ptr; + (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4); + if (strlen(buf) > namelen) + fprintf(stderr, "gethostname: namelen too small; truncating"); + strnpcy(name, buf, namelen); + return 0; +#endif +} diff --git a/eBones/lib/libkrb/klog.c b/eBones/lib/libkrb/klog.c new file mode 100644 index 0000000..b530e8b --- /dev/null +++ b/eBones/lib/libkrb/klog.c @@ -0,0 +1,108 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $ + * $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> + +#include <krb.h> +#include <klog.h> + +static char *log_name = KRBLOG; +static int is_open; +static char logtxt[1000]; + +/* + * This file contains two logging routines: kset_logfile() + * to determine the file to which log entries should be written; + * and klog() to write log entries to the file. + */ + +/* + * klog() is used to add entries to the logfile (see kset_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format" string. + * + * The log file is opened and closed for each log entry. + * + * If the given log type "type" is unknown, or if the log file + * cannot be opened, no entry is made to the log file. + * + * The return value is always a pointer to the formatted log + * text string "logtxt". + */ + +char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0) + int type; + char *format; + int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0; +{ + FILE *logfile, *fopen(); + long time(),now; + char *month_sname(); + struct tm *tm; + static int logtype_array[NLOGTYPE] = {0,0}; + static int array_initialized; + + if (!(array_initialized++)) { + logtype_array[L_NET_ERR] = 1; + logtype_array[L_KRB_PERR] = 1; + logtype_array[L_KRB_PWARN] = 1; + logtype_array[L_APPL_REQ] = 1; + logtype_array[L_INI_REQ] = 1; + logtype_array[L_DEATH_REQ] = 1; + logtype_array[L_NTGT_INTK] = 1; + logtype_array[L_ERR_SEXP] = 1; + logtype_array[L_ERR_MKV] = 1; + logtype_array[L_ERR_NKY] = 1; + logtype_array[L_ERR_NUN] = 1; + logtype_array[L_ERR_UNK] = 1; + } + + (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + + if (!logtype_array[type]) + return(logtxt); + + if ((logfile = fopen(log_name,"a")) == NULL) + return(logtxt); + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,"%s\n",logtxt); + (void) fclose(logfile); + return(logtxt); +} + +/* + * kset_logfile() changes the name of the file to which + * messages are logged. If kset_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +kset_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} diff --git a/eBones/lib/libkrb/kname_parse.c b/eBones/lib/libkrb/kname_parse.c new file mode 100644 index 0000000..dd5fe0b --- /dev/null +++ b/eBones/lib/libkrb/kname_parse.c @@ -0,0 +1,233 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $ + * $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> +#include <strings.h> + +/* max size of full name */ +#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ) + +#define NAME 0 /* which field are we in? */ +#define INST 1 +#define REALM 2 + +extern char *krb_err_txt[]; + +/* + * This file contains four routines for handling Kerberos names. + * + * kname_parse() breaks a Kerberos name into its name, instance, + * and realm components. + * + * k_isname(), k_isinst(), and k_isrealm() check a given string to see if + * it's a syntactically legitimate respective part of a Kerberos name, + * returning 1 if it is, 0 if it isn't. + * + * Definition of "syntactically legitimate" names is according to + * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying + * names", version dated 21 Dec 1987. + * / + +/* + * kname_parse() takes a Kerberos name "fullname" of the form: + * + * username[.instance][@realm] + * + * and returns the three components ("name", "instance", and "realm" + * in the example above) in the given arguments "np", "ip", and "rp". + * + * If successful, it returns KSUCCESS. If there was an error, + * KNAME_FMT is returned. + */ + +kname_parse(np, ip, rp, fullname) + char *np, *ip, *rp, *fullname; +{ + static char buf[FULL_SZ]; + char *rnext, *wnext; /* next char to read, write */ + register char c; + int backslash; + int field; + + backslash = 0; + rnext = buf; + wnext = np; + field = NAME; + + if (strlen(fullname) > FULL_SZ) + return KNAME_FMT; + (void) strcpy(buf, fullname); + + while (c = *rnext++) { + if (backslash) { + *wnext++ = c; + backslash = 0; + continue; + } + switch (c) { + case '\\': + backslash++; + break; + case '.': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *wnext = '\0'; + field = INST; + wnext = ip; + break; + case INST: + return KNAME_FMT; + /* break; */ + case REALM: + *wnext++ = c; + break; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + case '@': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *ip = '\0'; + /* fall through */ + case INST: + *wnext = '\0'; + field = REALM; + wnext = rp; + break; + case REALM: + return KNAME_FMT; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + default: + *wnext++ = c; + } + } + *wnext = '\0'; + if ((strlen(np) > ANAME_SZ - 1) || + (strlen(ip) > INST_SZ - 1) || + (strlen(rp) > REALM_SZ - 1)) + return KNAME_FMT; + return KSUCCESS; +} + +/* + * k_isname() returns 1 if the given name is a syntactically legitimate + * Kerberos name; returns 0 if it's not. + */ + +k_isname(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > ANAME_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + + +/* + * k_isinst() returns 1 if the given name is a syntactically legitimate + * Kerberos instance; returns 0 if it's not. + */ + +k_isinst(s) + char *s; +{ + register char c; + int backslash = 0; + + if (strlen(s) > INST_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + +/* + * k_isrealm() returns 1 if the given name is a syntactically legitimate + * Kerberos realm; returns 0 if it's not. + */ + +k_isrealm(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > REALM_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '@': + return 0; + /* break; */ + } + } + return 1; +} diff --git a/eBones/lib/libkrb/kntoln.c b/eBones/lib/libkrb/kntoln.c new file mode 100644 index 0000000..62ec1b5 --- /dev/null +++ b/eBones/lib/libkrb/kntoln.c @@ -0,0 +1,60 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $ + * $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <strings.h> + +/* + * krb_kntoln converts an auth name into a local name by looking up + * the auth name in the /etc/aname file. The format of the aname + * file is: + * + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | anl | inl | rll | lnl | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | 1by | 1by | 1by | 1by | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * + * If the /etc/aname file can not be opened it will set the + * local name to the auth name. Thus, in this case it performs as + * the identity function. + * + * The name instance and realm are passed to krb_kntoln through + * the AUTH_DAT structure (ad). + * + * Now here's what it *really* does: + * + * Given a Kerberos name in an AUTH_DAT structure, check that the + * instance is null, and that the realm is the same as the local + * realm, and return the principal's name in "lname". Return + * KSUCCESS if all goes well, otherwise KFAILURE. + */ + +krb_kntoln(ad,lname) + AUTH_DAT *ad; + char *lname; +{ + static char lrealm[REALM_SZ] = ""; + + if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE)) + return(KFAILURE); + + if (strcmp(ad->pinst,"")) + return(KFAILURE); + if (strcmp(ad->prealm,lrealm)) + return(KFAILURE); + (void) strcpy(lname,ad->pname); + return(KSUCCESS); +} diff --git a/eBones/lib/libkrb/kparse.c b/eBones/lib/libkrb/kparse.c new file mode 100644 index 0000000..d79f1cf --- /dev/null +++ b/eBones/lib/libkrb/kparse.c @@ -0,0 +1,763 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Purpose: + * This module was developed to parse the "~/.klogin" files for + * Kerberos-authenticated rlogin/rcp/rsh services. However, it is + * general purpose and can be used to parse any such parameter file. + * + * The parameter file should consist of one or more entries, with each + * entry on a separate line and consisting of zero or more + * "keyword=value" combinations. The keyword is case insensitive, but + * the value is not. Any string may be enclosed in quotes, and + * c-style "\" literals are supported. A comma may be used to + * separate the k/v combinations, and multiple commas are ignored. + * Whitespace (blank or tab) may be used freely and is ignored. + * + * Full error processing is available. When PS_BAD_KEYWORD or + * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg + * contains a meaningful error message. + * + * Keywords and their default values are programmed by an external + * table. + * + * Routines: + * fGetParameterSet() parse one line of the parameter file + * fGetKeywordValue() parse one "keyword=value" combo + * fGetToken() parse one token + * + * + * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $ + * $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <ctype.h> +#include <kparse.h> + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define void int + +#define MAXKEY 80 +#define MAXVALUE 80 + +char *malloc(); +char *strcpy(); + +int LineNbr=1; /* current line nbr in parameter file */ +char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX, + * or PS_BAD_KEYWORD is returned by + * fGetKeywordValue or fGetParameterSet */ + +int fGetParameterSet( fp,parm,parmcount ) + FILE *fp; + parmtable parm[]; + int parmcount; +{ + int rc,i; + char keyword[MAXKEY]; + char value[MAXVALUE]; + + while (TRUE) { + rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE); + + switch (rc) { + + case KV_EOF: + return(PS_EOF); + + case KV_EOL: + return(PS_OKAY); + + case KV_SYNTAX: + return(PS_SYNTAX); + + case KV_OKAY: + /* + * got a reasonable keyword/value pair. Search the + * parameter table to see if we recognize the keyword; if + * not, return an error. If we DO recognize it, make sure + * it has not already been given. If not already given, + * save the value. + */ + for (i=0; i<parmcount; i++) { + if (strcmp(strutol(keyword),parm[i].keyword)==0) { + if (parm[i].value) { + sprintf(ErrorMsg,"duplicate keyword \"%s\" found", + keyword); + return(PS_BAD_KEYWORD); + } + parm[i].value = strsave( value ); + break; + } + } + if (i >= parmcount) { + sprintf(ErrorMsg, "unrecognized keyword \"%s\" found", + keyword); + return(PS_BAD_KEYWORD); + } + break; + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + break; + } + } +} + +/* + * Routine: ParmCompare + * + * Purpose: + * ParmCompare checks a specified value for a particular keyword. + * fails if keyword not found or keyword found but the value was + * different. Like strcmp, ParmCompare returns 0 for a match found, -1 + * otherwise + */ +int ParmCompare( parm, parmcount, keyword, value ) + parmtable parm[]; + int parmcount; + char *keyword; + char *value; +{ + int i; + + for (i=0; i<parmcount; i++) { + if (strcmp(parm[i].keyword,keyword)==0) { + if (parm[i].value) { + return(strcmp(parm[i].value,value)); + } else { + return(strcmp(parm[i].defvalue,value)); + } + } + } + return(-1); +} + +void FreeParameterSet(parm,parmcount) + parmtable parm[]; + int parmcount; +{ + int i; + + for (i=0; i<parmcount; i++) { + if (parm[i].value) { + free(parm[i].value); + parm[i].value = (char *)NULL; + } + } +} + +int fGetKeywordValue( fp, keyword, klen, value, vlen ) + FILE *fp; + char *keyword; + int klen; + char *value; + int vlen; +{ + int rc; + int gotit; + + *keyword = *value = '\0'; /* preset strings to NULL */ + + /* + * Looking for a keyword. + * return an exception for EOF or BAD_QSTRING + * ignore leading WHITEspace + * ignore any number of leading commas + * newline means we have all the parms for this + * statement; give an indication that there is + * nothing more on this line. + * stop looking if we find QSTRING, STRING, or NUMBER + * return syntax error for any other PUNKtuation + */ + gotit = FALSE; + do { + rc = fGetToken(fp,keyword,klen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_EOF: + return(KV_EOF); + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg,"unterminated string \"%s found",keyword); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("\n",keyword)==0) { + return(KV_EOL); + } else if (strcmp(",",keyword)!=0) { + sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword); + } + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + gotit = TRUE; + break; + + default: + sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while (!gotit); + + /* + * now we expect an equal sign. + * skip any whitespace + * stop looking if we find an equal sign + * anything else causes a syntax error + */ + gotit = FALSE; + do { + rc = fGetToken(fp,value,vlen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg, + "expecting \'=\', found unterminated string \"%s", + value); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("=",value)==0) { + gotit = TRUE; + } else { + if (strcmp("\n",value)==0) { + sprintf(ErrorMsg,"expecting \"=\", found newline"); + fUngetChar('\n',fp); + } else { + sprintf(ErrorMsg, + "expecting rvalue, found \'%s\'",keyword); + } + return(KV_SYNTAX); + } + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value); + return(KV_SYNTAX); + + case GTOK_EOF: + sprintf(ErrorMsg,"expecting \'=\', found EOF"); + return(KV_SYNTAX); + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while ( !gotit ); + + /* + * got the keyword and equal sign, now get a value. + * ignore any whitespace + * any punctuation is a syntax error + */ + gotit = FALSE; + do { + rc = fGetToken(fp,value,vlen); + + switch (rc) { + + case GTOK_WHITE: + break; + + case GTOK_EOF: + sprintf(ErrorMsg,"expecting rvalue, found EOF"); + return(KV_SYNTAX); + + case GTOK_BAD_QSTRING: + sprintf(ErrorMsg,"unterminated quoted string \"%s",value); + return(KV_SYNTAX); + + case GTOK_PUNK: + if (strcmp("\n",value)==0) { + sprintf(ErrorMsg,"expecting rvalue, found newline"); + fUngetChar('\n',fp); + } else { + sprintf(ErrorMsg, + "expecting rvalue, found \'%s\'",value); + } + return(KV_SYNTAX); + break; + + case GTOK_STRING: + case GTOK_QSTRING: + case GTOK_NUMBER: + gotit = TRUE; + return(KV_OKAY); + + default: + sprintf(ErrorMsg, + "panic: bad return (%d) from fGetToken()",rc); + return(KV_SYNTAX); + } + + } while ( !gotit ); + /*NOTREACHED*/ +} + +/* + * Routine Name: fGetToken + * + * Function: read the next token from the specified file. + * A token is defined as a group of characters + * terminated by a white space char (SPACE, CR, + * LF, FF, TAB). The token returned is stripped of + * both leading and trailing white space, and is + * terminated by a NULL terminator. An alternate + * definition of a token is a string enclosed in + * single or double quotes. + * + * Explicit Parameters: + * fp pointer to the input FILE + * dest pointer to destination buffer + * maxlen length of the destination buffer. The buffer + * length INCLUDES the NULL terminator. + * + * Implicit Parameters: stderr where the "token too long" message goes + * + * External Procedures: fgetc + * + * Side Effects: None + * + * Return Value: A token classification value, as + * defined in kparse.h. Note that the + * classification for end of file is + * always zero. + */ +int fGetToken(fp, dest, maxlen) + FILE *fp; + char *dest; + int maxlen; +{ + int ch='\0'; + int len=0; + char *p = dest; + int digits; + + ch=fGetChar(fp); + + /* + * check for a quoted string. If found, take all characters + * that fit until a closing quote is found. Note that this + * algorithm will not behave well for a string which is too long. + */ + if (ISQUOTE(ch)) { + int done = FALSE; + do { + ch = fGetChar(fp); + done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF) + ||ISQUOTE(ch)); + if (ch=='\\') + ch = fGetLiteral(fp); + if (!done) + *p++ = ch; + else if ((ch!=EOF) && !ISQUOTE(ch)) + fUngetChar(ch,fp); + } while (!done); + *p = '\0'; + if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING); + return(GTOK_QSTRING); + } + + /* + * Not a quoted string. If its a token character (rules are + * defined via the ISTOKENCHAR macro, in kparse.h) take it and all + * token chars following it until we run out of space. + */ + digits=TRUE; + if (ISTOKENCHAR(ch)) { + while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) { + if (!isdigit(ch)) digits=FALSE; + *p++ = ch; + len++; + ch = fGetChar(fp); + }; + *p = '\0'; + + if (ch!=EOF) { + fUngetChar(ch,fp); + } + if (digits) { + return(GTOK_NUMBER); + } else { + return(GTOK_STRING); + } + } + + /* + * Neither a quoted string nor a token character. Return a string + * with just that one character in it. + */ + if (ch==EOF) { + return(GTOK_EOF); + } + if (!ISWHITESPACE(ch)) { + *p++ = ch; + *p='\0'; + } else { + *p++ = ' '; /* white space is always the + * blank character */ + *p='\0'; + /* + * The character is a white space. Flush all additional white + * space. + */ + while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF)) + ; + if (ch!=EOF) { + fUngetChar(ch,fp); + } + return(GTOK_WHITE); + } + return(GTOK_PUNK); +} + +/* + * fGetLiteral is called after we find a '\' in the input stream. A + * string of numbers following the backslash are converted to the + * appropriate value; hex (0xn), octal (0n), and decimal (otherwise) + * are all supported. If the char after the \ is not a number, we + * special case certain values (\n, \f, \r, \b) or return a literal + * otherwise (useful for \", for example). + */ +fGetLiteral(fp) + FILE *fp; +{ + int ch; + int n=0; + int base; + + ch = fGetChar(fp); + + if (!isdigit(ch)) { + switch (ch) { + case 'n': return('\n'); + case 'f': return('\f'); + case 'r': return('\r'); + case 'b': return('\b'); + default: return(ch); + } + } + + /* + * got a number. might be decimal (no prefix), octal (prefix 0), + * or hexadecimal (prefix 0x). Set the base appropriately. + */ + if (ch!='0') { + base=10; /* its a decimal number */ + } else { + /* + * found a zero, its either hex or octal + */ + ch = fGetChar(fp); + if ((ch!='x') && (ch!='X')) { + base=010; + } else { + ch = fGetChar(fp); + base=0x10; + } + } + + switch (base) { + + case 010: /* octal */ + while (ISOCTAL(ch)) { + n = (n*base) + ch - '0'; + ch = fGetChar(fp); + } + break; + + case 10: /* decimal */ + while (isdigit(ch)) { + n = (n*base) + ch - '0'; + ch = fGetChar(fp); + } + break; + case 0x10: /* hexadecimal */ + while (isxdigit(ch)) { + if (isdigit(ch)) { + n = (n*base) + ch - '0'; + } else { + n = (n*base) + toupper(ch) - 'A' + 0xA ; + } + ch = fGetChar(fp); + } + break; + default: + fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c."); + exit(1); + break; + } + fUngetChar(ch,fp); + return(n); +} + +/* + * exactly the same as ungetc(3) except that the line number of the + * input file is maintained. + */ +fUngetChar(ch,fp) + int ch; + FILE *fp; +{ + if (ch=='\n') LineNbr--; + return(ungetc(ch,fp)); +} + + +/* + * exactly the same as fgetc(3) except that the line number of the + * input file is maintained. + */ +fGetChar(fp) + FILE *fp; +{ + int ch = fgetc(fp); + if (ch=='\n') LineNbr++; + return(ch); +} + + +/* + * Routine Name: strsave + * + * Function: return a pointer to a saved copy of the + * input string. the copy will be allocated + * as large as necessary. + * + * Explicit Parameters: pointer to string to save + * + * Implicit Parameters: None + * + * External Procedures: malloc,strcpy,strlen + * + * Side Effects: None + * + * Return Value: pointer to copied string + * + */ +char * strsave(p) + char *p; +{ + return(strcpy(malloc(strlen(p)+1),p)); +} + + +/* + * strutol changes all characters in a string to lower case, in place. + * the pointer to the beginning of the string is returned. + */ + +char * strutol( start ) + char *start; +{ + char *q; + for (q=start; *q; q++) + if (isupper(*q)) + *q=tolower(*q); + return(start); +} + +#ifdef GTOK_TEST /* mainline test routine for fGetToken() */ + +#define MAXTOKEN 100 + +char *pgm = "gettoken"; + +main(argc,argv) + int argc; + char **argv; +{ + char *p; + int type; + FILE *fp; + + if (--argc) { + fp = fopen(*++argv,"ra"); + if (fp == (FILE *)NULL) { + fprintf(stderr,"can\'t open \"%s\"\n",*argv); + } + } else + fp = stdin; + + p = malloc(MAXTOKEN); + while (type = fGetToken(fp,p,MAXTOKEN)) { + switch(type) { + case GTOK_BAD_QSTRING: + printf("BAD QSTRING!\t"); + break; + case GTOK_EOF: + printf("EOF!\t"); + break; + case GTOK_QSTRING: + printf("QSTRING\t"); + break; + case GTOK_STRING: + printf("STRING\t"); + break; + case GTOK_NUMBER: + printf("NUMBER\t"); + break; + case GTOK_PUNK: + printf("PUNK\t"); + break; + case GTOK_WHITE: + printf("WHITE\t"); + break; + default: + printf("HUH?\t"); + break; + } + if (*p=='\n') + printf("\\n\n"); + else + printf("%s\n",p); + } + exit(0); +} +#endif + +#ifdef KVTEST + +main(argc,argv) + int argc; + char **argv; +{ + int rc,ch; + FILE *fp; + char key[MAXKEY],valu[MAXVALUE]; + char *filename; + + if (argc != 2) { + fprintf(stderr,"usage: test <filename>\n"); + exit(1); + } + + if (!(fp=fopen(*++argv,"r"))) { + fprintf(stderr,"can\'t open input file \"%s\"\n",filename); + exit(1); + } + filename = *argv; + + while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){ + + switch (rc) { + + case KV_EOL: + printf("%s, line %d: nada mas.\n",filename,LineNbr-1); + break; + + case KV_SYNTAX: + printf("%s, line %d: syntax error: %s\n", + filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case KV_OKAY: + printf("%s, line %d: okay, %s=\"%s\"\n", + filename,LineNbr,key,valu); + break; + + default: + printf("panic: bad return (%d) from fGetKeywordValue\n",rc); + break; + } + } + printf("EOF"); + fclose(fp); + exit(0); +} +#endif + +#ifdef PSTEST + +parmtable kparm[] = { + /* keyword, default, found value */ + { "user", "", (char *)NULL }, + { "realm", "Athena", (char *)NULL }, + { "instance", "", (char *)NULL } +}; + +main(argc,argv) + int argc; + char **argv; +{ + int rc,i,ch; + FILE *fp; + char *filename; + + if (argc != 2) { + fprintf(stderr,"usage: test <filename>\n"); + exit(1); + } + + if (!(fp=fopen(*++argv,"r"))) { + fprintf(stderr,"can\'t open input file \"%s\"\n",filename); + exit(1); + } + filename = *argv; + + while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) { + + switch (rc) { + + case PS_BAD_KEYWORD: + printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case PS_SYNTAX: + printf("%s, line %d: syntax error: %s\n", + filename,LineNbr,ErrorMsg); + while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') ); + break; + + case PS_OKAY: + printf("%s, line %d: valid parameter set found:\n", + filename,LineNbr-1); + for (i=0; i<PARMCOUNT(kparm); i++) { + printf("\t%s = \"%s\"\n",kparm[i].keyword, + (kparm[i].value ? kparm[i].value + : kparm[i].defvalue)); + } + break; + + default: + printf("panic: bad return (%d) from fGetParameterSet\n",rc); + break; + } + FreeParameterSet(kparm,PARMCOUNT(kparm)); + } + printf("EOF"); + fclose(fp); + exit(0); +} +#endif diff --git a/eBones/lib/libkrb/krb_err.et b/eBones/lib/libkrb/krb_err.et new file mode 100644 index 0000000..2c6830b --- /dev/null +++ b/eBones/lib/libkrb/krb_err.et @@ -0,0 +1,257 @@ +# Copyright 1987,1988 Massachusetts Institute of Technology +# For copying and distribution information, see the file +# "Copyright.MIT". +# +# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $ +# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $ +# + error_table krb + + ec KRBET_KSUCCESS, + "Kerberos successful" + + ec KRBET_KDC_NAME_EXP, + "Kerberos principal expired" + + ec KRBET_KDC_SERVICE_EXP, + "Kerberos service expired" + + ec KRBET_KDC_AUTH_EXP, + "Kerberos auth expired" + + ec KRBET_KDC_PKT_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_P_MKEY_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_S_MKEY_VER, + "Incorrect kerberos master key version" + + ec KRBET_KDC_BYTE_ORDER, + "Kerberos error: byte order unknown" + + ec KRBET_KDC_PR_UNKNOWN, + "Kerberos principal unknown" + + ec KRBET_KDC_PR_N_UNIQUE, + "Kerberos principal not unique" + + ec KRBET_KDC_NULL_KEY, + "Kerberos principal has null key" + + ec KRBET_KRB_RES11, + "Reserved 11" + + ec KRBET_KRB_RES12, + "Reserved 12" + + ec KRBET_KRB_RES13, + "Reserved 13" + + ec KRBET_KRB_RES14, + "Reserved 14" + + ec KRBET_KRB_RES15, + "Reserved 15" + + ec KRBET_KRB_RES16, + "Reserved 16" + + ec KRBET_KRB_RES17, + "Reserved 17" + + ec KRBET_KRB_RES18, + "Reserved 18" + + ec KRBET_KRB_RES19, + "Reserved 19" + + ec KRBET_KDC_GEN_ERR, + "Generic error from Kerberos KDC" + + ec KRBET_GC_TKFIL, + "Can't read Kerberos ticket file" + + ec KRBET_GC_NOTKT, + "Can't find Kerberos ticket or TGT" + + ec KRBET_KRB_RES23, + "Reserved 23" + + ec KRBET_KRB_RES24, + "Reserved 24" + + ec KRBET_KRB_RES25, + "Reserved 25" + + ec KRBET_MK_AP_TGTEXP, + "Kerberos TGT Expired" + + ec KRBET_KRB_RES27, + "Reserved 27" + + ec KRBET_KRB_RES28, + "Reserved 28" + + ec KRBET_KRB_RES29, + "Reserved 29" + + ec KRBET_KRB_RES30, + "Reserved 30" + + ec KRBET_RD_AP_UNDEC, + "Kerberos error: Can't decode authenticator" + + ec KRBET_RD_AP_EXP, + "Kerberos ticket expired" + + ec KRBET_RD_AP_NYV, + "Kerberos ticket not yet valid" + + ec KRBET_RD_AP_REPEAT, + "Kerberos error: Repeated request" + + ec KRBET_RD_AP_NOT_US, + "The kerberos ticket isn't for us" + + ec KRBET_RD_AP_INCON, + "Kerberos request inconsistent" + + ec KRBET_RD_AP_TIME, + "Kerberos error: delta_t too big" + + ec KRBET_RD_AP_BADD, + "Kerberos error: incorrect net address" + + ec KRBET_RD_AP_VERSION, + "Kerberos protocol version mismatch" + + ec KRBET_RD_AP_MSG_TYPE, + "Kerberos error: invalid msg type" + + ec KRBET_RD_AP_MODIFIED, + "Kerberos error: message stream modified" + + ec KRBET_RD_AP_ORDER, + "Kerberos error: message out of order" + + ec KRBET_RD_AP_UNAUTHOR, + "Kerberos error: unauthorized request" + + ec KRBET_KRB_RES44, + "Reserved 44" + + ec KRBET_KRB_RES45, + "Reserved 45" + + ec KRBET_KRB_RES46, + "Reserved 46" + + ec KRBET_KRB_RES47, + "Reserved 47" + + ec KRBET_KRB_RES48, + "Reserved 48" + + ec KRBET_KRB_RES49, + "Reserved 49" + + ec KRBET_KRB_RES50, + "Reserved 50" + + ec KRBET_GT_PW_NULL, + "Kerberos error: current PW is null" + + ec KRBET_GT_PW_BADPW, + "Kerberos error: Incorrect current password" + + ec KRBET_GT_PW_PROT, + "Kerberos protocol error" + + ec KRBET_GT_PW_KDCERR, + "Error returned by Kerberos KDC" + + ec KRBET_GT_PW_NULLTKT, + "Null Kerberos ticket returned by KDC" + + ec KRBET_SKDC_RETRY, + "Kerberos error: Retry count exceeded" + + ec KRBET_SKDC_CANT, + "Kerberos error: Can't send request" + + ec KRBET_KRB_RES58, + "Reserved 58" + + ec KRBET_KRB_RES59, + "Reserved 59" + + ec KRBET_KRB_RES60, + "Reserved 60" + + ec KRBET_INTK_W_NOTALL, + "Kerberos error: not all tickets returned" + + ec KRBET_INTK_BADPW, + "Kerberos error: incorrect password" + + ec KRBET_INTK_PROT, + "Kerberos error: Protocol Error" + + ec KRBET_KRB_RES64, + "Reserved 64" + + ec KRBET_KRB_RES65, + "Reserved 65" + + ec KRBET_KRB_RES66, + "Reserved 66" + + ec KRBET_KRB_RES67, + "Reserved 67" + + ec KRBET_KRB_RES68, + "Reserved 68" + + ec KRBET_KRB_RES69, + "Reserved 69" + + ec KRBET_INTK_ERR, + "Other error" + + ec KRBET_AD_NOTGT, + "Don't have Kerberos ticket-granting ticket" + + ec KRBET_KRB_RES72, + "Reserved 72" + + ec KRBET_KRB_RES73, + "Reserved 73" + + ec KRBET_KRB_RES74, + "Reserved 74" + + ec KRBET_KRB_RES75, + "Reserved 75" + + ec KRBET_NO_TKT_FIL, + "No ticket file found" + + ec KRBET_TKT_FIL_ACC, + "Couldn't access ticket file" + + ec KRBET_TKT_FIL_LCK, + "Couldn't lock ticket file" + + ec KRBET_TKT_FIL_FMT, + "Bad ticket file format" + + ec KRBET_TKT_FIL_INI, + "tf_init not called first" + + ec KRBET_KNAME_FMT, + "Bad Kerberos name format" + + end + diff --git a/eBones/lib/libkrb/krb_err_txt.c b/eBones/lib/libkrb/krb_err_txt.c new file mode 100644 index 0000000..785563f --- /dev/null +++ b/eBones/lib/libkrb/krb_err_txt.c @@ -0,0 +1,278 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $ + * $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $"; +#endif lint + +/* + * This file contains an array of error text strings. + * The associated error codes (which are defined in "krb.h") + * follow the string in the comments at the end of each line. + */ + +char *krb_err_txt[256] = { + "OK", /* 000 */ + "Principal expired (kerberos)", /* 001 */ + "Service expired (kerberos)", /* 002 */ + "Authentication expired (kerberos)", /* 003 */ + "Unknown protocol version number (kerberos)", /* 004 */ + "Principal: Incorrect master key version (kerberos)", /* 005 */ + "Service: Incorrect master key version (kerberos)", /* 006 */ + "Bad byte order (kerberos)", /* 007 */ + "Principal unknown (kerberos)", /* 008 */ + "Principal not unique (kerberos)", /* 009 */ + "Principal has null key (kerberos)", /* 010 */ + "Reserved error message 11 (kerberos)", /* 011 */ + "Reserved error message 12 (kerberos)", /* 012 */ + "Reserved error message 13 (kerberos)", /* 013 */ + "Reserved error message 14 (kerberos)", /* 014 */ + "Reserved error message 15 (kerberos)", /* 015 */ + "Reserved error message 16 (kerberos)", /* 016 */ + "Reserved error message 17 (kerberos)", /* 017 */ + "Reserved error message 18 (kerberos)", /* 018 */ + "Reserved error message 19 (kerberos)", /* 019 */ + "Permission Denied (kerberos)", /* 020 */ + "Can't read ticket file (krb_get_cred)", /* 021 */ + "Can't find ticket (krb_get_cred)", /* 022 */ + "Reserved error message 23 (krb_get_cred)", /* 023 */ + "Reserved error message 24 (krb_get_cred)", /* 024 */ + "Reserved error message 25 (krb_get_cred)", /* 025 */ + "Ticket granting ticket expired (krb_mk_req)", /* 026 */ + "Reserved error message 27 (krb_mk_req)", /* 027 */ + "Reserved error message 28 (krb_mk_req)", /* 028 */ + "Reserved error message 29 (krb_mk_req)", /* 029 */ + "Reserved error message 30 (krb_mk_req)", /* 030 */ + "Can't decode authenticator (krb_rd_req)", /* 031 */ + "Ticket expired (krb_rd_req)", /* 032 */ + "Ticket issue date too far in the future (krb_rd_req)",/* 033 */ + "Repeat request (krb_rd_req)", /* 034 */ + "Ticket for wrong server (krb_rd_req)", /* 035 */ + "Request inconsistent (krb_rd_req)", /* 036 */ + "Time is out of bounds (krb_rd_req)", /* 037 */ + "Incorrect network address (krb_rd_req)", /* 038 */ + "Protocol version mismatch (krb_rd_req)", /* 039 */ + "Illegal message type (krb_rd_req)", /* 040 */ + "Message integrity error (krb_rd_req)", /* 041 */ + "Message duplicate or out of order (krb_rd_req)", /* 042 */ + "Unauthorized request (krb_rd_req)", /* 043 */ + "Reserved error message 44 (krb_rd_req)", /* 044 */ + "Reserved error message 45 (krb_rd_req)", /* 045 */ + "Reserved error message 46 (krb_rd_req)", /* 046 */ + "Reserved error message 47 (krb_rd_req)", /* 047 */ + "Reserved error message 48 (krb_rd_req)", /* 048 */ + "Reserved error message 49 (krb_rd_req)", /* 049 */ + "Reserved error message 50 (krb_rd_req)", /* 050 */ + "Current password is NULL (get_pw_tkt)", /* 051 */ + "Current password incorrect (get_pw_tkt)", /* 052 */ + "Protocol error (gt_pw_tkt)", /* 053 */ + "Error returned by KDC (gt_pw_tkt)", /* 054 */ + "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */ + "Retry count exceeded (send_to_kdc)", /* 056 */ + "Can't send request (send_to_kdc)", /* 057 */ + "Reserved error message 58 (send_to_kdc)", /* 058 */ + "Reserved error message 59 (send_to_kdc)", /* 059 */ + "Reserved error message 60 (send_to_kdc)", /* 060 */ + "Warning: Not ALL tickets returned", /* 061 */ + "Password incorrect", /* 062 */ + "Protocol error (get_intkt)", /* 063 */ + "Reserved error message 64 (get_in_tkt)", /* 064 */ + "Reserved error message 65 (get_in_tkt)", /* 065 */ + "Reserved error message 66 (get_in_tkt)", /* 066 */ + "Reserved error message 67 (get_in_tkt)", /* 067 */ + "Reserved error message 68 (get_in_tkt)", /* 068 */ + "Reserved error message 69 (get_in_tkt)", /* 069 */ + "Generic error (get_intkt)", /* 070 */ + "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */ + "Reserved error message 72 (get_ad_tkt)", /* 072 */ + "Reserved error message 73 (get_ad_tkt)", /* 073 */ + "Reserved error message 74 (get_ad_tkt)", /* 074 */ + "Reserved error message 75 (get_ad_tkt)", /* 075 */ + "No ticket file (tf_util)", /* 076 */ + "Can't access ticket file (tf_util)", /* 077 */ + "Can't lock ticket file; try later (tf_util)", /* 078 */ + "Bad ticket file format (tf_util)", /* 079 */ + "Read ticket file before tf_init (tf_util)", /* 080 */ + "Bad Kerberos name format (kname_parse)", /* 081 */ + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "Generic kerberos error (kfailure)", /* 255 */ +}; diff --git a/eBones/lib/libkrb/krb_get_in_tkt.c b/eBones/lib/libkrb/krb_get_in_tkt.c new file mode 100644 index 0000000..a37bb60 --- /dev/null +++ b/eBones/lib/libkrb/krb_get_in_tkt.c @@ -0,0 +1,297 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $ + * $Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <des.h> +#include <prot.h> + +#include <stdio.h> +#include <strings.h> +#include <errno.h> + +/* use the bsd time.h struct defs for PC too! */ +#include <sys/time.h> +#include <sys/types.h> + +int swap_bytes; + +/* + * decrypt_tkt(): Given user, instance, realm, passwd, key_proc + * and the cipher text sent from the KDC, decrypt the cipher text + * using the key returned by key_proc. + */ + +static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp) + char *user; + char *instance; + char *realm; + char *arg; + int (*key_proc)(); + KTEXT *cipp; +{ + KTEXT cip = *cipp; + C_Block key; /* Key for decrypting cipher */ + Key_schedule key_s; + +#ifndef NOENCRYPTION + /* Attempt to decrypt it */ +#endif + + /* generate a key */ + + { + register int rc; + rc = (*key_proc)(user,instance,realm,arg,key); + if (rc) + return(rc); + } + +#ifndef NOENCRYPTION + key_sched(key,key_s); + pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat, + (long) cip->length,key_s,key,DES_DECRYPT); +#endif /* !NOENCRYPTION */ + /* Get rid of all traces of key */ + bzero((char *)key,sizeof(key)); + bzero((char *)key_s,sizeof(key_s)); + + return(0); +} + +/* + * krb_get_in_tkt() gets a ticket for a given principal to use a given + * service and stores the returned ticket and session key for future + * use. + * + * The "user", "instance", and "realm" arguments give the identity of + * the client who will use the ticket. The "service" and "sinstance" + * arguments give the identity of the server that the client wishes + * to use. (The realm of the server is the same as the Kerberos server + * to whom the request is sent.) The "life" argument indicates the + * desired lifetime of the ticket; the "key_proc" argument is a pointer + * to the routine used for getting the client's private key to decrypt + * the reply from Kerberos. The "decrypt_proc" argument is a pointer + * to the routine used to decrypt the reply from Kerberos; and "arg" + * is an argument to be passed on to the "key_proc" routine. + * + * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it + * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned + * by Kerberos, then the error code it contains is returned. Other + * error codes returned by this routine include INTK_PROT to indicate + * wrong protocol version, INTK_BADPW to indicate bad password (if + * decrypted ticket didn't make sense), INTK_ERR if the ticket was for + * the wrong server or the ticket store couldn't be initialized. + * + * The format of the message sent to Kerberos is as follows: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_KDC_REQUEST | message type + * HOST_BYTE_ORDER local byte order in lsb + * string user client's name + * string instance client's instance + * string realm client's realm + * 4 bytes tlocal.tv_sec timestamp in seconds + * 1 byte life desired lifetime + * string service service's name + * string sinstance service's instance + */ + +krb_get_in_tkt(user, instance, realm, service, sinstance, life, + key_proc, decrypt_proc, arg) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + int (*key_proc)(); + int (*decrypt_proc)(); + char *arg; +{ + KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; /* Packet to KDC */ + KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + C_Block ses; /* Session key for tkt */ + int kvno; /* Kvno for session key */ + unsigned char *v = pkt->dat; /* Prot vers no */ + unsigned char *t = (pkt->dat+1); /* Prot msg type */ + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + char rlm[REALM_SZ]; + int lifetime; + int msg_byte_order; + int kerror; + unsigned long exp_date; + char *ptr; + + struct timeval t_local; + + unsigned long rep_err_code; + + unsigned long kdc_time; /* KDC time */ + + /* BUILD REQUEST PACKET */ + + /* Set up the fixed part of the packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Now for the variable info */ + (void) strcpy((char *)(pkt->dat+2),user); /* aname */ + pkt->length = 3 + strlen(user); + (void) strcpy((char *)(pkt->dat+pkt->length), + instance); /* instance */ + pkt->length += 1 + strlen(instance); + (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */ + pkt->length += 1 + strlen(realm); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + /* timestamp */ + bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4); + pkt->length += 4; + + *(pkt->dat+(pkt->length)++) = (char) life; + (void) strcpy((char *)(pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */ + + if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4); + if (swap_bytes) swap_u_long(rep_err_code); + return((int)rep_err_code); + default: + return(INTK_PROT); + } + + /* EXTRACT INFORMATION FROM RETURN PACKET */ + + /* get the principal's expiration date */ + bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date)); + if (swap_bytes) swap_u_long(exp_date); + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + if ((cip->length < 0) || (cip->length > sizeof(cip->dat))) + return(INTK_ERR); /* no appropriate error code + currently defined for INTK_ */ + /* copy information from return packet into "cip" */ + bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length); + + /* Attempt to decrypt the reply. */ + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip); + + ptr = (char *) cip->dat; + + /* extract session key */ + bcopy(ptr,(char *)ses,8); + ptr += 8; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's name */ + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's instance */ + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's realm */ + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + /* extract ticket lifetime, server key version, ticket length */ + /* be sure to avoid sign extension on lifetime! */ + lifetime = (unsigned char) ptr[0]; + kvno = (unsigned char) ptr[1]; + tkt->length = (unsigned char) ptr[2]; + ptr += 3; + + if ((tkt->length < 0) || + ((tkt->length + (ptr - (char *) cip->dat)) > cip->length)) + return(INTK_BADPW); + + /* extract ticket itself */ + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&t_local,(struct timezone *) 0); + if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + /* initialize ticket cache */ + if (in_tkt(user,instance) != KSUCCESS) + return(INTK_ERR); + + /* stash ticket, session key, etc. for future use */ + if (kerror = save_credentials(s_name, s_instance, rlm, ses, + lifetime, kvno, tkt, t_local.tv_sec)) + return(kerror); + + return(INTK_OK); +} diff --git a/eBones/lib/libkrb/krb_realmofhost.3 b/eBones/lib/libkrb/krb_realmofhost.3 new file mode 100644 index 0000000..f284069 --- /dev/null +++ b/eBones/lib/libkrb/krb_realmofhost.3 @@ -0,0 +1,161 @@ +.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $ +.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst, +krb_get_lrealm \- additional Kerberos utility routines +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.ft B +char *krb_realmofhost(host) +char *host; +.PP +.ft B +char *krb_get_phost(alias) +char *alias; +.PP +.ft B +krb_get_krbhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_admhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_lrealm(realm,n) +char *realm; +int n; +.fi +.ft R +.SH DESCRIPTION +.I krb_realmofhost +returns the Kerberos realm of the host +.IR host , +as determined by the translation table +.IR /etc/krb.realms . +.I host +should be the fully-qualified domain-style primary host name of the host +in question. In order to prevent certain security attacks, this routine +must either have +.I a priori +knowledge of a host's realm, or obtain such information securely. +.PP +The format of the translation file is described by +.IR krb.realms (5). +If +.I host +exactly matches a host_name line, the corresponding realm +is returned. +Otherwise, if the domain portion of +.I host +matches a domain_name line, the corresponding realm +is returned. +If +.I host +contains a domain, but no translation is found, +.IR host 's +domain is converted to upper-case and returned. +If +.I host +contains no discernable domain, or an error occurs, +the local realm name, as supplied by +.IR krb_get_lrealm (3), +is returned. +.PP +.I krb_get_phost +converts the hostname +.I alias +(which can be either an official name or an alias) into the instance +name to be used in obtaining Kerberos tickets for most services, +including the Berkeley rcmd suite (rlogin, rcp, rsh). +.br +The current convention is to return the first segment of the official +domain-style name after conversion to lower case. +.PP +.I krb_get_krbhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos key distribution center (KDC) +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +The configuration file is described by +.IR krb.conf (5). +If the host is successfully filled in, the routine +returns KSUCCESS. +If the file cannot be opened, and +.I n +equals 1, then the value of KRB_HOST as defined in +.I <krb.h> +is filled in, and KSUCCESS is returned. If there are fewer than +.I n +hosts running a Kerberos KDC for the requested realm, or the +configuration file is malformed, the routine +returns KFAILURE. +.PP +.I krb_get_admhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos KDC database administration server +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +If the file cannot be opened or is malformed, or there are fewer than +.I n +hosts running a Kerberos KDC database administration server, +the routine returns KFAILURE. +.PP +The character arrays used as return values for +.IR krb_get_krbhst , +.IR krb_get_admhst , +should be large enough to +hold any hostname (MAXHOSTNAMELEN from <sys/param.h>). +.PP +.I krb_get_lrealm +fills in +.I realm +with the +.IR n th +realm of the local host, as specified in the configuration file. +.I realm +should be at least REALM_SZ (from +.IR <krb.h>) characters long. +.PP +.SH SEE ALSO +kerberos(3), krb.conf(5), krb.realms(5) +.SH FILES +.TP 20n +/etc/krb.realms +translation file for host-to-realm mapping. +.TP +/etc/krb.conf +local realm-name and realm/server configuration file. +.SH BUGS +The current convention for instance names is too limited; the full +domain name should be used. +.PP +.I krb_get_lrealm +currently only supports +.I n += 1. It should really consult the user's ticket cache to determine the +user's current realm, rather than consulting a file on the host. diff --git a/eBones/lib/libkrb/krb_sendauth.3 b/eBones/lib/libkrb/krb_sendauth.3 new file mode 100644 index 0000000..f5e95b7 --- /dev/null +++ b/eBones/lib/libkrb/krb_sendauth.3 @@ -0,0 +1,348 @@ +.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $ +.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $ +.\" Copyright 1988 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \- +Kerberos routines for sending authentication via network stream sockets +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.fi +.HP 1i +.ft B +int krb_sendauth(options, fd, ktext, service, inst, realm, checksum, +msg_data, cred, schedule, laddr, faddr, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst, *realm; +u_long checksum; +MSG_DAT *msg_data; +CREDENTIALS *cred; +Key_schedule schedule; +struct sockaddr_in *laddr, *faddr; +char *version; +.PP +.fi +.HP 1i +.ft B +int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr, +auth_data, filename, schedule, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst; +struct sockaddr_in *faddr, *laddr; +AUTH_DAT *auth_data; +char *filename; +Key_schedule schedule; +char *version; +.PP +.ft B +int krb_net_write(fd, buf, len) +int fd; +char *buf; +int len; +.PP +.ft B +int krb_net_read(fd, buf, len) +int fd; +char *buf; +int len; +.fi +.SH DESCRIPTION +.PP +These functions, +which are built on top of the core Kerberos library, +provide a convenient means for client and server +programs to send authentication messages +to one another through network connections. +The +.I krb_sendauth +function sends an authenticated ticket from the client program to +the server program by writing the ticket to a network socket. +The +.I krb_recvauth +function receives the ticket from the client by +reading from a network socket. + +.SH KRB_SENDAUTH +.PP +This function writes the ticket to +the network socket specified by the +file descriptor +.IR fd, +returning KSUCCESS if the write proceeds successfully, +and an error code if it does not. + +The +.I ktext +argument should point to an allocated KTEXT_ST structure. +The +.IR service, +.IR inst, +and +.IR realm +arguments specify the server program's Kerberos principal name, +instance, and realm. +If you are writing a client that uses the local realm exclusively, +you can set the +.I realm +argument to NULL. + +The +.I version +argument allows the client program to pass an application-specific +version string that the server program can then match against +its own version string. +The +.I version +string can be up to KSEND_VNO_LEN (see +.IR <krb.h> ) +characters in length. + +The +.I checksum +argument can be used to pass checksum information to the +server program. +The client program is responsible for specifying this information. +This checksum information is difficult to corrupt because +.I krb_sendauth +passes it over the network in encrypted form. +The +.I checksum +argument is passed as the checksum argument to +.IR krb_mk_req . + +You can set +.IR krb_sendauth's +other arguments to NULL unless you want the +client and server programs to mutually authenticate +themselves. +In the case of mutual authentication, +the client authenticates itself to the server program, +and demands that the server in turn authenticate itself to +the client. + +.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION +.PP +If you want mutual authentication, +make sure that you read all pending data from the local socket +before calling +.IR krb_sendauth. +Set +.IR krb_sendauth's +.I options +argument to +.BR KOPT_DO_MUTUAL +(this macro is defined in the +.IR krb.h +file); +make sure that the +.I laddr +argument points to +the address of the local socket, +and that +.I faddr +points to the foreign socket's network address. + +.I Krb_sendauth +fills in the other arguments-- +.IR msg_data , +.IR cred , +and +.IR schedule --before +sending the ticket to the server program. +You must, however, allocate space for these arguments +before calling the function. + +.I Krb_sendauth +supports two other options: +.BR KOPT_DONT_MK_REQ, +and +.BR KOPT_DONT_CANON. +If called with +.I options +set as KOPT_DONT_MK_REQ, +.I krb_sendauth +will not use the +.I krb_mk_req +function to retrieve the ticket from the Kerberos server. +The +.I ktext +argument must point to an existing ticket and authenticator (such as +would be created by +.IR krb_mk_req ), +and the +.IR service, +.IR inst, +and +.IR realm +arguments can be set to NULL. + +If called with +.I options +set as KOPT_DONT_CANON, +.I krb_sendauth +will not convert the service's instance to canonical form using +.IR krb_get_phost (3). + +If you want to call +.I krb_sendauth +with a multiple +.I options +specification, +construct +.I options +as a bitwise-OR of the options you want to specify. + +.SH KRB_RECVAUTH +.PP +The +.I krb_recvauth +function +reads a ticket/authenticator pair from the socket pointed to by the +.I fd +argument. +Set the +.I options +argument +as a bitwise-OR of the options desired. +Currently only KOPT_DO_MUTUAL is useful to the receiver. + +The +.I ktext +argument +should point to an allocated KTEXT_ST structure. +.I Krb_recvauth +fills +.I ktext +with the +ticket/authenticator pair read from +.IR fd , +then passes it to +.IR krb_rd_req . + +The +.I service +and +.I inst +arguments +specify the expected service and instance for which the ticket was +generated. They are also passed to +.IR krb_rd_req. +The +.I inst +argument may be set to "*" if the caller wishes +.I krb_mk_req +to fill in the instance used (note that there must be space in the +.I inst +argument to hold a full instance name, see +.IR krb_mk_req (3)). + +The +.I faddr +argument +should point to the address of the peer which is presenting the ticket. +It is also passed to +.IR krb_rd_req . + +If the client and server plan to mutually authenticate +one another, +the +.I laddr +argument +should point to the local address of the file descriptor. +Otherwise you can set this argument to NULL. + +The +.I auth_data +argument +should point to an allocated AUTH_DAT area. +It is passed to and filled in by +.IR krb_rd_req . +The checksum passed to the corresponding +.I krb_sendauth +is available as part of the filled-in AUTH_DAT area. + +The +.I filename +argument +specifies the filename +which the service program should use to obtain its service key. +.I Krb_recvauth +passes +.I filename +to the +.I krb_rd_req +function. +If you set this argument to "", +.I krb_rd_req +looks for the service key in the file +.IR /etc/srvtab. + +If the client and server are performing mutual authenication, +the +.I schedule +argument +should point to an allocated Key_schedule. +Otherwise it is ignored and may be NULL. + +The +.I version +argument should point to a character array of at least KSEND_VNO_LEN +characters. It is filled in with the version string passed by the client to +.IR krb_sendauth. +.PP +.SH KRB_NET_WRITE AND KRB_NET_READ +.PP +The +.I krb_net_write +function +emulates the write(2) system call, but guarantees that all data +specified is written to +.I fd +before returning, unless an error condition occurs. +.PP +The +.I krb_net_read +function +emulates the read(2) system call, but guarantees that the requested +amount of data is read from +.I fd +before returning, unless an error condition occurs. +.PP +.SH BUGS +.IR krb_sendauth, +.IR krb_recvauth, +.IR krb_net_write, +and +.IR krb_net_read +will not work properly on sockets set to non-blocking I/O mode. + +.SH SEE ALSO + +krb_mk_req(3), krb_rd_req(3), krb_get_phost(3) + +.SH AUTHOR +John T. Kohl, MIT Project Athena +.SH RESTRICTIONS +Copyright 1988, Massachusetts Instititute of Technology. +For copying and distribution information, +please see the file <mit-copyright.h>. diff --git a/eBones/lib/libkrb/krb_set_tkt_string.3 b/eBones/lib/libkrb/krb_set_tkt_string.3 new file mode 100644 index 0000000..c9f3dcf --- /dev/null +++ b/eBones/lib/libkrb/krb_set_tkt_string.3 @@ -0,0 +1,43 @@ +.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $ +.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_set_tkt_string \- set Kerberos ticket cache file name +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +void krb_set_tkt_string(filename) +char *filename; +.fi +.ft R +.SH DESCRIPTION +.I krb_set_tkt_string +sets the name of the file that holds the user's +cache of Kerberos server tickets and associated session keys. +.PP +The string +.I filename +passed in is copied into local storage. +Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are +copied in for use as the cache file name. +.PP +This routine should be called during initialization, before other +Kerberos routines are called; otherwise the routines which fetch the +ticket cache file name may be called and return an undesired ticket file +name until this routine is called. +.SH FILES +.TP 20n +/tmp/tkt[uid] +default ticket file name, unless the environment variable KRBTKFILE is set. +[uid] denotes the user's uid, in decimal. +.SH SEE ALSO +kerberos(3), setenv(3) diff --git a/eBones/lib/libkrb/krbglue.c b/eBones/lib/libkrb/krbglue.c new file mode 100644 index 0000000..8e864c1 --- /dev/null +++ b/eBones/lib/libkrb/krbglue.c @@ -0,0 +1,252 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $ + * $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $"; +#endif lint + +#ifndef NCOMPAT +/* + * glue together new libraries and old clients + */ + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "des.h" +#include "krb.h" + +/* These definitions should be in krb.h, no? */ +#if defined(__HIGHC__) +#undef __STDC__ +#endif +#ifdef __STDC__ +extern int krb_mk_req (KTEXT, char *, char *, char *, long); +extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *); +extern int krb_kntoln (AUTH_DAT *, char *); +extern int krb_set_key (char *, int); +extern int krb_get_cred (char *, char *, char *, CREDENTIALS *); +extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule, + C_Block, struct sockaddr_in *, + struct sockaddr_in *); +extern long krb_rd_priv (u_char *, u_long, Key_schedule, + C_Block, struct sockaddr_in *, + struct sockaddr_in *, MSG_DAT *); +extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *, + struct sockaddr_in *, struct sockaddr_in *); +extern long krb_rd_safe (u_char *, u_long, C_Block *, + struct sockaddr_in *, struct sockaddr_in *, + MSG_DAT *); +extern long krb_mk_err (u_char *, long, char *); +extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *); +extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int, + char *); +extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int, + char *); +extern int krb_get_pw_tkt (char *, char *, char *, char *); +extern int krb_get_lrealm (char *, char *); +extern int krb_realmofhost (char *); +extern char *krb_get_phost (char *); +extern int krb_get_krbhst (char *, char *, int); +#ifdef DEBUG +extern KTEXT krb_create_death_packet (char *); +#endif /* DEBUG */ +#else +extern int krb_mk_req (); +extern int krb_rd_req (); +extern int krb_kntoln (); +extern int krb_set_key (); +extern int krb_get_cred (); +extern long krb_mk_priv (); +extern long krb_rd_priv (); +extern long krb_mk_safe (); +extern long krb_rd_safe (); +extern long krb_mk_err (); +extern int krb_rd_err (); +extern int krb_get_pw_in_tkt (); +extern int krb_get_svc_in_tkt (); +extern int krb_get_pw_tkt (); +extern int krb_get_lrealm (); +extern int krb_realmofhost (); +extern char *krb_get_phost (); +extern int krb_get_krbhst (); +#ifdef DEBUG +extern KTEXT krb_create_death_packet (); +#endif /* DEBUG */ +#endif /* STDC */ +int mk_ap_req(authent, service, instance, realm, checksum) + KTEXT authent; + char *service, *instance, *realm; + u_long checksum; +{ + return krb_mk_req(authent,service,instance,realm,checksum); +} + +int rd_ap_req(authent, service, instance, from_addr, ad, fn) + KTEXT authent; + char *service, *instance; + u_long from_addr; + AUTH_DAT *ad; + char *fn; +{ + return krb_rd_req(authent,service,instance,from_addr,ad,fn); +} + +int an_to_ln(ad, lname) + AUTH_DAT *ad; + char *lname; +{ + return krb_kntoln (ad,lname); +} + +int set_serv_key (key, cvt) + char *key; + int cvt; +{ + return krb_set_key(key,cvt); +} + +int get_credentials (svc,inst,rlm,cred) + char *svc, *inst, *rlm; + CREDENTIALS *cred; +{ + return krb_get_cred (svc, inst, rlm, cred); +} + +long mk_private_msg (in,out,in_length,schedule,key,sender,receiver) + u_char *in, *out; + u_long in_length; + Key_schedule schedule; + C_Block key; + struct sockaddr_in *sender, *receiver; +{ + return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver); +} + +long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data) + u_char *in; + u_long in_length; + Key_schedule schedule; + C_Block key; + struct sockaddr_in *sender, *receiver; + MSG_DAT *msg_data; +{ + return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data); +} + +long mk_safe_msg (in,out,in_length,key,sender,receiver) + u_char *in, *out; + u_long in_length; + C_Block *key; + struct sockaddr_in *sender, *receiver; +{ + return krb_mk_safe (in,out,in_length,key,sender,receiver); +} + +long rd_safe_msg (in,length,key,sender,receiver,msg_data) + u_char *in; + u_long length; + C_Block *key; + struct sockaddr_in *sender, *receiver; + MSG_DAT *msg_data; +{ + return krb_rd_safe (in,length,key,sender,receiver,msg_data); +} + +long mk_appl_err_msg (out,code,string) + u_char *out; + long code; + char *string; +{ + return krb_mk_err (out,code,string); +} + +long rd_appl_err_msg (in,length,code,msg_data) + u_char *in; + u_long length; + long *code; + MSG_DAT *msg_data; +{ + return krb_rd_err (in,length,code,msg_data); +} + +int get_in_tkt(user,instance,realm,service,sinstance,life,password) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *password; +{ + return krb_get_pw_in_tkt(user,instance,realm,service,sinstance, + life,password); +} + +int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user, *instance, *realm, *service, *sinstance; + int life; + char *srvtab; +{ + return krb_get_svc_in_tkt(user, instance, realm, service, sinstance, + life, srvtab); +} + +int get_pw_tkt(user,instance,realm,cpw) + char *user; + char *instance; + char *realm; + char *cpw; +{ + return krb_get_pw_tkt(user,instance,realm,cpw); +} + +int +get_krbrlm (r, n) +char *r; +int n; +{ + return krb_get_lream(r,n); +} + +int +krb_getrealm (host) +{ + return krb_realmofhost(host); +} + +char * +get_phost (host) +char *host +{ + return krb_get_phost(host); +} + +int +get_krbhst (h, r, n) +char *h; +char *r; +int n; +{ + return krb_get_krbhst(h,r,n); +} +#ifdef DEBUG +struct ktext *create_death_packet(a_name) + char *a_name; +{ + return krb_create_death_packet(a_name); +} +#endif /* DEBUG */ + +#if 0 +extern int krb_ck_repl (); + +int check_replay () +{ + return krb_ck_repl (); +} +#endif +#endif /* NCOMPAT */ diff --git a/eBones/lib/libkrb/kuserok.3 b/eBones/lib/libkrb/kuserok.3 new file mode 100644 index 0000000..36968ba --- /dev/null +++ b/eBones/lib/libkrb/kuserok.3 @@ -0,0 +1,63 @@ +.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $ +.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kuserok \- Kerberos version of ruserok +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +kuserok(kdata, localuser) +AUTH_DAT *auth_data; +char *localuser; +.fi +.ft R +.SH DESCRIPTION +.I kuserok +determines whether a Kerberos principal described by the structure +.I auth_data +is authorized to login as user +.I localuser +according to the authorization file +("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized, +1 (one) if not authorized. +.PP +If there is no account for +.I localuser +on the local machine, authorization is not granted. +If there is no authorization file, and the Kerberos principal described +by +.I auth_data +translates to +.I localuser +(using +.IR krb_kntoln (3)), +authorization is granted. +If the authorization file +can't be accessed, or the file is not owned by +.IR localuser, +authorization is denied. Otherwise, the file is searched for +a matching principal name, instance, and realm. If a match is found, +authorization is granted, else authorization is denied. +.PP +The file entries are in the format: +.nf +.in +5n + name.instance@realm +.in -5n +.fi +with one entry per line. +.SH SEE ALSO +kerberos(3), ruserok(3), krb_kntoln(3) +.SH FILES +.TP 20n +~\fIlocaluser\fR/.klogin +authorization list diff --git a/eBones/lib/libkrb/kuserok.c b/eBones/lib/libkrb/kuserok.c new file mode 100644 index 0000000..cb1f708 --- /dev/null +++ b/eBones/lib/libkrb/kuserok.c @@ -0,0 +1,195 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * kuserok: check if a kerberos principal has + * access to a local account + * + * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $ + * $Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <stdio.h> +#include <pwd.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <strings.h> + +#define OK 0 +#define NOTOK 1 +#define MAX_USERNAME 10 + +/* + * Given a Kerberos principal "kdata", and a local username "luser", + * determine whether user is authorized to login according to the + * authorization file ("~luser/.klogin" by default). Returns OK + * if authorized, NOTOK if not authorized. + * + * If there is no account for "luser" on the local machine, returns + * NOTOK. If there is no authorization file, and the given Kerberos + * name "kdata" translates to the same name as "luser" (using + * krb_kntoln()), returns OK. Otherwise, if the authorization file + * can't be accessed, returns NOTOK. Otherwise, the file is read for + * a matching principal name, instance, and realm. If one is found, + * returns OK, if none is found, returns NOTOK. + * + * The file entries are in the format: + * + * name.instance@realm + * + * one entry per line. + * + * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin + * file entries. See the file "kparse.c". + */ + +#ifdef ATHENA_COMPAT + +#include <kparse.h> + +/* + * The parmtable defines the keywords we will recognize with their + * default values, and keeps a pointer to the found value. The found + * value should be filled in with strsave(), since FreeParameterSet() + * will release memory for all non-NULL found strings. + * +*** NOTE WELL! *** + * + * The table below is very nice, but we cannot hard-code a default for the + * realm: we have to get the realm via krb_get_lrealm(). Even though the + * default shows as "from krb_get_lrealm, below", it gets changed in + * kuserok to whatever krb_get_lrealm() tells us. That code assumes that + * the realm will be the entry number in the table below, so if you + * change the order of the entries below, you have to change the + * #definition of REALM_SCRIPT to reflect it. + */ +#define REALM_SUBSCRIPT 1 +parmtable kparm[] = { + +/* keyword default found value */ +{"user", "", (char *) NULL}, +{"realm", "see krb_get_lrealm, below", (char *) NULL}, +{"instance", "", (char *) NULL}, +}; +#define KPARMS kparm,PARMCOUNT(kparm) +#endif ATHENA_COMPAT + +kuserok(kdata, luser) + AUTH_DAT *kdata; + char *luser; +{ + struct stat sbuf; + struct passwd *pwd; + char pbuf[MAXPATHLEN]; + int isok = NOTOK, rc; + FILE *fp; + char kuser[MAX_USERNAME]; + char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; + char linebuf[BUFSIZ]; + char *newline; + int gobble; +#ifdef ATHENA_COMPAT + char local_realm[REALM_SZ]; +#endif ATHENA_COMPAT + + /* no account => no access */ + if ((pwd = getpwnam(luser)) == NULL) { + return(NOTOK); + } + (void) strcpy(pbuf, pwd->pw_dir); + (void) strcat(pbuf, "/.klogin"); + + if (access(pbuf, F_OK)) { /* not accessible */ + /* + * if he's trying to log in as himself, and there is no .klogin file, + * let him. To find out, call + * krb_kntoln to convert the triple in kdata to a name which we can + * string compare. + */ + if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) { + return(OK); + } + } + /* open ~/.klogin */ + if ((fp = fopen(pbuf, "r")) == NULL) { + return(NOTOK); + } + /* + * security: if the user does not own his own .klogin file, + * do not grant access + */ + if (fstat(fileno(fp), &sbuf)) { + fclose(fp); + return(NOTOK); + } + if (sbuf.st_uid != pwd->pw_uid) { + fclose(fp); + return(NOTOK); + } + +#ifdef ATHENA_COMPAT + /* Accept old-style .klogin files */ + + /* + * change the default realm from the hard-coded value to the + * accepted realm that Kerberos specifies. + */ + rc = krb_get_lrealm(local_realm, 1); + if (rc == KSUCCESS) + kparm[REALM_SUBSCRIPT].defvalue = local_realm; + else + return (rc); + + /* check each line */ + while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) { + switch (rc) { + case PS_BAD_KEYWORD: + case PS_SYNTAX: + while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n')); + break; + + case PS_OKAY: + isok = (ParmCompare(KPARMS, "user", kdata->pname) || + ParmCompare(KPARMS, "instance", kdata->pinst) || + ParmCompare(KPARMS, "realm", kdata->prealm)); + break; + + default: + break; + } + FreeParameterSet(kparm, PARMCOUNT(kparm)); + } + /* reset the stream for parsing new-style names, if necessary */ + rewind(fp); +#endif ATHENA_COMPAT + + /* check each line */ + while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) { + /* null-terminate the input string */ + linebuf[BUFSIZ-1] = '\0'; + newline = NULL; + /* nuke the newline if it exists */ + if (newline = index(linebuf, '\n')) + *newline = '\0'; + rc = kname_parse(principal, inst, realm, linebuf); + if (rc == KSUCCESS) { + isok = (strncmp(kdata->pname, principal, ANAME_SZ) || + strncmp(kdata->pinst, inst, INST_SZ) || + strncmp(kdata->prealm, realm, REALM_SZ)); + } + /* clean up the rest of the line if necessary */ + if (!newline) + while (((gobble = getc(fp)) != EOF) && gobble != '\n'); + } + fclose(fp); + return(isok); +} diff --git a/eBones/lib/libkrb/log.c b/eBones/lib/libkrb/log.c new file mode 100644 index 0000000..42fccfb --- /dev/null +++ b/eBones/lib/libkrb/log.c @@ -0,0 +1,121 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $ + * $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> +#include <krb.h> +#include <klog.h> + +static char *log_name = KRBLOG; +static is_open; + +/* + * This file contains three logging routines: set_logfile() + * to determine the file that log entries should be written to; + * and log() and new_log() to write log entries to the file. + */ + +/* + * log() is used to add entries to the logfile (see set_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format". + * + * The log file is opened and closed for each log entry. + * + * The return value is undefined. + */ + +__BEGIN_DECLS +char *month_sname __P((int)); +__END_DECLS + + +/*VARARGS1 */ +void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0) + char *format; + int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0; +{ + FILE *logfile, *fopen(); + long time(),now; + struct tm *tm; + + if ((logfile = fopen(log_name,"a")) == NULL) + return; + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + fprintf(logfile,"\n"); + (void) fclose(logfile); + return; +} + +/* + * set_logfile() changes the name of the file to which + * messages are logged. If set_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +set_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} + +/* + * new_log() appends a log entry containing the give time "t" and the + * string "string" to the logfile (see set_logfile() above). The file + * is opened once and left open. The routine returns 1 on failure, 0 + * on success. + */ + +new_log(t,string) + long t; + char *string; +{ + static FILE *logfile; + + long time(); + struct tm *tm; + + if (!is_open) { + if ((logfile = fopen(log_name,"a")) == NULL) return(1); + is_open = 1; + } + + if (t) { + tm = localtime(&t); + + fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec, string); + } + else { + fprintf(logfile,"\n%20s%s","",string); + } + + (void) fflush(logfile); + return(0); +} diff --git a/eBones/lib/libkrb/mk_err.c b/eBones/lib/libkrb/mk_err.c new file mode 100644 index 0000000..331cba9 --- /dev/null +++ b/eBones/lib/libkrb/mk_err.c @@ -0,0 +1,63 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $ + * $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/types.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +/* + * This routine creates a general purpose error reply message. It + * doesn't use KTEXT because application protocol may have long + * messages, and may want this part of buffer contiguous to other + * stuff. + * + * The error reply is built in "p", using the error code "e" and + * error text "e_string" given. The length of the error reply is + * returned. + * + * The error reply is in the following format: + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_ERR message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte order + * 4 bytes e given error code + * string e_string given error text + */ + +long krb_mk_err(p,e,e_string) + u_char *p; /* Where to build error packet */ + long e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *start; + + start = p; + + /* Create fixed part of packet */ + *p++ = (unsigned char) KRB_PROT_VERSION; + *p = (unsigned char) AUTH_MSG_APPL_ERR; + *p++ |= HOST_BYTE_ORDER; + + /* Add the basic info */ + bcopy((char *)&e,(char *)p,4); /* err code */ + p += sizeof(e); + (void) strcpy((char *)p,e_string); /* err text */ + p += strlen(e_string); + + /* And return the length */ + return p-start; +} diff --git a/eBones/lib/libkrb/mk_priv.c b/eBones/lib/libkrb/mk_priv.c new file mode 100644 index 0000000..3bae4ed --- /dev/null +++ b/eBones/lib/libkrb/mk_priv.c @@ -0,0 +1,203 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine constructs a Kerberos 'private msg', i.e. + * cryptographically sealed with a private session key. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT. + * + * Note-- It's too bad that it did a long int compare on the RT before. + * + * Returns either < 0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + * + * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $ + * $Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + + +static u_long c_length; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes + * some user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address. +#ifndef NOENCRYTION + * The packet is encrypted by pcbc_encrypt(), using the given + * "key" and "schedule". +#endif + * The length of the resulting packet "out" is + * returned. + * + * It is similar to krb_mk_safe() except for the additional key + * schedule argument "schedule" and the fact that the data is encrypted + * rather than appended with a checksum. Also, the protocol version + * number is "private_msg_ver", defined in krb_rd_priv.c, rather than + * KRB_PROT_VERSION, defined in "krb.h". + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte private_msg_ver protocol version number + * 1 byte AUTH_MSG_PRIVATE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * 4 bytes c_length length of data +#ifndef NOENCRYPT + * we encrypt from here with pcbc_encrypt +#endif + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * 0<=n<=7 bytes pad to 8 byte multiple zeroes + */ + +long krb_mk_priv(in,out,length,schedule,key,sender,receiver) + u_char *in; /* application data */ + u_char *out; /* put msg here, leave room for + * header! breaks if in and out + * (header stuff) overlap */ + u_long length; /* of in data */ + Key_schedule schedule; /* precomputed key schedule */ + C_Block key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + static u_char *c_length_ptr; + extern int private_msg_ver; /* in krb_rd_priv.c */ + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = private_msg_ver; + *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER; + + /* calculate cipher length */ + c_length_ptr = p; + p += sizeof(c_length); + + q = p; + + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + +#ifdef NOENCRYPTION + /* make all the stuff contiguous for checksum */ +#else + /* make all the stuff contiguous for checksum and encryption */ +#endif + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *)&sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok + * until 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + +#ifdef notdef + /* + * calculate the checksum of the length, address, sequence, and + * inp data + */ + cksum = quad_cksum(q,NULL,p-q,0,key); + if (krb_debug) + printf("\ncksum = %u",cksum); + /* stuff checksum */ + bcopy((char *) &cksum,(char *) p,sizeof(cksum)); + p += sizeof(cksum); +#endif + + /* + * All the data have been assembled, compute length + */ + + c_length = p - q; + c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) * + sizeof(C_Block); + /* stuff the length */ + bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length)); + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT); +#endif /* NOENCRYPTION */ + + return (q - out + c_length); /* resulting size */ +} diff --git a/eBones/lib/libkrb/mk_req.c b/eBones/lib/libkrb/mk_req.c new file mode 100644 index 0000000..bb0f097 --- /dev/null +++ b/eBones/lib/libkrb/mk_req.c @@ -0,0 +1,195 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $ + * $Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> +#include <des.h> +#include <sys/time.h> +#include <strings.h> + +extern int krb_ap_req_debug; +static struct timeval tv_local = { 0, 0 }; +static int lifetime = DEFAULT_TKT_LIFE; + +/* + * krb_mk_req takes a text structure in which an authenticator is to + * be built, the name of a service, an instance, a realm, + * and a checksum. It then retrieves a ticket for + * the desired service and creates an authenticator in the text + * structure passed as the first argument. krb_mk_req returns + * KSUCCESS on success and a Kerberos error code on failure. + * + * The peer procedure on the other end is krb_rd_req. When making + * any changes to this routine it is important to make corresponding + * changes to krb_rd_req. + * + * The authenticator consists of the following: + * + * authent->dat + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_REQUEST message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte ordering + * unsigned char kvno from ticket server's key version + * string realm server's realm + * unsigned char tl ticket length + * unsigned char idl request id length + * text ticket->dat ticket for server + * text req_id->dat request id + * + * The ticket information is retrieved from the ticket cache or + * fetched from Kerberos. The request id (called the "authenticator" + * in the papers on Kerberos) contains the following: + * + * req_id->dat + * + * string cr.pname {name, instance, and + * string cr.pinst realm of principal + * string myrealm making this request} + * 4 bytes checksum checksum argument given + * unsigned char tv_local.tf_usec time (milliseconds) + * 4 bytes tv_local.tv_sec time (seconds) + * + * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time, + * all rounded up to multiple of 8. + */ + +krb_mk_req(authent,service,instance,realm,checksum) + register KTEXT authent; /* Place to build the authenticator */ + char *service; /* Name of the service */ + char *instance; /* Service instance */ + char *realm; /* Authentication domain of service */ + long checksum; /* Checksum of data (optional) */ +{ + static KTEXT_ST req_st; /* Temp storage for req id */ + register KTEXT req_id = &req_st; + unsigned char *v = authent->dat; /* Prot version number */ + unsigned char *t = (authent->dat+1); /* Message type */ + unsigned char *kv = (authent->dat+2); /* Key version no */ + unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */ + unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */ + CREDENTIALS cr; /* Credentials used by retr */ + register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */ + int retval; /* Returned by krb_get_cred */ + static Key_schedule key_s; + char myrealm[REALM_SZ]; + + /* The fixed parts of the authenticator */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_APPL_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Get the ticket and move it into the authenticator */ + if (krb_ap_req_debug) + printf("Realm: %s\n",realm); + /* + * Determine realm of these tickets. We will send this to the + * KDC from which we are requesting tickets so it knows what to + * with our session key. + */ + if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS) + return(retval); + + retval = krb_get_cred(service,instance,realm,&cr); + + if (retval == RET_NOTKT) { + if (retval = get_ad_tkt(service,instance,realm,lifetime)) + return(retval); + if (retval = krb_get_cred(service,instance,realm,&cr)) + return(retval); + } + + if (retval != KSUCCESS) return (retval); + + if (krb_ap_req_debug) + printf("%s %s %s %s %s\n", service, instance, realm, + cr.pname, cr.pinst); + *kv = (unsigned char) cr.kvno; + (void) strcpy((char *)(authent->dat+3),realm); + *tl = (unsigned char) ticket->length; + bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)), + ticket->length); + authent->length = 6 + strlen(realm) + ticket->length; + if (krb_ap_req_debug) + printf("Ticket->length = %d\n",ticket->length); + if (krb_ap_req_debug) + printf("Issue date: %d\n",cr.issue_date); + + /* Build request id */ + (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */ + req_id->length = strlen(cr.pname)+1; + /* Principal's instance */ + (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst); + req_id->length += strlen(cr.pinst)+1; + /* Authentication domain */ + (void) strcpy((char *)(req_id->dat+req_id->length),myrealm); + req_id->length += strlen(myrealm)+1; + /* Checksum */ + bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4); + req_id->length += 4; + + /* Fill in the times on the request id */ + (void) gettimeofday(&tv_local,(struct timezone *) 0); + *(req_id->dat+(req_id->length)++) = + (unsigned char) tv_local.tv_usec; + /* Time (coarse) */ + bcopy((char *)&(tv_local.tv_sec), + (char *)(req_id->dat+req_id->length), 4); + req_id->length += 4; + + /* Fill to a multiple of 8 bytes for DES */ + req_id->length = ((req_id->length+7)/8)*8; + +#ifndef NOENCRYPTION + key_sched(cr.session,key_s); + pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat, + (long)req_id->length,key_s,cr.session,ENCRYPT); + bzero((char *) key_s, sizeof(key_s)); +#endif /* NOENCRYPTION */ + + /* Copy it into the authenticator */ + bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length), + req_id->length); + authent->length += req_id->length; + /* And set the id length */ + *idl = (unsigned char) req_id->length; + /* clean up */ + bzero((char *)req_id, sizeof(*req_id)); + + if (krb_ap_req_debug) + printf("Authent->length = %d\n",authent->length); + if (krb_ap_req_debug) + printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl); + + return(KSUCCESS); +} + +/* + * krb_set_lifetime sets the default lifetime for additional tickets + * obtained via krb_mk_req(). + * + * It returns the previous value of the default lifetime. + */ + +int +krb_set_lifetime(newval) +int newval; +{ + int olife = lifetime; + + lifetime = newval; + return(olife); +} diff --git a/eBones/lib/libkrb/mk_safe.c b/eBones/lib/libkrb/mk_safe.c new file mode 100644 index 0000000..567004b --- /dev/null +++ b/eBones/lib/libkrb/mk_safe.c @@ -0,0 +1,168 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine constructs a Kerberos 'safe msg', i.e. authenticated + * using a private session key to seed a checksum. Msg is NOT + * encrypted. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT + * + * Returns either <0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + * + * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $ + * $Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static u_long cksum; +static C_Block big_cksum[2]; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some + * user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address, followed by a checksum computed on the above, using the + * given "key". The length of the resulting packet is returned. + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_SAFE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * ===================== begin checksum ================================ + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * ======================= end checksum ================================ + * + * 16 bytes big_cksum quadratic checksum of + * above using "key" + */ + +long krb_mk_safe(in,out,length,key,sender,receiver) + u_char *in; /* application data */ + u_char *out; /* + * put msg here, leave room for header! + * breaks if in and out (header stuff) + * overlap + */ + u_long length; /* of in data */ + C_Block *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = KRB_PROT_VERSION; + *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER; + + q = p; /* start for checksum stuff */ + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + + /* make all the stuff contiguous for checksum */ + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *) &sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok until + * 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* + * all that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + +#ifdef NOENCRYPTION + cksum = 0; + bzero(big_cksum, sizeof(big_cksum)); +#else + cksum=quad_cksum(q,big_cksum,p-q,2,key); +#endif + if (krb_debug) + printf("\ncksum = %u",cksum); + + /* stuff checksum */ + bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum)); + p += sizeof(big_cksum); + + return ((long)(p - out)); /* resulting size */ + +} diff --git a/eBones/lib/libkrb/month_sname.c b/eBones/lib/libkrb/month_sname.c new file mode 100644 index 0000000..e7a63ec --- /dev/null +++ b/eBones/lib/libkrb/month_sname.c @@ -0,0 +1,31 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $ + * $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $"; +#endif /* lint */ + + +/* + * Given an integer 1-12, month_sname() returns a string + * containing the first three letters of the corresponding + * month. Returns 0 if the argument is out of range. + */ + +char *month_sname(n) + int n; +{ + static char *name[] = { + "Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec" + }; + return((n < 1 || n > 12) ? 0 : name [n-1]); +} diff --git a/eBones/lib/libkrb/netread.c b/eBones/lib/libkrb/netread.c new file mode 100644 index 0000000..eb86327 --- /dev/null +++ b/eBones/lib/libkrb/netread.c @@ -0,0 +1,46 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $ + * $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $"; +#endif lint + +/* + * krb_net_read() reads from the file descriptor "fd" to the buffer + * "buf", until either 1) "len" bytes have been read or 2) cannot + * read anymore from "fd". It returns the number of bytes read + * or a read() error. (The calling interface is identical to + * read(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_read(fd, buf, len) +int fd; +register char *buf; +register int len; +{ + int cc, len2 = 0; + + do { + cc = read(fd, buf, len); + if (cc < 0) + return(cc); /* errno is already set */ + else if (cc == 0) { + return(len2); + } else { + buf += cc; + len2 += cc; + len -= cc; + } + } while (len > 0); + return(len2); +} diff --git a/eBones/lib/libkrb/netwrite.c b/eBones/lib/libkrb/netwrite.c new file mode 100644 index 0000000..5945ce0 --- /dev/null +++ b/eBones/lib/libkrb/netwrite.c @@ -0,0 +1,42 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $"; + * $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $"; +#endif lint + +/* + * krb_net_write() writes "len" bytes from "buf" to the file + * descriptor "fd". It returns the number of bytes written or + * a write() error. (The calling interface is identical to + * write(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_write(fd, buf, len) +int fd; +register char *buf; +int len; +{ + int cc; + register int wrlen = len; + do { + cc = write(fd, buf, wrlen); + if (cc < 0) + return(cc); + else { + buf += cc; + wrlen -= cc; + } + } while (wrlen > 0); + return(len); +} diff --git a/eBones/lib/libkrb/one.c b/eBones/lib/libkrb/one.c new file mode 100644 index 0000000..c0e8bc6 --- /dev/null +++ b/eBones/lib/libkrb/one.c @@ -0,0 +1,20 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $ + * $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $"; +#endif lint + +/* + * definition of variable set to 1. + * used in krb_conf.h to determine host byte order. + */ + +int krbONE = 1; diff --git a/eBones/lib/libkrb/pkt_cipher.c b/eBones/lib/libkrb/pkt_cipher.c new file mode 100644 index 0000000..6ef870c --- /dev/null +++ b/eBones/lib/libkrb/pkt_cipher.c @@ -0,0 +1,38 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $ + * $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + + +/* + * This routine takes a reply packet from the Kerberos ticket-granting + * service and returns a pointer to the beginning of the ciphertext in it. + * + * See "prot.h" for packet format. + */ + +KTEXT +pkt_cipher(packet) + KTEXT packet; +{ + unsigned char *ptr = pkt_a_realm(packet) + 6 + + strlen((char *)pkt_a_realm(packet)); + /* Skip a few more fields */ + ptr += 3 + 4; /* add 4 for exp_date */ + + /* And return the pointer */ + return((KTEXT) ptr); +} diff --git a/eBones/lib/libkrb/pkt_clen.c b/eBones/lib/libkrb/pkt_clen.c new file mode 100644 index 0000000..23ad4c3 --- /dev/null +++ b/eBones/lib/libkrb/pkt_clen.c @@ -0,0 +1,53 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $ + * $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +extern int krb_debug; +extern int swap_bytes; + +/* + * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of + * its ciphertext portion. The external variable "swap_bytes" is assumed + * to have been set to indicate whether or not the packet is in local + * byte order. pkt_clen() takes this into account when reading the + * ciphertext length out of the packet. + */ + +pkt_clen(pkt) + KTEXT pkt; +{ + static unsigned short temp,temp2; + int clen = 0; + + /* Start of ticket list */ + unsigned char *ptr = pkt_a_realm(pkt) + 10 + + strlen((char *)pkt_a_realm(pkt)); + + /* Finally the length */ + bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */ + if (swap_bytes) { + /* assume a short is 2 bytes?? */ + swab((char *)&temp,(char *)&temp2,2); + temp = temp2; + } + + clen = (int) temp; + + if (krb_debug) + printf("Clen is %d\n",clen); + return(clen); +} diff --git a/eBones/lib/libkrb/rd_err.c b/eBones/lib/libkrb/rd_err.c new file mode 100644 index 0000000..e73c47b --- /dev/null +++ b/eBones/lib/libkrb/rd_err.c @@ -0,0 +1,79 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'safe msg', + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $ + * $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <krb.h> +#include <prot.h> + +/* + * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length", + * return the error code from the message in "code" and the text in + * "m_data" as follows: + * + * m_data->app_data points to the error text + * m_data->app_length points to the length of the error text + * + * If all goes well, return RD_AP_OK. If the version number + * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR + * type message, return RD_AP_MSG_TYPE. + * + * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c + */ + +int +krb_rd_err(in,in_length,code,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* of in msg */ + long *code; /* received error code */ + MSG_DAT *m_data; +{ + register u_char *p; + int swap_bytes = 0; + p = in; /* beginning of message */ + + if (*p++ != KRB_PROT_VERSION) + return(RD_AP_VERSION); + if (((*p) & ~1) != AUTH_MSG_APPL_ERR) + return(RD_AP_MSG_TYPE); + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* safely get code */ + bcopy((char *)p,(char *)code,sizeof(*code)); + if (swap_bytes) + swap_u_long(*code); + p += sizeof(*code); /* skip over */ + + m_data->app_data = p; /* we're now at the error text + * message */ + m_data->app_length = in_length; + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/eBones/lib/libkrb/rd_priv.c b/eBones/lib/libkrb/rd_priv.c new file mode 100644 index 0000000..9adefec --- /dev/null +++ b/eBones/lib/libkrb/rd_priv.c @@ -0,0 +1,204 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'private msg', decrypting it, + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If + * the return value is RD_AP_TIME, then either the times are too far + * out of synch, OR the packet was modified. + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $ + * $Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[]= +"$Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static u_long c_length; +static int swap_bytes; +static struct timeval local_time; +static long delta_t; +int private_msg_ver = KRB_PROT_VERSION; + +/* +#ifdef NOENCRPYTION + * krb_rd_priv() checks the integrity of an +#else + * krb_rd_priv() decrypts and checks the integrity of an +#endif + * AUTH_MSG_PRIVATE message. Given the message received, "in", + * the length of that message, "in_length", the key "schedule" + * and "key", and the network addresses of the + * "sender" and "receiver" of the message, krb_rd_safe() returns + * RD_AP_OK if the message is okay, otherwise some error code. + * + * The message data retrieved from "in" are returned in the structure + * "m_data". The pointer to the application data + * (m_data->app_data) refers back to the appropriate place in "in". + * + * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* length of "in" msg */ + Key_schedule schedule; /* precomputed key schedule */ + C_Block key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; + struct sockaddr_in *receiver; + MSG_DAT *m_data; /*various input/output data from msg */ +{ + register u_char *p,*q; + static u_long src_addr; /* Can't send structs since no + * guarantees on size */ + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION && *(p-1) != 3) + return RD_AP_VERSION; + private_msg_ver = *(p-1); + if (((*p) & ~1) != AUTH_MSG_PRIVATE) + return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* get cipher length */ + bcopy((char *)p,(char *)&c_length,sizeof(c_length)); + if (swap_bytes) + swap_u_long(c_length); + p += sizeof(c_length); + /* check for rational length so we don't go comatose */ + if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length) + return RD_AP_MODIFIED; + + + q = p; /* mark start of encrypted stuff */ + +#ifndef NOENCRYPTION + pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT); +#endif + + /* safely get application data length */ + bcopy((char *) p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) + swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(c_length) + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ + > in_length) + return RD_AP_MODIFIED; + +#ifndef NOENCRYPTION + /* we're now at the decrypted application data */ +#endif + m_data->app_data = p; + + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *) p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *) p,(char *)&src_addr,sizeof(src_addr)); + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (src_addr != (u_long) sender->sin_addr.s_addr) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *) p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) swap_u_long(m_data->time_sec); + + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + /* + * all that for one tiny bit! + * Heaven help those that talk to themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec + - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) + return RD_AP_TIME; + if (krb_debug) + printf("\ndelta_t = %d",delta_t); + + /* + * caller must check timestamps for proper order and + * replays, since server might have multiple clients + * each with its own timestamps and we don't assume + * tightly synchronized clocks. + */ + +#ifdef notdef + bcopy((char *) p,(char *)&cksum,sizeof(cksum)); + if (swap_bytes) swap_u_long(cksum) + /* + * calculate the checksum of the length, sequence, + * and input data, on the sending byte order!! + */ + calc_cksum = quad_cksum(q,NULL,p-q,0,key); + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + calc_cksum, cksum); + if (cksum != calc_cksum) + return RD_AP_MODIFIED; +#endif + return RD_AP_OK; /* OK == 0 */ +} diff --git a/eBones/lib/libkrb/rd_req.c b/eBones/lib/libkrb/rd_req.c new file mode 100644 index 0000000..22b6540 --- /dev/null +++ b/eBones/lib/libkrb/rd_req.c @@ -0,0 +1,328 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $ + * $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $"; +#endif /* lint */ + +#include <des.h> +#include <krb.h> +#include <prot.h> +#include <sys/time.h> +#include <strings.h> + +extern int krb_ap_req_debug; + +static struct timeval t_local = { 0, 0 }; + +/* + * Keep the following information around for subsequent calls + * to this routine by the same server using the same key. + */ + +static Key_schedule serv_key; /* Key sched to decrypt ticket */ +static C_Block ky; /* Initialization vector */ +static int st_kvno; /* version number for this key */ +static char st_rlm[REALM_SZ]; /* server's realm */ +static char st_nam[ANAME_SZ]; /* service name */ +static char st_inst[INST_SZ]; /* server's instance */ + +/* + * This file contains two functions. krb_set_key() takes a DES + * key or password string and returns a DES key (either the original + * key, or the password converted into a DES key) and a key schedule + * for it. + * + * krb_rd_req() reads an authentication request and returns information + * about the identity of the requestor, or an indication that the + * identity information was not authentic. + */ + +/* + * krb_set_key() takes as its first argument either a DES key or a + * password string. The "cvt" argument indicates how the first + * argument "key" is to be interpreted: if "cvt" is null, "key" is + * taken to be a DES key; if "cvt" is non-null, "key" is taken to + * be a password string, and is converted into a DES key using + * string_to_key(). In either case, the resulting key is returned + * in the external static variable "ky". A key schedule is + * generated for "ky" and returned in the external static variable + * "serv_key". + * + * This routine returns the return value of des_key_sched. + * + * krb_set_key() needs to be in the same .o file as krb_rd_req() so that + * the key set by krb_set_key() is available in private storage for + * krb_rd_req(). + */ + +int +krb_set_key(key,cvt) + char *key; + int cvt; +{ +#ifdef NOENCRYPTION + bzero(ky, sizeof(ky)); + return KSUCCESS; +#else + if (cvt) + string_to_key(key,ky); + else + bcopy(key,(char *)ky,8); + return(des_key_sched(ky,serv_key)); +#endif +} + + +/* + * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or + * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), + * checks its integrity and returns a judgement as to the requestor's + * identity. + * + * The "authent" argument is a pointer to the received message. + * The "service" and "instance" arguments name the receiving server, + * and are used to get the service's ticket to decrypt the ticket + * in the message, and to compare against the server name inside the + * ticket. "from_addr" is the network address of the host from which + * the message was received; this is checked against the network + * address in the ticket. If "from_addr" is zero, the check is not + * performed. "ad" is an AUTH_DAT structure which is + * filled in with information about the sender's identity according + * to the authenticator and ticket sent in the message. Finally, + * "fn" contains the name of the file containing the server's key. + * (If "fn" is NULL, the server's key is assumed to have been set + * by krb_set_key(). If "fn" is the null string ("") the default + * file KEYFILE, defined in "krb.h", is used.) + * + * krb_rd_req() returns RD_AP_OK if the authentication information + * was genuine, or one of the following error codes (defined in + * "krb.h"): + * + * RD_AP_VERSION - wrong protocol version number + * RD_AP_MSG_TYPE - wrong message type + * RD_AP_UNDEC - couldn't decipher the message + * RD_AP_INCON - inconsistencies found + * RD_AP_BADD - wrong network address + * RD_AP_TIME - client time (in authenticator) + * too far off server time + * RD_AP_NYV - Kerberos time (in ticket) too + * far off server time + * RD_AP_EXP - ticket expired + * + * For the message format, see krb_mk_req(). + * + * Mutual authentication is not implemented. + */ + +krb_rd_req(authent,service,instance,from_addr,ad,fn) + register KTEXT authent; /* The received message */ + char *service; /* Service name */ + char *instance; /* Service instance */ + long from_addr; /* Net address of originating host */ + AUTH_DAT *ad; /* Structure to be filled in */ + char *fn; /* Filename to get keys from */ +{ + static KTEXT_ST ticket; /* Temp storage for ticket */ + static KTEXT tkt = &ticket; + static KTEXT_ST req_id_st; /* Temp storage for authenticator */ + register KTEXT req_id = &req_id_st; + + char realm[REALM_SZ]; /* Realm of issuing kerberos */ + static Key_schedule seskey_sched; /* Key sched for session key */ + unsigned char skey[KKEY_SZ]; /* Session key from ticket */ + char sname[SNAME_SZ]; /* Service name from ticket */ + char iname[INST_SZ]; /* Instance name from ticket */ + char r_aname[ANAME_SZ]; /* Client name from authenticator */ + char r_inst[INST_SZ]; /* Client instance from authenticator */ + char r_realm[REALM_SZ]; /* Client realm from authenticator */ + unsigned int r_time_ms; /* Fine time from authenticator */ + unsigned long r_time_sec; /* Coarse time from authenticator */ + register char *ptr; /* For stepping through */ + unsigned long delta_t; /* Time in authenticator - local time */ + long tkt_age; /* Age of ticket */ + static int swap_bytes; /* Need to swap bytes? */ + static int mutual; /* Mutual authentication requested? */ + static unsigned char s_kvno;/* Version number of the server's key + * Kerberos used to encrypt ticket */ + int status; + + if (authent->length <= 0) + return(RD_AP_MODIFIED); + + ptr = (char *) authent->dat; + + /* get msg version, type and byte order, and server key version */ + + /* check version */ + if (KRB_PROT_VERSION != (unsigned int) *ptr++) + return(RD_AP_VERSION); + + /* byte order */ + swap_bytes = 0; + if ((*ptr & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* check msg type */ + mutual = 0; + switch (*ptr++ & ~1) { + case AUTH_MSG_APPL_REQUEST: + break; + case AUTH_MSG_APPL_REQUEST_MUTUAL: + mutual++; + break; + default: + return(RD_AP_MSG_TYPE); + } + +#ifdef lint + /* XXX mutual is set but not used; why??? */ + /* this is a crock to get lint to shut up */ + if (mutual) + mutual = 0; +#endif /* lint */ + s_kvno = *ptr++; /* get server key version */ + (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */ + ptr += strlen(ptr) + 1; /* skip the realm "hint" */ + + /* + * If "fn" is NULL, key info should already be set; don't + * bother with ticket file. Otherwise, check to see if we + * already have key info for the given server and key version + * (saved in the static st_* variables). If not, go get it + * from the ticket file. If "fn" is the null string, use the + * default ticket file. + */ + if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) || + strcmp(st_rlm,realm) || (st_kvno != s_kvno))) { + if (*fn == 0) fn = KEYFILE; + st_kvno = s_kvno; +#ifndef NOENCRYPTION + if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey)) + return(RD_AP_UNDEC); + if (status=krb_set_key((char *)skey,0)) return(status); +#endif + (void) strcpy(st_rlm,realm); + (void) strcpy(st_nam,service); + (void) strcpy(st_inst,instance); + } + + /* Get ticket from authenticator */ + tkt->length = (int) *ptr++; + if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr+1,(char *)(tkt->dat),tkt->length); + + if (krb_ap_req_debug) + log("ticket->length: %d",tkt->length); + +#ifndef NOENCRYPTION + /* Decrypt and take apart ticket */ +#endif + + if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, + &(ad->address),ad->session, &(ad->life), + &(ad->time_sec),sname,iname,ky,serv_key)) + return(RD_AP_UNDEC); + + if (krb_ap_req_debug) { + log("Ticket Contents."); + log(" Aname: %s.%s",ad->pname, + ((int)*(ad->prealm) ? ad->prealm : "Athena")); + log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname); + } + + /* Extract the authenticator */ + req_id->length = (int) *(ptr++); + if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) > + authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length); + +#ifndef NOENCRYPTION + key_sched(ad->session,seskey_sched); + pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat, + (long)req_id->length,seskey_sched,ad->session,DES_DECRYPT); +#endif /* NOENCRYPTION */ + +#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); + + ptr = (char *) req_id->dat; + (void) strcpy(r_aname,ptr); /* Authentication name */ + ptr += strlen(r_aname)+1; + check_ptr(); + (void) strcpy(r_inst,ptr); /* Authentication instance */ + ptr += strlen(r_inst)+1; + check_ptr(); + (void) strcpy(r_realm,ptr); /* Authentication name */ + ptr += strlen(r_realm)+1; + check_ptr(); + bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */ + ptr += 4; + check_ptr(); + if (swap_bytes) swap_u_long(ad->checksum); + r_time_ms = *(ptr++); /* Time (fine) */ +#ifdef lint + /* XXX r_time_ms is set but not used. why??? */ + /* this is a crock to get lint to shut up */ + if (r_time_ms) + r_time_ms = 0; +#endif /* lint */ + check_ptr(); + /* assume sizeof(r_time_sec) == 4 ?? */ + bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(r_time_sec); + + /* Check for authenticity of the request */ + if (krb_ap_req_debug) + log("Pname: %s %s",ad->pname,r_aname); + if (strcmp(ad->pname,r_aname) != 0) + return(RD_AP_INCON); + if (strcmp(ad->pinst,r_inst) != 0) + return(RD_AP_INCON); + if (krb_ap_req_debug) + log("Realm: %s %s",ad->prealm,r_realm); + if ((strcmp(ad->prealm,r_realm) != 0)) + return(RD_AP_INCON); + + if (krb_ap_req_debug) + log("Address: %d %d",ad->address,from_addr); + if (from_addr && (ad->address != from_addr)) + return(RD_AP_BADD); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + delta_t = abs((int)(t_local.tv_sec - r_time_sec)); + if (delta_t > CLOCK_SKEW) { + if (krb_ap_req_debug) + log("Time out of range: %d - %d = %d", + t_local.tv_sec,r_time_sec,delta_t); + return(RD_AP_TIME); + } + + /* Now check for expiration of ticket */ + + tkt_age = t_local.tv_sec - ad->time_sec; + if (krb_ap_req_debug) + log("Time: %d Issue Date: %d Diff: %d Life %x", + t_local.tv_sec,ad->time_sec,tkt_age,ad->life); + + if (t_local.tv_sec < ad->time_sec) { + if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW) + return(RD_AP_NYV); + } + else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life) + return(RD_AP_EXP); + + /* All seems OK */ + ad->reply.length = 0; + + return(RD_AP_OK); +} diff --git a/eBones/lib/libkrb/rd_safe.c b/eBones/lib/libkrb/rd_safe.c new file mode 100644 index 0000000..e500b4d --- /dev/null +++ b/eBones/lib/libkrb/rd_safe.c @@ -0,0 +1,180 @@ +/* + * Copyright 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine dissects a a Kerberos 'safe msg', checking its + * integrity, and returning a pointer to the application data + * contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + * + * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $ + * $Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $"; +#endif /* lint */ + +/* system include files */ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/time.h> + +/* application include files */ +#include <des.h> +#include <krb.h> +#include <prot.h> +#include "lsb_addr_comp.h" + +extern char *errmsg(); +extern int errno; +extern int krb_debug; + +/* static storage */ + +static C_Block calc_cksum[2]; +static C_Block big_cksum[2]; +static int swap_bytes; +static struct timeval local_time; +static u_long delta_t; + +/* + * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message. + * Given the message received, "in", the length of that message, + * "in_length", the "key" to compute the checksum with, and the + * network addresses of the "sender" and "receiver" of the message, + * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise + * some error code. + * + * The message data retrieved from "in" is returned in the structure + * "m_data". The pointer to the application data (m_data->app_data) + * refers back to the appropriate place in "in". + * + * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +long krb_rd_safe(in,in_length,key,sender,receiver,m_data) + u_char *in; /* pointer to the msg received */ + u_long in_length; /* length of "in" msg */ + C_Block *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender's address */ + struct sockaddr_in *receiver; /* receiver's address -- me */ + MSG_DAT *m_data; /* where to put message information */ +{ + register u_char *p,*q; + static u_long src_addr; /* Can't send structs since no + * guarantees on size */ + /* Be very conservative */ + if (sizeof(u_long) != sizeof(struct in_addr)) { + fprintf(stderr,"\n\ +krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)"); + exit(-1); + } + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION; + if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++; + + q = p; /* mark start of cksum stuff */ + + /* safely get length */ + bcopy((char *)p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(big_cksum) + sizeof(src_addr) + + VERSION_SZ + MSG_TYPE_SZ > in_length) + return(RD_AP_MODIFIED); + + m_data->app_data = p; /* we're now at the application data */ + + /* skip app data */ + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *)p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *)p,(char *)&src_addr,sizeof(src_addr)); + + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (src_addr != (u_long) sender->sin_addr.s_addr) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *)p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) + swap_u_long(m_data->time_sec); + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) return RD_AP_TIME; + + /* + * caller must check timestamps for proper order and replays, since + * server might have multiple clients each with its own timestamps + * and we don't assume tightly synchronized clocks. + */ + + bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum)); + if (swap_bytes) swap_u_16(big_cksum); + +#ifdef NOENCRYPTION + bzero(calc_cksum, sizeof(calc_cksum)); +#else + quad_cksum(q,calc_cksum,p-q,2,key); +#endif + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + (long) calc_cksum[0], (long) big_cksum[0]); + if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum))) + return(RD_AP_MODIFIED); + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/eBones/lib/libkrb/read_service_key.c b/eBones/lib/libkrb/read_service_key.c new file mode 100644 index 0000000..4d66710 --- /dev/null +++ b/eBones/lib/libkrb/read_service_key.c @@ -0,0 +1,120 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $ + * $Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $"; +#endif /* lint */ + +#include <krb.h> +#include <stdio.h> +#include <strings.h> + +/* + * The private keys for servers on a given host are stored in a + * "srvtab" file (typically "/etc/srvtab"). This routine extracts + * a given server's key from the file. + * + * read_service_key() takes the server's name ("service"), "instance", + * and "realm" and a key version number "kvno", and looks in the given + * "file" for the corresponding entry, and if found, returns the entry's + * key field in "key". + * + * If "instance" contains the string "*", then it will match + * any instance, and the chosen instance will be copied to that + * string. For this reason it is important that the there is enough + * space beyond the "*" to receive the entry. + * + * If "kvno" is 0, it is treated as a wild card and the first + * matching entry regardless of the "vno" field is returned. + * + * This routine returns KSUCCESS on success, otherwise KFAILURE. + * + * The format of each "srvtab" entry is as follows: + * + * Size Variable Field in file + * ---- -------- ------------- + * string serv server name + * string inst server instance + * string realm server realm + * 1 byte vno server key version # + * 8 bytes key server's key + * ... ... ... + */ + + +/*ARGSUSED */ +read_service_key(service,instance,realm,kvno,file,key) + char *service; /* Service Name */ + char *instance; /* Instance name or "*" */ + char *realm; /* Realm */ + int kvno; /* Key version number */ + char *file; /* Filename */ + char *key; /* Pointer to key to be filled in */ +{ + char serv[SNAME_SZ]; + char inst[INST_SZ]; + char rlm[REALM_SZ]; + unsigned char vno; /* Key version number */ + int wcard; + + int stab, open(); + + if ((stab = open(file, 0, 0)) < NULL) + return(KFAILURE); + + wcard = (instance[0] == '*') && (instance[1] == '\0'); + + while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */ + (void) getst(stab,inst,INST_SZ); /* Instance */ + (void) getst(stab,rlm,REALM_SZ); /* Realm */ + /* Vers number */ + if (read(stab,(char *)&vno,1) != 1) { + close(stab); + return(KFAILURE); + } + /* Key */ + if (read(stab,key,8) != 8) { + close(stab); + return(KFAILURE); + } + /* Is this the right service */ + if (strcmp(serv,service)) + continue; + /* How about instance */ + if (!wcard && strcmp(inst,instance)) + continue; + if (wcard) + (void) strncpy(instance,inst,INST_SZ); + /* Is this the right realm */ +#ifdef ATHENA_COMPAT + /* XXX For backward compatibility: if keyfile says "Athena" + and caller wants "ATHENA.MIT.EDU", call it a match */ + if (strcmp(rlm,realm) && + (strcmp(rlm,"Athena") || + strcmp(realm,"ATHENA.MIT.EDU"))) + continue; +#else /* ! ATHENA_COMPAT */ + if (strcmp(rlm,realm)) + continue; +#endif /* ATHENA_COMPAT */ + + /* How about the key version number */ + if (kvno && kvno != (int) vno) + continue; + + (void) close(stab); + return(KSUCCESS); + } + + /* Can't find the requested service */ + (void) close(stab); + return(KFAILURE); +} diff --git a/eBones/lib/libkrb/recvauth.c b/eBones/lib/libkrb/recvauth.c new file mode 100644 index 0000000..fe26814 --- /dev/null +++ b/eBones/lib/libkrb/recvauth.c @@ -0,0 +1,286 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $"; + * $Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> + + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN + chars */ + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_sendauth.c + * be sure to support old versions of krb_sendauth! + */ + +extern int errno; + +/* + * krb_recvauth() reads (and optionally responds to) a message sent + * using krb_sendauth(). The "options" argument is a bit-field of + * selected options (see "sendauth.c" for options description). + * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL + * (mutual authentication requested). The "fd" argument supplies + * a file descriptor to read from (and write to, if mutual authenti- + * cation is requested). + * + * Part of the received message will be a Kerberos ticket sent by the + * client; this is read into the "ticket" argument. The "service" and + * "instance" arguments supply the server's Kerberos name. If the + * "instance" argument is the string "*", it is treated as a wild card + * and filled in during the krb_rd_req() call (see read_service_key()). + * + * The "faddr" and "laddr" give the sending (client) and receiving + * (local server) network addresses. ("laddr" may be left NULL unless + * mutual authentication is requested, in which case it must be set.) + * + * The authentication information extracted from the message is returned + * in "kdata". The "filename" argument indicates the file where the + * server's key can be found. (It is passed on to krb_rd_req().) If + * left null, the default "/etc/srvtab" will be used. + * + * If mutual authentication is requested, the session key schedule must + * be computed in order to reply; this schedule is returned in the + * "schedule" argument. A string containing the application version + * number from the received message is returned in "version", which + * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. + * + * See krb_sendauth() for the format of the received client message. + * + * This routine supports another client format, for backward + * compatibility, consisting of: + * + * Size Variable Field + * ---- -------- ----- + * + * string tmp_buf, tkt_len length of ticket, in + * ascii + * + * char ' ' (space char) separator + * + * tkt_len ticket->dat the ticket + * + * This old-style version does not support mutual authentication. + * + * krb_recvauth() first reads the protocol version string from the + * given file descriptor. If it doesn't match the current protocol + * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In + * that case, the string of characters up to the first space is read + * and interpreted as the ticket length, then the ticket is read. + * + * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() + * next reads the application protocol version string. Then the + * ticket length and ticket itself are read. + * + * The ticket is decrypted and checked by the call to krb_rd_req(). + * If no mutual authentication is required, the result of the + * krb_rd_req() call is retured by this routine. If mutual authenti- + * cation is required, a message in the following format is returned + * on "fd": + * + * Size Variable Field + * ---- -------- ----- + * + * 4 bytes tkt_len length of ticket or -1 + * if error occurred + * + * priv_len tmp_buf "private" message created + * by krb_mk_priv() which + * contains the incremented + * checksum sent by the client + * encrypted in the session + * key. (This field is not + * present in case of error.) + * + * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some + * other error code is returned. + */ + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif /* max */ + +int +krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, + filename, schedule, version) +long options; /* bit-pattern of options */ +int fd; /* file descr. to read from */ +KTEXT ticket; /* storage for client's ticket */ +char *service; /* service expected */ +char *instance; /* inst expected (may be filled in) */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +struct sockaddr_in *laddr; /* local address */ +AUTH_DAT *kdata; /* kerberos data (returned) */ +char *filename; /* name of file with service keys */ +Key_schedule schedule; /* key schedule (return) */ +char *version; /* version string (filled in) */ +{ + + int i, cc, old_vers = 0; + char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ + char *cp; + int rem; + long tkt_len, priv_len; + u_long cksum; + u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)]; + + /* read the protocol version number */ + if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + krb_vers[KRB_SENDAUTH_VLEN] = '\0'; + + /* check version string */ + if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) { + /* Assume the old version of sendkerberosdata: send ascii + length, ' ', and ticket. */ + if (options & KOPT_DO_MUTUAL) + return(KFAILURE); /* XXX can't do old style with mutual auth */ + old_vers = 1; + + /* copy what we have read into tmp_buf */ + (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN); + + /* search for space, and make it a null */ + for (i = 0; i < KRB_SENDAUTH_VLEN; i++) + if (tmp_buf[i]== ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + + if (i == KRB_SENDAUTH_VLEN) + /* didn't find the space, keep reading to find it */ + for (; i<20; i++) { + if (read(fd, (char *)&tmp_buf[i], 1) != 1) { + return(KFAILURE); + } + if (tmp_buf[i] == ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + } + + tkt_len = (long) atoi((char *) tmp_buf); + + /* sanity check the length */ + if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN)) + return(KFAILURE); + + if (i < KRB_SENDAUTH_VLEN) { + /* since we already got the space, and part of the ticket, + we read fewer bytes to get the rest of the ticket */ + if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), + (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + return(errno); + } else { + if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != + (int) tkt_len) + return(errno); + } + ticket->length = tkt_len; + /* copy the ticket into the struct */ + (void) bcopy(cp, (char *) ticket->dat, ticket->length); + + } else { + /* read the application version string */ + if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + version[KRB_SENDAUTH_VLEN] = '\0'; + + /* get the length of the ticket */ + if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + + /* sanity check */ + ticket->length = ntohl((unsigned long)tkt_len); + if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) { + if (options & KOPT_DO_MUTUAL) { + rem = KFAILURE; + goto mutual_fail; + } else + return(KFAILURE); /* XXX there may still be junk on the fd? */ + } + + /* read the ticket */ + if (krb_net_read(fd, (char *) ticket->dat, ticket->length) + != ticket->length) + return(errno); + } + /* + * now have the ticket. decrypt it to get the authenticated + * data. + */ + rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr, + kdata,filename); + + if (old_vers) return(rem); /* XXX can't do mutual with old client */ + + /* if we are doing mutual auth, compose a response */ + if (options & KOPT_DO_MUTUAL) { + if (rem != KSUCCESS) + /* the krb_rd_req failed */ + goto mutual_fail; + + /* add one to the (formerly) sealed checksum, and re-seal it + for return to the client */ + cksum = kdata->checksum + 1; + cksum = htonl(cksum); +#ifndef NOENCRYPTION + key_sched(kdata->session,schedule); +#endif + priv_len = krb_mk_priv((unsigned char *)&cksum, + tmp_buf, + (unsigned long) sizeof(cksum), + schedule, + kdata->session, + laddr, + faddr); + if (priv_len < 0) { + /* re-sealing failed; notify the client */ + rem = KFAILURE; /* XXX */ +mutual_fail: + priv_len = -1; + tkt_len = htonl((unsigned long) priv_len); + /* a length of -1 is interpreted as an authentication + failure by the client */ + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + return(rem); + } else { + /* re-sealing succeeded, send the private message */ + tkt_len = htonl((unsigned long)priv_len); + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len)) + != (int) priv_len) + return(cc); + } + } + return(rem); +} diff --git a/eBones/lib/libkrb/save_credentials.c b/eBones/lib/libkrb/save_credentials.c new file mode 100644 index 0000000..129c912 --- /dev/null +++ b/eBones/lib/libkrb/save_credentials.c @@ -0,0 +1,53 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $ + * $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <krb.h> + +/* + * This routine takes a ticket and associated info and calls + * tf_save_cred() to store them in the ticket cache. The peer + * routine for extracting a ticket and associated info from the + * ticket cache is krb_get_cred(). When changes are made to + * this routine, the corresponding changes should be made + * in krb_get_cred() as well. + * + * Returns KSUCCESS if all goes well, otherwise an error returned + * by the tf_init() or tf_save_cred() routines. + */ + +save_credentials(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + C_Block session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + long issue_date; /* The issue time */ +{ + int tf_status; /* return values of the tf_util calls */ + + /* Open and lock the ticket file for writing */ + if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Save credentials by appending to the ticket file */ + tf_status = tf_save_cred(service, instance, realm, session, + lifetime, kvno, ticket, issue_date); + (void) tf_close(); + return (tf_status); +} diff --git a/eBones/lib/libkrb/send_to_kdc.c b/eBones/lib/libkrb/send_to_kdc.c new file mode 100644 index 0000000..aeaf389 --- /dev/null +++ b/eBones/lib/libkrb/send_to_kdc.c @@ -0,0 +1,313 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $ + * $Id: send_to_kdc.c,v 1.2 1994/07/19 19:26:21 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid_send_to_kdc_c[] = +"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp "; +#endif /* lint */ + +#include <krb.h> +#include <prot.h> + +#include <stdio.h> +#include <errno.h> +#include <sys/time.h> +#include <sys/types.h> +#ifdef lint +#include <sys/uio.h> /* struct iovec to make lint happy */ +#endif /* lint */ +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <strings.h> + +#define S_AD_SZ sizeof(struct sockaddr_in) + +extern int errno; +extern int krb_debug; + +extern char *malloc(), *calloc(), *realloc(); + +int krb_udp_port = 0; + +/* CLIENT_KRB_TIMEOUT indicates the time to wait before + * retrying a server. It's defined in "krb.h". + */ +static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0}; +static char *prog = "send_to_kdc"; +static send_recv(); + +/* + * This file contains two routines, send_to_kdc() and send_recv(). + * send_recv() is a static routine used by send_to_kdc(). + */ + +/* + * send_to_kdc() sends a message to the Kerberos authentication + * server(s) in the given realm and returns the reply message. + * The "pkt" argument points to the message to be sent to Kerberos; + * the "rpkt" argument will be filled in with Kerberos' reply. + * The "realm" argument indicates the realm of the Kerberos server(s) + * to transact with. If the realm is null, the local realm is used. + * + * If more than one Kerberos server is known for a given realm, + * different servers will be queried until one of them replies. + * Several attempts (retries) are made for each server before + * giving up entirely. + * + * If an answer was received from a Kerberos host, KSUCCESS is + * returned. The following errors can be returned: + * + * SKDC_CANT - can't get local realm + * - can't find "kerberos" in /etc/services database + * - can't open socket + * - can't bind socket + * - all ports in use + * - couldn't find any Kerberos host + * + * SKDC_RETRY - couldn't get an answer from any Kerberos server, + * after several retries + */ + +send_to_kdc(pkt,rpkt,realm) + KTEXT pkt; + KTEXT rpkt; + char *realm; +{ + int i, f; + int no_host; /* was a kerberos host found? */ + int retry; + int n_hosts; + int retval; + struct sockaddr_in to; + struct hostent *host, *hostlist; + char *cp; + char krbhst[MAX_HSTNM]; + char lrealm[REALM_SZ]; + + /* + * If "realm" is non-null, use that, otherwise get the + * local realm. + */ + if (realm) + (void) strcpy(lrealm, realm); + else + if (krb_get_lrealm(lrealm,1)) { + if (krb_debug) + fprintf(stderr, "%s: can't get local realm\n", prog); + return(SKDC_CANT); + } + if (krb_debug) + printf("lrealm is %s\n", lrealm); + if (krb_udp_port == 0) { + register struct servent *sp; + if ((sp = getservbyname("kerberos","udp")) == 0) { + if (krb_debug) + fprintf(stderr, "%s: Can't get kerberos/udp service\n", + prog); + return(SKDC_CANT); + } + krb_udp_port = sp->s_port; + if (krb_debug) + printf("krb_udp_port is %d\n", krb_udp_port); + } + bzero((char *)&to, S_AD_SZ); + hostlist = (struct hostent *) malloc(sizeof(struct hostent)); + if (!hostlist) + return (/*errno */SKDC_CANT); + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if (krb_debug) + fprintf(stderr,"%s: Can't open socket\n", prog); + return(SKDC_CANT); + } + /* from now on, exit through rtn label for cleanup */ + + no_host = 1; + /* get an initial allocation */ + n_hosts = 0; + for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { + if (krb_debug) { + printf("Getting host entry for %s...",krbhst); + (void) fflush(stdout); + } + host = gethostbyname(krbhst); + if (krb_debug) { + printf("%s.\n", + host ? "Got it" : "Didn't get it"); + (void) fflush(stdout); + } + if (!host) + continue; + no_host = 0; /* found at least one */ + n_hosts++; + /* preserve host network address to check later + * (would be better to preserve *all* addresses, + * take care of that later) + */ + hostlist = (struct hostent *) + realloc((char *)hostlist, + (unsigned) + sizeof(struct hostent)*(n_hosts+1)); + if (!hostlist) + return /*errno */SKDC_CANT; + bcopy((char *)host, (char *)&hostlist[n_hosts-1], + sizeof(struct hostent)); + host = &hostlist[n_hosts-1]; + cp = malloc((unsigned)host->h_length); + if (!cp) { + retval = /*errno */SKDC_CANT; + goto rtn; + } + bcopy((char *)host->h_addr, cp, host->h_length); +/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2 + (or worse) only return one name ... */ +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + host->h_addr_list = (char **)malloc(sizeof(char *)); + if (!host->h_addr_list) { + retval = /*errno */SKDC_CANT; + goto rtn; + } +#endif /* ULTRIX022 || SunOS */ + host->h_addr = cp; + bzero((char *)&hostlist[n_hosts], + sizeof(struct hostent)); + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + to.sin_port = krb_udp_port; + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + if (krb_debug) { + printf("Timeout, error, or wrong descriptor\n"); + (void) fflush(stdout); + } + } + if (no_host) { + if (krb_debug) + fprintf(stderr, "%s: can't find any Kerberos host.\n", + prog); + retval = SKDC_CANT; + goto rtn; + } + /* retry each host in sequence */ + for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { + for (host = hostlist; host->h_name != (char *)NULL; host++) { + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + } + } + retval = SKDC_RETRY; +rtn: + (void) close(f); + if (hostlist) { + register struct hostent *hp; + for (hp = hostlist; hp->h_name; hp++) +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + if (hp->h_addr_list) { +#endif /* ULTRIX022 || SunOS */ + if (hp->h_addr) + free(hp->h_addr); +#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) + free((char *)hp->h_addr_list); + } +#endif /* ULTRIX022 || SunOS */ + free((char *)hostlist); + } + return(retval); +} + +/* + * try to send out and receive message. + * return 1 on success, 0 on failure + */ + +static send_recv(pkt,rpkt,f,_to,addrs) + KTEXT pkt; + KTEXT rpkt; + int f; + struct sockaddr_in *_to; + struct hostent *addrs; +{ + fd_set readfds; + register struct hostent *hp; + struct sockaddr_in from; + int sin_size; + int numsent; + + if (krb_debug) { + if (_to->sin_family == AF_INET) + printf("Sending message to %s...", + inet_ntoa(_to->sin_addr)); + else + printf("Sending message..."); + (void) fflush(stdout); + } + if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0, + (struct sockaddr *)_to, + S_AD_SZ)) != pkt->length) { + if (krb_debug) + printf("sent only %d/%d\n",numsent, pkt->length); + return 0; + } + if (krb_debug) { + printf("Sent\nWaiting for reply..."); + (void) fflush(stdout); + } + FD_ZERO(&readfds); + FD_SET(f, &readfds); + errno = 0; + /* select - either recv is ready, or timeout */ + /* see if timeout or error or wrong descriptor */ + if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1 + || !FD_ISSET(f, &readfds)) { + if (krb_debug) { + fprintf(stderr, "select failed: readfds=%x", + readfds); + perror(""); + } + return 0; + } + sin_size = sizeof(from); + if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0, + (struct sockaddr *)&from, &sin_size) + < 0) { + if (krb_debug) + perror("recvfrom"); + return 0; + } + if (krb_debug) { + printf("received packet from %s\n", inet_ntoa(from.sin_addr)); + fflush(stdout); + } + for (hp = addrs; hp->h_name != (char *)NULL; hp++) { + if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr, + hp->h_length)) { + if (krb_debug) { + printf("Received it\n"); + (void) fflush(stdout); + } + return 1; + } + if (krb_debug) + fprintf(stderr, + "packet not from %x\n", + hp->h_addr); + } + if (krb_debug) + fprintf(stderr, "%s: received packet from wrong host! (%x)\n", + "send_to_kdc(send_rcv)", from.sin_addr.s_addr); + return 0; +} diff --git a/eBones/lib/libkrb/sendauth.c b/eBones/lib/libkrb/sendauth.c new file mode 100644 index 0000000..7d798bb --- /dev/null +++ b/eBones/lib/libkrb/sendauth.c @@ -0,0 +1,257 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $ + * $Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <syslog.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */ +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_recvauth.c + */ + +extern int errno; + +extern char *krb_get_phost(); + +/* + * This file contains two routines: krb_sendauth() and krb_sendsrv(). + * + * krb_sendauth() transmits a ticket over a file descriptor for a + * desired service, instance, and realm, doing mutual authentication + * with the server if desired. + * + * krb_sendsvc() sends a service name to a remote knetd server. + */ + +/* + * The first argument to krb_sendauth() contains a bitfield of + * options (the options are defined in "krb.h"): + * + * KOPT_DONT_CANON Don't canonicalize instance as a hostname. + * (If this option is not chosen, krb_get_phost() + * is called to canonicalize it.) + * + * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. + * A ticket must be supplied in the "ticket" + * argument. + * (If this option is not chosen, and there + * is no ticket for the given server in the + * ticket cache, one will be fetched using + * krb_mk_req() and returned in "ticket".) + * + * KOPT_DO_MUTUAL Do mutual authentication, requiring that the + * receiving server return the checksum+1 encrypted + * in the session key. The mutual authentication + * is done using krb_mk_priv() on the other side + * (see "recvauth.c") and krb_rd_priv() on this + * side. + * + * The "fd" argument is a file descriptor to write to the remote + * server on. The "ticket" argument is used to store the new ticket + * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is + * chosen, the ticket must be supplied in the "ticket" argument. + * The "service", "inst", and "realm" arguments identify the ticket. + * If "realm" is null, the local realm is used. + * + * The following arguments are only needed if the KOPT_DO_MUTUAL option + * is chosen: + * + * The "checksum" argument is a number that the server will add 1 to + * to authenticate itself back to the client; the "msg_data" argument + * holds the returned mutual-authentication message from the server + * (i.e., the checksum+1); the "cred" structure is used to hold the + * session key of the server, extracted from the ticket file, for use + * in decrypting the mutual authentication message from the server; + * and "schedule" holds the key schedule for that decryption. The + * the local and server addresses are given in "laddr" and "faddr". + * + * The application protocol version number (of up to KRB_SENDAUTH_VLEN + * characters) is passed in "version". + * + * If all goes well, KSUCCESS is returned, otherwise some error code. + * + * The format of the message sent to the server is: + * + * Size Variable Field + * ---- -------- ----- + * + * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol + * bytes version number + * + * KRB_SENDAUTH_VLEN version application protocol + * bytes version number + * + * 4 bytes ticket->length length of ticket + * + * ticket->length ticket->dat ticket itself + */ + +/* + * XXX: Note that krb_rd_priv() is coded in such a way that + * "msg_data->app_data" will be pointing into "priv_buf", which + * will disappear when krb_sendauth() returns. + */ + +int +krb_sendauth(options, fd, ticket, service, inst, realm, checksum, + msg_data, cred, schedule, laddr, faddr, version) +long options; /* bit-pattern of options */ +int fd; /* file descriptor to write onto */ +KTEXT ticket; /* where to put ticket (return); or + * supplied in case of KOPT_DONT_MK_REQ */ +char *service, *inst, *realm; /* service name, instance, realm */ +u_long checksum; /* checksum to include in request */ +MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */ +CREDENTIALS *cred; /* credentials (return) */ +Key_schedule schedule; /* key schedule (return) */ +struct sockaddr_in *laddr; /* local address */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +char *version; /* version string */ +{ + int rem, i, cc; + char srv_inst[INST_SZ]; + char krb_realm[REALM_SZ]; + char buf[BUFSIZ]; + long tkt_len; + u_char priv_buf[1024]; + u_long cksum; + + rem=KSUCCESS; + + /* get current realm if not passed in */ + if (!realm) { + rem = krb_get_lrealm(krb_realm,1); + if (rem != KSUCCESS) + return(rem); + realm = krb_realm; + } + + /* copy instance into local storage, canonicalizing if desired */ + if (options & KOPT_DONT_CANON) + (void) strncpy(srv_inst, inst, INST_SZ); + else + (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ); + + /* get the ticket if desired */ + if (!(options & KOPT_DONT_MK_REQ)) { + rem = krb_mk_req(ticket, service, srv_inst, realm, checksum); + if (rem != KSUCCESS) + return(rem); + } + +#ifdef ATHENA_COMPAT + /* this is only for compatibility with old servers */ + if (options & KOPT_DO_OLDSTYLE) { + (void) sprintf(buf,"%d ",ticket->length); + (void) write(fd, buf, strlen(buf)); + (void) write(fd, (char *) ticket->dat, ticket->length); + return(rem); + } +#endif ATHENA_COMPAT + /* if mutual auth, get credentials so we have service session + keys for decryption below */ + if (options & KOPT_DO_MUTUAL) + if (cc = krb_get_cred(service, srv_inst, realm, cred)) + return(cc); + + /* zero the buffer */ + (void) bzero(buf, BUFSIZ); + + /* insert version strings */ + (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN); + (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN); + + /* increment past vers strings */ + i = 2*KRB_SENDAUTH_VLEN; + + /* put ticket length into buffer */ + tkt_len = htonl((unsigned long) ticket->length); + (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len)); + i += sizeof(tkt_len); + + /* put ticket into buffer */ + (void) bcopy((char *) ticket->dat, buf+i, ticket->length); + i += ticket->length; + + /* write the request to the server */ + if ((cc = krb_net_write(fd, buf, i)) != i) + return(cc); + + /* mutual authentication, if desired */ + if (options & KOPT_DO_MUTUAL) { + /* get the length of the reply */ + if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + tkt_len = ntohl((unsigned long)tkt_len); + + /* if the length is negative, the server failed to recognize us. */ + if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf))) + return(KFAILURE); /* XXX */ + /* read the reply... */ + if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len) + return(errno); + + /* ...and decrypt it */ +#ifndef NOENCRYPTION + key_sched(cred->session,schedule); +#endif + if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule, + cred->session, faddr, laddr, msg_data)) + return(cc); + + /* fetch the (modified) checksum */ + (void) bcopy((char *)msg_data->app_data, (char *)&cksum, + sizeof(cksum)); + cksum = ntohl(cksum); + + /* if it doesn't match, fail */ + if (cksum != checksum + 1) + return(KFAILURE); /* XXX */ + } + return(KSUCCESS); +} + +#ifdef ATHENA_COMPAT +/* + * krb_sendsvc + */ + +int +krb_sendsvc(fd, service) +int fd; +char *service; +{ + /* write the service name length and then the service name to + the fd */ + long serv_length; + int cc; + + serv_length = htonl((unsigned long)strlen(service)); + if ((cc = krb_net_write(fd, (char *) &serv_length, + sizeof(serv_length))) + != sizeof(serv_length)) + return(cc); + if ((cc = krb_net_write(fd, service, strlen(service))) + != strlen(service)) + return(cc); + return(KSUCCESS); +} +#endif ATHENA_COMPAT diff --git a/eBones/lib/libkrb/stime.c b/eBones/lib/libkrb/stime.c new file mode 100644 index 0000000..c040374 --- /dev/null +++ b/eBones/lib/libkrb/stime.c @@ -0,0 +1,40 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $ + * $Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/time.h> +#include <stdio.h> /* for sprintf() */ + +/* + * Given a pointer to a long containing the number of seconds + * since the beginning of time (midnight 1 Jan 1970 GMT), return + * a string containing the local time in the form: + * + * "25-Jan-88 10:17:56" + */ + +char *stime(t) + long *t; +{ + static char st_data[40]; + static char *st = st_data; + struct tm *tm; + char *month_sname(); + + tm = localtime(t); + (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + return st; +} diff --git a/eBones/lib/libkrb/tf_shm.c b/eBones/lib/libkrb/tf_shm.c new file mode 100644 index 0000000..5548f0d --- /dev/null +++ b/eBones/lib/libkrb/tf_shm.c @@ -0,0 +1,174 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Shared memory segment functions for session keys. Derived from code + * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu). + * + * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $ + * $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <krb.h> +#include <des.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */ + +extern int errno; +extern int krb_debug; + +/* + * krb_create_shmtkt: + * + * create a shared memory segment for session keys, leaving its id + * in the specified filename. + */ + +int +krb_shm_create(file_name) +char *file_name; +{ + int retval; + int shmid; + struct shmid_ds shm_buf; + FILE *sfile; + uid_t me, metoo, getuid(), geteuid(); + + (void) krb_shm_dest(file_name); /* nuke it if it exists... + this cleans up to make sure we + don't slowly lose memory. */ + + shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT); + if (shmid == -1) { + if (krb_debug) + perror("krb_shm_create shmget"); + return(KFAILURE); /* XXX */ + } + me = getuid(); + metoo = geteuid(); + /* + * now set up the buffer so that we can modify it + */ + shm_buf.shm_perm.uid = me; + shm_buf.shm_perm.gid = getgid(); + shm_buf.shm_perm.mode = 0600; + if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */ + if (krb_debug) + perror("krb_shm_create shmctl"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */ + /* arrange so the file is owned by the ruid + (swap real & effective uid if necessary). */ + if (me != metoo) { + if (setreuid(metoo, me) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("krb_shm_create: setreuid"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",metoo,me); + } + if ((sfile = fopen(file_name,"w")) == 0) { + if (krb_debug) + perror("krb_shm_create file"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + if (fchmod(fileno(sfile),0600) < 0) { + if (krb_debug) + perror("krb_shm_create fchmod"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); /* XXX */ + } + if (me != metoo) { + if (setreuid(me, metoo) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("krb_shm_create: setreuid2"); + (void) shmctl(shmid, IPC_RMID, 0); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",me,metoo); + } + + (void) fprintf(sfile,"%d",shmid); + (void) fflush(sfile); + (void) fclose(sfile); + return(KSUCCESS); +} + + +/* + * krb_is_diskless: + * + * check / to see if file .diskless exists. If so it is diskless. + * Do it this way now to avoid dependencies on a particular routine. + * Choose root file system since that will be private to the client. + */ + +int krb_is_diskless() +{ + struct stat buf; + if (stat("/.diskless",&buf) < 0) + return(0); + else return(1); +} + +/* + * krb_shm_dest: destroy shared memory segment with session keys, and remove + * file pointing to it. + */ + +int krb_shm_dest(file) +char *file; +{ + int shmid; + FILE *sfile; + struct stat st_buf; + + if (stat(file,&st_buf) == 0) { + /* successful stat */ + if ((sfile = fopen(file,"r")) == 0) { + if (krb_debug) + perror("cannot open shared memory file"); + return(KFAILURE); /* XXX */ + } + if (fscanf(sfile,"%d",&shmid) == 1) { + if (shmctl(shmid,IPC_RMID,0) != 0) { + if (krb_debug) + perror("krb_shm_dest: cannot delete shm segment"); + (void) fclose(sfile); + return(KFAILURE); /* XXX */ + } + } else { + if (krb_debug) + fprintf(stderr, "bad format in shmid file\n"); + (void) fclose(sfile); + return(KFAILURE); /* XXX */ + } + (void) fclose(sfile); + (void) unlink(file); + return(KSUCCESS); + } else + return(RET_TKFIL); /* XXX */ +} + + + diff --git a/eBones/lib/libkrb/tf_util.3 b/eBones/lib/libkrb/tf_util.3 new file mode 100644 index 0000000..3a9bc94 --- /dev/null +++ b/eBones/lib/libkrb/tf_util.3 @@ -0,0 +1,151 @@ +.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $ +.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \ +\- Routines for manipulating a Kerberos ticket file +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +extern char *krb_err_txt[]; +.PP +.ft B +tf_init(tf_name, rw) +char *tf_name; +int rw; +.PP +.ft B +tf_get_pname(pname) +char *pname; +.PP +.ft B +tf_get_pinst(pinst) +char *pinst; +.PP +.ft B +tf_get_cred(c) +CREDENTIALS *c; +.PP +.ft B +tf_close() +.PP +.fi +.SH DESCRIPTION +This group of routines are provided to manipulate the Kerberos tickets +file. A ticket file has the following format: +.nf +.in +4 +.sp +principal's name (null-terminated string) +principal's instance (null-terminated string) +CREDENTIAL_1 +CREDENTIAL_2 + ... +CREDENTIAL_n +EOF +.sp +.in -4 +.LP +Where "CREDENTIAL_x" consists of the following fixed-length +fields from the CREDENTIALS structure (defined in <krb.h>): +.nf +.sp +.in +4 + char service[ANAME_SZ] + char instance[INST_SZ] + char realm[REALM_SZ] + des_cblock session + int lifetime + int kvno + KTEXT_ST ticket_st + long issue_date +.in -4 +.sp +.fi +.PP +.I tf_init +must be called before the other ticket file +routines. +It takes the name of the ticket file to use, +and a read/write flag as arguments. +It tries to open the ticket file, checks the mode and if +everything is okay, locks the file. If it's opened for +reading, the lock is shared. If it's opened for writing, +the lock is exclusive. +KSUCCESS is returned if all went well, otherwise one of the +following: +.nf +.sp +NO_TKT_FIL - file wasn't there +TKT_FIL_ACC - file was in wrong mode, etc. +TKT_FIL_LCK - couldn't lock the file, even after a retry +.sp +.fi +.PP +The +.I tf_get_pname +reads the principal's name from a ticket file. +It should only be called after tf_init has been called. The +principal's name is filled into the +.I pname +parameter. If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If the principal's name was null, or EOF was encountered, or the +name was longer than ANAME_SZ, TKT_FIL_FMT is returned. +.PP +The +.I tf_get_pinst +reads the principal's instance from a ticket file. +It should only be called after tf_init and tf_get_pname +have been called. +The principal's instance is filled into the +.I pinst +parameter. +If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If EOF was encountered, or the +name was longer than INST_SZ, TKT_FIL_FMT is returned. +Note that, unlike the principal name, the instance name may be null. +.PP +The +.I tf_get_cred +routine reads a CREDENTIALS record from a ticket file and +fills in the given structure. +It should only be called after +tf_init, tf_get_pname, and tf_get_pinst have been called. +If all goes well, KSUCCESS is returned. Possible error codes +are: +.nf +.sp +TKT_FIL_INI - tf_init wasn't called first +TKT_FIL_FMT - bad format +EOF - end of file encountered +.sp +.fi +.PP +.I tf_close +closes the ticket file and releases the lock on it. +.SH "SEE ALSO" +krb(3) +.SH DIAGNOSTICS +.SH BUGS +The ticket file routines have to be called in a certain order. +.SH AUTHORS +Jennifer Steiner, MIT Project Athena +.br +Bill Bryant, MIT Project Athena +.SH RESTRICTIONS +Copyright 1987 Massachusetts Institute of Technology diff --git a/eBones/lib/libkrb/tf_util.c b/eBones/lib/libkrb/tf_util.c new file mode 100644 index 0000000..a9e8551 --- /dev/null +++ b/eBones/lib/libkrb/tf_util.c @@ -0,0 +1,572 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $ + * $Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <krb.h> + +#ifdef TKT_SHMEM +#include <sys/param.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#endif /* TKT_SHMEM */ + +#define TOO_BIG -1 +#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before + * retry if ticket file is + * locked */ +extern errno; +extern int krb_debug; + +#ifdef TKT_SHMEM +char *krb_shm_addr = 0; +static char *tmp_shm_addr = 0; +static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0}; + +char *shmat(); +#endif /* TKT_SHMEM */ + +/* + * fd must be initialized to something that won't ever occur as a real + * file descriptor. Since open(2) returns only non-negative numbers as + * valid file descriptors, and tf_init always stuffs the return value + * from open in here even if it is an error flag, we must + * a. Initialize fd to a negative number, to indicate that it is + * not initially valid. + * b. When checking for a valid fd, assume that negative values + * are invalid (ie. when deciding whether tf_init has been + * called.) + * c. In tf_close, be sure it gets reinitialized to a negative + * number. + */ +static fd = -1; +static curpos; /* Position in tfbfr */ +static lastpos; /* End of tfbfr */ +static char tfbfr[BUFSIZ]; /* Buffer for ticket data */ + +static tf_gets(), tf_read(); + +/* + * This file contains routines for manipulating the ticket cache file. + * + * The ticket file is in the following format: + * + * principal's name (null-terminated string) + * principal's instance (null-terminated string) + * CREDENTIAL_1 + * CREDENTIAL_2 + * ... + * CREDENTIAL_n + * EOF + * + * Where "CREDENTIAL_x" consists of the following fixed-length + * fields from the CREDENTIALS structure (see "krb.h"): + * + * char service[ANAME_SZ] + * char instance[INST_SZ] + * char realm[REALM_SZ] + * C_Block session + * int lifetime + * int kvno + * KTEXT_ST ticket_st + * long issue_date + * + * Short description of routines: + * + * tf_init() opens the ticket file and locks it. + * + * tf_get_pname() returns the principal's name. + * + * tf_get_pinst() returns the principal's instance (may be null). + * + * tf_get_cred() returns the next CREDENTIALS record. + * + * tf_save_cred() appends a new CREDENTIAL record to the ticket file. + * + * tf_close() closes the ticket file and releases the lock. + * + * tf_gets() returns the next null-terminated string. It's an internal + * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred(). + * + * tf_read() reads a given number of bytes. It's an internal routine + * used by tf_get_cred(). + */ + +/* + * tf_init() should be called before the other ticket file routines. + * It takes the name of the ticket file to use, "tf_name", and a + * read/write flag "rw" as arguments. + * + * It tries to open the ticket file, checks the mode, and if everything + * is okay, locks the file. If it's opened for reading, the lock is + * shared. If it's opened for writing, the lock is exclusive. + * + * Returns KSUCCESS if all went well, otherwise one of the following: + * + * NO_TKT_FIL - file wasn't there + * TKT_FIL_ACC - file was in wrong mode, etc. + * TKT_FIL_LCK - couldn't lock the file, even after a retry + */ + +tf_init(tf_name, rw) + char *tf_name; +{ + int wflag; + uid_t me, getuid(); + struct stat stat_buf; +#ifdef TKT_SHMEM + char shmidname[MAXPATHLEN]; + FILE *sfp; + int shmid; +#endif + + switch (rw) { + case R_TKT_FIL: + wflag = 0; + break; + case W_TKT_FIL: + wflag = 1; + break; + default: + if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n"); + return TKT_FIL_ACC; + } + if (lstat(tf_name, &stat_buf) < 0) + switch (errno) { + case ENOENT: + return NO_TKT_FIL; + default: + return TKT_FIL_ACC; + } + me = getuid(); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#ifdef TKT_SHMEM + (void) strcpy(shmidname, tf_name); + (void) strcat(shmidname, ".shm"); + if (stat(shmidname,&stat_buf) < 0) + return(TKT_FIL_ACC); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#endif /* TKT_SHMEM */ + + /* + * If "wflag" is set, open the ticket file in append-writeonly mode + * and lock the ticket file in exclusive mode. If unable to lock + * the file, sleep and try again. If we fail again, return with the + * proper error message. + */ + + curpos = sizeof(tfbfr); + +#ifdef TKT_SHMEM + sfp = fopen(shmidname, "r"); /* only need read/write on the + actual tickets */ + if (sfp == 0) + return TKT_FIL_ACC; + shmid = -1; + { + char buf[BUFSIZ]; + int val; /* useful for debugging fscanf */ + /* We provide our own buffer here since some STDIO libraries + barf on unbuffered input with fscanf() */ + + setbuf(sfp, buf); + if ((val = fscanf(sfp,"%d",&shmid)) != 1) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + if (shmid < 0) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + (void) fclose(sfp); + } + /* + * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and + * attach the same segment twice so we need this check. + */ + if (!krb_shm_addr) { + if ((krb_shm_addr = shmat(shmid,0,0)) == -1){ + if (krb_debug) + fprintf(stderr, + "cannot attach shared memory for segment %d\n", + shmid); + krb_shm_addr = 0; /* reset so we catch further errors */ + return TKT_FIL_ACC; + } + } + tmp_shm_addr = krb_shm_addr; +#endif /* TKT_SHMEM */ + + if (wflag) { + fd = open(tf_name, O_RDWR, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; + } + /* + * Otherwise "wflag" is not set and the ticket file should be opened + * for read-only operations and locked for shared access. + */ + + fd = open(tf_name, O_RDONLY, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; +} + +/* + * tf_get_pname() reads the principal's name from the ticket file. It + * should only be called after tf_init() has been called. The + * principal's name is filled into the "p" parameter. If all goes well, + * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is + * returned. If the name was null, or EOF was encountered, or the name + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. + */ + +tf_get_pname(p) + char *p; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pname called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */ + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_pinst() reads the principal's instance from a ticket file. + * It should only be called after tf_init() and tf_get_pname() have been + * called. The instance is filled into the "inst" parameter. If all + * goes well, KSUCCESS is returned. If tf_init() wasn't called, + * TKT_FIL_INI is returned. If EOF was encountered, or the instance + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the + * instance may be null. + */ + +tf_get_pinst(inst) + char *inst; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pinst called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(inst, INST_SZ) < 1) + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills + * in the given structure "c". It should only be called after tf_init(), + * tf_get_pname(), and tf_get_pinst() have been called. If all goes well, + * KSUCCESS is returned. Possible error codes are: + * + * TKT_FIL_INI - tf_init wasn't called first + * TKT_FIL_FMT - bad format + * EOF - end of file encountered + */ + +tf_get_cred(c) + CREDENTIALS *c; +{ + KTEXT ticket = &c->ticket_st; /* pointer to ticket */ + int k_errno; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1) + switch (k_errno) { + case TOO_BIG: + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ( + tf_read((char *) (c->session), KEY_SZ) < 1 || + tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 || + tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 || + tf_read((char *) &(ticket->length), sizeof(ticket->length)) + < 1 || + /* don't try to read a silly amount into ticket->dat */ + ticket->length > MAX_KTXT_LEN || + tf_read((char *) (ticket->dat), ticket->length) < 1 || + tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1 + ) { + tf_close(); + return TKT_FIL_FMT; + } +#ifdef TKT_SHMEM + bcopy(tmp_shm_addr,c->session,KEY_SZ); + tmp_shm_addr += KEY_SZ; +#endif /* TKT_SHMEM */ + return KSUCCESS; +} + +/* + * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is + * not a valid file descriptor, it just returns. It also clears the + * buffer used to read tickets. + * + * The return value is not defined. + */ + +tf_close() +{ + if (!(fd < 0)) { +#ifdef TKT_SHMEM + if (shmdt(krb_shm_addr)) { + /* what kind of error? */ + if (krb_debug) + fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno); + } else { + krb_shm_addr = 0; + } +#endif TKT_SHMEM + (void) flock(fd, LOCK_UN); + (void) close(fd); + fd = -1; /* see declaration of fd above */ + } + bzero(tfbfr, sizeof(tfbfr)); +} + +/* + * tf_gets() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until either it has read "n" characters, + * or until it reads a null byte. When finished, what has been read exists + * in "s". If it encounters EOF or an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read (including null terminator) + * when all goes well + * + * 0 end of file or read error + * + * TOO_BIG if "count" characters are read and no null is + * encountered. This is an indication that the ticket + * file is seriously ill. + */ + +static +tf_gets(s, n) + register char *s; +{ + register count; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_gets called before tf_init.\n"); + return TKT_FIL_INI; + } + for (count = n - 1; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s = tfbfr[curpos++]; + if (*s++ == '\0') + return (n - count); + } + tf_close(); + return TOO_BIG; +} + +/* + * tf_read() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until "n" bytes have been read. When + * finished, what has been read exists in "s". If it encounters EOF or + * an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read when all goes well + * + * 0 on end of file or read error + */ + +static +tf_read(s, n) + register char *s; + register n; +{ + register count; + + for (count = n; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s++ = tfbfr[curpos++]; + } + return n; +} + +char *tkt_string(); + +/* + * tf_save_cred() appends an incoming ticket to the end of the ticket + * file. You must call tf_init() before calling tf_save_cred(). + * + * The "service", "instance", and "realm" arguments specify the + * server's name; "session" contains the session key to be used with + * the ticket; "kvno" is the server key version number in which the + * ticket is encrypted, "ticket" contains the actual ticket, and + * "issue_date" is the time the ticket was requested (local host's time). + * + * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't + * called previously, and KFAILURE for anything else that went wrong. + */ + +tf_save_cred(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + C_Block session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + long issue_date; /* The issue time */ +{ + + off_t lseek(); + int count; /* count for write */ +#ifdef TKT_SHMEM + int *skey_check; +#endif /* TKT_SHMEM */ + + if (fd < 0) { /* fd is ticket file as set by tf_init */ + if (krb_debug) + fprintf(stderr, "tf_save_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + /* Find the end of the ticket file */ + (void) lseek(fd, 0L, 2); +#ifdef TKT_SHMEM + /* scan to end of existing keys: pick first 'empty' slot. + we assume that no real keys will be completely zero (it's a weak + key under DES) */ + + skey_check = (int *) krb_shm_addr; + + while (*skey_check && *(skey_check+1)) + skey_check += 2; + tmp_shm_addr = (char *)skey_check; +#endif /* TKT_SHMEM */ + + /* Write the ticket and associated data */ + /* Service */ + count = strlen(service) + 1; + if (write(fd, service, count) != count) + goto bad; + /* Instance */ + count = strlen(instance) + 1; + if (write(fd, instance, count) != count) + goto bad; + /* Realm */ + count = strlen(realm) + 1; + if (write(fd, realm, count) != count) + goto bad; + /* Session key */ +#ifdef TKT_SHMEM + bcopy(session,tmp_shm_addr,8); + tmp_shm_addr+=8; + if (write(fd,krb_dummy_skey,8) != 8) + goto bad; +#else /* ! TKT_SHMEM */ + if (write(fd, (char *) session, 8) != 8) + goto bad; +#endif /* TKT_SHMEM */ + /* Lifetime */ + if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int)) + goto bad; + /* Key vno */ + if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int)) + goto bad; + /* Tkt length */ + if (write(fd, (char *) &(ticket->length), sizeof(int)) != + sizeof(int)) + goto bad; + /* Ticket */ + count = ticket->length; + if (write(fd, (char *) (ticket->dat), count) != count) + goto bad; + /* Issue date */ + if (write(fd, (char *) &issue_date, sizeof(long)) + != sizeof(long)) + goto bad; + + /* Actually, we should check each write for success */ + return (KSUCCESS); +bad: + return (KFAILURE); +} diff --git a/eBones/lib/libkrb/tkt_string.c b/eBones/lib/libkrb/tkt_string.c new file mode 100644 index 0000000..ba22db8 --- /dev/null +++ b/eBones/lib/libkrb/tkt_string.c @@ -0,0 +1,79 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $ + * $Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $ + */ + +#ifndef lint +static char *rcsid = +"$Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <sys/types.h> +#include <krb.h> +#include <string.h> +#include <sys/param.h> + +char *getenv(); + +/* + * This routine is used to generate the name of the file that holds + * the user's cache of server tickets and associated session keys. + * + * If it is set, krb_ticket_string contains the ticket file name. + * Otherwise, the filename is constructed as follows: + * + * If it is set, the environment variable "KRBTKFILE" will be used as + * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and + * the user's uid are concatenated to produce the ticket file name + * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket + * file name is returned. + */ + +static char krb_ticket_string[MAXPATHLEN] = ""; + +char *tkt_string() +{ + char *env; + uid_t getuid(); + + if (!*krb_ticket_string) { + if (env = getenv("KRBTKFILE")) { + (void) strncpy(krb_ticket_string, env, + sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + } else { + /* 32 bits of signed integer will always fit in 11 characters + (including the sign), so no need to worry about overflow */ + (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,getuid()); + } + } + return krb_ticket_string; +} + +/* + * This routine is used to set the name of the file that holds the user's + * cache of server tickets and associated session keys. + * + * The value passed in is copied into local storage. + * + * NOTE: This routine should be called during initialization, before other + * Kerberos routines are called; otherwise tkt_string() above may be called + * and return an undesired ticket file name until this routine is called. + */ + +void +krb_set_tkt_string(val) +char *val; +{ + + (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + + return; +} diff --git a/eBones/lib/libkrb/util.c b/eBones/lib/libkrb/util.c new file mode 100644 index 0000000..8e48557 --- /dev/null +++ b/eBones/lib/libkrb/util.c @@ -0,0 +1,72 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Miscellaneous debug printing utilities + * + * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $ + * $Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $"; +#endif lint + +#include <krb.h> +#include <des.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> + +/* + * Print some of the contents of the given authenticator structure + * (AUTH_DAT defined in "krb.h"). Fields printed are: + * + * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session + */ + +ad_print(x) +AUTH_DAT *x; +{ + struct in_addr in; + + /* Print the contents of an auth_dat struct. */ + in.s_addr = x->address; + printf("\n%s %s %s %s flags %u cksum 0x%X\n\ttkt_tm 0x%X sess_key", + x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags, + x->checksum, x->time_sec); + + printf("[8] ="); +#ifdef NOENCRYPTION + placebo_cblock_print(x->session); +#else + des_cblock_print_file(x->session,stdout); +#endif + /* skip reply for now */ +} + +/* + * Print in hex the 8 bytes of the given session key. + * + * Printed format is: " 0x { x, x, x, x, x, x, x, x }" + */ + +#ifdef NOENCRYPTION +placebo_cblock_print(x) + des_cblock x; +{ + unsigned char *y = (unsigned char *) x; + register int i = 0; + + printf(" 0x { "); + + while (i++ <8) { + printf("%x",*y++); + if (i<8) printf(", "); + } + printf(" }"); +} +#endif diff --git a/eBones/libexec/registerd/Makefile b/eBones/libexec/registerd/Makefile new file mode 100644 index 0000000..bc91577 --- /dev/null +++ b/eBones/libexec/registerd/Makefile @@ -0,0 +1,20 @@ +# +# Copyright (c) 1990 The Regents of the University of California. +# All rights reserved. +# +# %sccs.include.redist.sh +# +# @(#)Makefile 8.1 (Berkeley) 6/1/93 +# +# $Id: Makefile,v 1.3 1994/07/20 09:20:51 g89r4222 Exp $ + +PROG= registerd +SRCS= registerd.c +CFLAGS+=-DCRYPT -DKERBEROS -I${.CURDIR}/../register +.PATH: ${.CURDIR}/../../usr.bin/rlogin +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN8= registerd.8 +BINDIR= /usr/libexec + +.include <bsd.prog.mk> diff --git a/eBones/libexec/registerd/registerd.8 b/eBones/libexec/registerd/registerd.8 new file mode 100644 index 0000000..7ceff75 --- /dev/null +++ b/eBones/libexec/registerd/registerd.8 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)registerd.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt REGISTERD 8 +.Os +.Sh NAME +.Nm registerd +.Nd Kerberos registration daemon +.Sh SYNOPSIS +.Nm registerd +.Sh DESCRIPTION +Act as a registration agent for a Kerberos domain. +.Sh FILES +.Bl -tag -width /etc/kerberosIV/register_keys -compact +.It Pa /.update.keyxx.xx.xx.xx +shared +.Tn DES +key with server +.It Pa /etc/kerberosIV/principal* +Kerberos database +.It Pa /etc/kerberosIV/register_keys +directory containing keys for trusted hosts +.El +.Sh SEE ALSO +.Xr registerd 8 , +.Xr kerberos 1 +.Sh DIAGNOSTICS +.Dq Already exists , +if the user already exists in the Kerberos database. +.Pp +.Dq Permission Denied , +if the host on which register is being run is untrusted. +.Sh HISTORY +The +.Nm registerd +utility +first appeared in 4.4BSD. + diff --git a/eBones/libexec/registerd/registerd.c b/eBones/libexec/registerd/registerd.c new file mode 100644 index 0000000..b62e379 --- /dev/null +++ b/eBones/libexec/registerd/registerd.c @@ -0,0 +1,341 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/signal.h> +#include <sys/resource.h> +#include <sys/param.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <syslog.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include <kerberosIV/krb_db.h> +#include <stdio.h> +#include "register_proto.h" +#include "pathnames.h" + +#define KBUFSIZ (sizeof(struct keyfile_data)) +#define RCRYPT 0x00 +#define CLEAR 0x01 + +char *progname, msgbuf[BUFSIZ]; + +main(argc, argv) + int argc; + char **argv; +{ + static Key_schedule schedule; + static struct rlimit rl = { 0, 0 }; + struct keyfile_data *kfile; + u_char code; + int kf, retval, sval; + struct sockaddr_in sin; + char keyfile[MAXPATHLEN], keybuf[KBUFSIZ]; + void die(); + + progname = argv[0]; /* for the library routines */ + + openlog("registerd", LOG_PID, LOG_AUTH); + + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGTSTP, SIG_IGN); + (void)signal(SIGPIPE, die); + + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + syslog(LOG_ERR, "setrlimit: %m"); + exit(1); + } + + + /* figure out who we are talking to */ + + sval = sizeof(sin); + if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) { + syslog(LOG_ERR, "getpeername: %m"); + exit(1); + } + + /* get encryption key */ + + (void) sprintf(keyfile, "%s/%s%s", + SERVER_KEYDIR, + KEYFILE_BASE, + inet_ntoa(sin.sin_addr)); + + if ((kf = open(keyfile, O_RDONLY)) < 0) { + syslog(LOG_ERR, + "error opening Kerberos update keyfile (%s): %m", keyfile); + (void) sprintf(msgbuf, + "couldn't open session keyfile for your host"); + send_packet(msgbuf, CLEAR); + exit(1); + } + + if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) { + syslog(LOG_ERR, "wrong read size of Kerberos update keyfile"); + (void) sprintf(msgbuf, + "couldn't read session key from your host's keyfile"); + send_packet(msgbuf, CLEAR); + exit(1); + } + (void) sprintf(msgbuf, GOTKEY_MSG); + send_packet(msgbuf, CLEAR); + kfile = (struct keyfile_data *) keybuf; + key_sched(kfile->kf_key, schedule); + des_set_key(kfile->kf_key, schedule); + + /* read the command code byte */ + + if (des_read(0, &code, 1) == 1) { + + switch(code) { + case APPEND_DB: + retval = do_append(&sin); + break; + case ABORT: + cleanup(); + close(0); + exit(0); + default: + retval = KFAILURE; + syslog(LOG_NOTICE, + "invalid command code on db update (0x%x)", + code); + } + + } else { + retval = KFAILURE; + syslog(LOG_ERR, + "couldn't read command code on Kerberos update"); + } + + code = (u_char) retval; + if (code != KSUCCESS) { + (void) sprintf(msgbuf, "%s", krb_err_txt[code]); + send_packet(msgbuf, RCRYPT); + } else { + (void) sprintf(msgbuf, "Update complete."); + send_packet(msgbuf, RCRYPT); + } + cleanup(); + close(0); + exit(0); +} + +#define MAX_PRINCIPAL 10 +static Principal principal_data[MAX_PRINCIPAL]; +static C_Block key, master_key; +static Key_schedule master_key_schedule; +int +do_append(sinp) + struct sockaddr_in *sinp; +{ + Principal default_princ; + char input_name[ANAME_SZ]; + char input_instance[INST_SZ]; + int j,n, more; + long mkeyversion; + + + + /* get master key from MKEYFILE */ + if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) { + syslog(LOG_ERR, "couldn't get master key"); + return(KFAILURE); + } + + mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL); + if (mkeyversion < 0) { + syslog(LOG_ERR, "couldn't validate master key"); + return(KFAILURE); + } + + n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + + if (n != 1) { + syslog(LOG_ERR, "couldn't get default principal"); + return(KFAILURE); + } + + /* + * get principal name, instance, and password from network. + * convert password to key and store it + */ + + if (net_get_principal(input_name, input_instance, key) != 0) { + return(KFAILURE); + } + + + j = kerb_get_principal( + input_name, + input_instance, + principal_data, + MAX_PRINCIPAL, + &more + ); + + if (j != 0) { + /* already in database, no update */ + syslog(LOG_NOTICE, + "attempt to add duplicate entry for principal %s.%s", + input_name, input_instance); + return(KDC_PR_N_UNIQUE); + } + + /* + * set up principal's name, instance + */ + + strcpy(principal_data[0].name, input_name); + strcpy(principal_data[0].instance, input_instance); + principal_data[0].old = NULL; + + + /* and the expiration date and version #s */ + + principal_data[0].exp_date = default_princ.exp_date; + strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt); + principal_data[0].max_life = default_princ.max_life; + principal_data[0].attributes = default_princ.attributes; + principal_data[0].kdc_key_ver = default_princ.kdc_key_ver; + + + /* and the key */ + + kdb_encrypt_key(key, key, master_key, master_key_schedule, + ENCRYPT); + bcopy(key, &principal_data[0].key_low, 4); + bcopy(((long *) key) + 1, &principal_data[0].key_high,4); + bzero(key, sizeof(key)); + + principal_data[0].key_version = 1; /* 1st entry */ + + /* and write it to the database */ + + if (kerb_put_principal(&principal_data[0], 1)) { + syslog(LOG_INFO, "Kerberos update failure: put_principal failed"); + return(KFAILURE); + } + + syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s", + principal_data[0].name, + principal_data[0].instance, + inet_ntoa(sinp->sin_addr) + ); + + return(KSUCCESS); + +} + +send_packet(msg,flag) + char *msg; + int flag; +{ + int len = strlen(msg); + msg[len++] = '\n'; + msg[len] = '\0'; + if (len > sizeof(msgbuf)) { + syslog(LOG_ERR, "send_packet: invalid msg size"); + return; + } + if (flag == RCRYPT) { + if (des_write(0, msg, len) != len) + syslog(LOG_ERR, "couldn't write reply message"); + } else if (flag == CLEAR) { + if (write(0, msg, len) != len) + syslog(LOG_ERR, "couldn't write reply message"); + } else + syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag); + +} + +net_get_principal(pname, iname, keyp) + char *pname, *iname; + C_Block *keyp; +{ + int cc; + static char password[255]; + + cc = des_read(0, pname, ANAME_SZ); + if (cc != ANAME_SZ) { + syslog(LOG_ERR, "couldn't get principal name"); + return(-1); + } + + cc = des_read(0, iname, INST_SZ); + if (cc != INST_SZ) { + syslog(LOG_ERR, "couldn't get instance name"); + return(-1); + } + + cc = des_read(0, password, 255); + if (cc != 255) { + syslog(LOG_ERR, "couldn't get password"); + bzero(password, 255); + return(-1); + } + + string_to_key(password, *keyp); + bzero(password, 255); + return(0); +} + +cleanup() +{ + bzero(master_key, sizeof(master_key)); + bzero(key, sizeof(key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); +} + +void +die() +{ + syslog(LOG_ERR, "remote end died (SIGPIPE)"); + cleanup(); + exit(1); +} diff --git a/eBones/make_keypair/Makefile b/eBones/make_keypair/Makefile new file mode 100644 index 0000000..b00048e --- /dev/null +++ b/eBones/make_keypair/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 + +PROG= make_keypair +MAN8= make_keypair.8 +CFLAGS+=-DKERBEROS -I${.CURDIR}/../register +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes + +.include <bsd.prog.mk> diff --git a/eBones/make_keypair/make_keypair.8 b/eBones/make_keypair/make_keypair.8 new file mode 100644 index 0000000..d0b7b88 --- /dev/null +++ b/eBones/make_keypair/make_keypair.8 @@ -0,0 +1,87 @@ +.\" Copyright (c) 1988, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)make_keypair.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt MAKE_KEYPAIR 8 +.Os +.Sh NAME +.Nm make_keypair +.Nd generate Kerberos host key pair +.Sh SYNOPSIS +.Nm make_keypair +.Ar hostname +.Op Ar hostname ... +.Sh DESCRIPTION +The +.Nm make_keypair +command +is used to create pairs of +.Tn DES +keys for +each +.Ar hostname . +The keys are used by privileged programs such as +.Xr register 1 +to make remote updates to the Kerberos database without +having to have first acquired a Kerberos ticket granting ticket +.Pq Tn TGT . +The keys created by +.Nm make_keypair +are placed (by hand) in the filesystems of the +kerberos server in +.Pa /etc/kerberosIV/register_keys , +and in the root directory of the clients. +For example, the file +.Pa /.update.key128.32.130.3 +would +contain a copy of the key of the client with +IP address 128.32.130.3. +These keys provide a shared secret which may be used to establish +a secure channel between the client hosts and the Kerberos server. +.Sh FILES +.Bl -tag -width /etc/kerberosIV/register_keysxx -compact +.It Pa /.update.keyxx.xx.xx.xx +shared +.Tn DES +key with server +.It Pa /etc/kerberosIV/register_keys +server's key storage directory +.El +.Sh SEE ALSO +.Xr register 1 , +.Xr registerd 8 , +.Xr kerberos 1 +.Sh HISTORY +The +.Nm make_keypair +utility first appeared in 4.4BSD. diff --git a/eBones/make_keypair/make_keypair.c b/eBones/make_keypair/make_keypair.c new file mode 100644 index 0000000..c9883ed --- /dev/null +++ b/eBones/make_keypair/make_keypair.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <stdio.h> +#include <netdb.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include "pathnames.h" +#include "register_proto.h" + +extern void random_key(), herror(); +void make_key(), usage(); + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + char *addr; + int i; + struct sockaddr_in sin; + + progname = *argv; /* argv[0] */ + + if (argc != 2) { + usage(argv[0]); + exit(1); + } + + if ((hp = gethostbyname(argv[1])) == NULL) { + herror(argv[1]); + exit(1); + } + + for (i = 0; addr = hp->h_addr_list[i]; i++) { + addr = hp->h_addr_list[i]; + bcopy(addr, &sin.sin_addr, hp->h_length); + + printf("Making key for host %s (%s)\n", + argv[1], inet_ntoa(sin.sin_addr)); + make_key(sin.sin_addr); + } + printf("==========\n"); + printf("One copy of the each key should be put in %s on the\n", + SERVER_KEYDIR); + printf("Kerberos server machine (mode 600, owner root).\n"); + printf("Another copy of each key should be put on the named\n"); + printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n", + CLIENT_KEYFILE); + printf("where the X's refer to digits of the host's inet address.\n"); + (void)fflush(stdout); + exit(0); +} + +void +make_key(addr) + struct in_addr addr; +{ + struct keyfile_data kfile; + char namebuf[255]; + int fd; + + (void)sprintf(namebuf, "%s%s", + CLIENT_KEYFILE, + inet_ntoa(addr)); + fd = open(namebuf, O_WRONLY|O_CREAT, 0600); + if (fd < 0) { + perror("open"); + exit(1); + } + random_key(kfile.kf_key); + printf("writing to file -> %s ...", namebuf); + if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) { + fprintf(stderr, "error writing file %s\n", namebuf); + } + printf("done.\n"); + (void)close(fd); + return; +} + +void +usage(name) + char *name; +{ + fprintf(stderr, "usage: %s host\n", name); +} diff --git a/eBones/man/Makefile b/eBones/man/Makefile new file mode 100644 index 0000000..8de00f0 --- /dev/null +++ b/eBones/man/Makefile @@ -0,0 +1,19 @@ +# from: @(#)Makefile 5.4 (Berkeley) 7/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:27:15 g89r4222 Exp $ + +MAN1= kdestroy.1 kerberos.1 kinit.1 klist.1 ksrvtgt.1 \ + kpasswd.1 ksu.1 rcp.1 rlogin.1 rsh.1 tftp.1 +MAN3= acl_check.3 des_crypt.3 krb.3 krb_realmofhost.3 krb_sendauth.3 \ + krb_set_tkt_string.3 kuserok.3 tf_util.3 kerberos.3 +MAN5= krb.conf.5 krb.realms.5 +MAN8= ext_srvtab.8 kdb_destroy.8 kdb_edit.8 kdb_init.8 kdb_util.8 kstash.8 \ + kadmin.8 kadmind.8 klogind.8 kshd.8 ksrvutil.8 tcom.8 tftpd.8 +MLINKS+=krb_realmofhost.3 realm.3 +MLINKS+=des_crypt.3 des.3 +MLINKS+=krb.3 kerberos.3 krb.3 krb_mk_req.3 krb.3 krb_rd_req.3 +MLINKS+=krb.3 krb_kntoln.3 krb.3 krb_set_key.3 krb.3 krb_get_cred.3 +MLINKS+=krb.3 krb_mk_priv.3 krb.3 krb_mk_safe.3 krb.3 krb_rd_safe.3 +MLINKS+=krb.3 krb_mk_err.3 krb.3 krb_rd_err.3 krb.3 krb_ck_repl.3 +MLINKS+=krb_sendauth.3 ksend.3 + +.include <bsd.prog.mk> diff --git a/eBones/man/acl_check.3 b/eBones/man/acl_check.3 new file mode 100644 index 0000000..c142506 --- /dev/null +++ b/eBones/man/acl_check.3 @@ -0,0 +1,183 @@ +.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $ +.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +acl_canonicalize_principal, acl_check, acl_exact_match, acl_add, +acl_delete, acl_initialize \- Access control list routines +.SH SYNOPSIS +.nf +.nj +.ft B +cc <files> \-lacl \-lkrb +.PP +.ft B +#include <krb.h> +.PP +.ft B +acl_canonicalize_principal(principal, buf) +char *principal; +char *buf; +.PP +.ft B +acl_check(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_exact_match(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_add(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_delete(acl, principal) +char *acl; +char *principal; +.PP +.ft B +acl_initialize(acl_file, mode) +char *acl_file; +int mode; +.fi +.ft R +.SH DESCRIPTION +.SS Introduction +.PP +An access control list (ACL) is a list of principals, where each +principal is represented by a text string which cannot contain +whitespace. The library allows application programs to refer to named +access control lists to test membership and to atomically add and +delete principals using a natural and intuitive interface. At +present, the names of access control lists are required to be Unix +filenames, and refer to human-readable Unix files; in the future, when +a networked ACL server is implemented, the names may refer to a +different namespace specific to the ACL service. +.PP +.SS Principal Names +.PP +Principal names have the form +.nf +.in +5n +<name>[.<instance>][@<realm>] +.in -5n +e.g.: +.in +5n +asp +asp.root +asp@ATHENA.MIT.EDU +asp.@ATHENA.MIT.EDU +asp.root@ATHENA.MIT.EDU +.in -5n +.fi +It is possible for principals to be underspecified. If an instance is +missing, it is assumed to be "". If realm is missing, it is assumed +to be the local realm as determined by +.IR krb_get_lrealm (3). +The canonical form contains all of name, instance, +and realm; the acl_add and acl_delete routines will always +leave the file in that form. Note that the canonical form of +asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU. +.SS Routines +.PP +.I acl_canonicalize_principal +stores the canonical form of +.I principal +in +.IR buf . +.I Buf +must contain enough +space to store a principal, given the limits on the sizes of name, +instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ, +respectively, in +.IR /usr/include/krb.h . +.PP +.I acl_check +returns nonzero if +.I principal +appears in +.IR acl . +Returns 0 if principal +does not appear in acl, or if an error occurs. Canonicalizes +principal before checking, and allows the ACL to contain wildcards. The +only supported wildcards are entries of the form +name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the +its component field. For example, "jtkohl.*@*" would match principal +jtkohl, with any instance and any realm. +.PP +.I acl_exact_match +performs like +.IR acl_check , +but does no canonicalization or wildcard matching. +.PP +.I acl_add +atomically adds +.I principal +to +.IR acl . +Returns 0 if successful, nonzero otherwise. It is considered a failure +if +.I principal +is already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_delete +atomically deletes +.I principal +from +.IR acl . +Returns 0 if successful, +nonzero otherwise. It is considered a failure if +.I principal +is not +already in +.IR acl . +This routine will canonicalize +.IR principal , +but will treat wildcards literally. +.PP +.I acl_initialize +initializes +.IR acl_file . +If the file +.I acl_file +does not exist, +.I acl_initialize +creates it with mode +.IR mode . +If the file +.I acl_file +exists, +.I acl_initialize +removes all members. Returns 0 if successful, +nonzero otherwise. WARNING: Mode argument is likely to change with +the eventual introduction of an ACL service. +.SH NOTES +In the presence of concurrency, there is a very small chance that +.I acl_add +or +.I acl_delete +could report success even though it would have +had no effect. This is a necessary side effect of using lock files +for concurrency control rather than flock(2), which is not supported +by NFS. +.PP +The current implementation caches ACLs in memory in a hash-table +format for increased efficiency in checking membership; one effect of +the caching scheme is that one file descriptor will be kept open for +each ACL cached, up to a maximum of 8. +.SH SEE ALSO +kerberos(3), krb_get_lrealm(3) +.SH AUTHOR +James Aspnes (MIT Project Athena) diff --git a/eBones/man/des.point b/eBones/man/des.point new file mode 100644 index 0000000..853c9cb --- /dev/null +++ b/eBones/man/des.point @@ -0,0 +1 @@ +.so man3/des_crypt.3 diff --git a/eBones/man/des_crypt.3 b/eBones/man/des_crypt.3 new file mode 100644 index 0000000..0be8342 --- /dev/null +++ b/eBones/man/des_crypt.3 @@ -0,0 +1,380 @@ +.\" from: des_crypt.3,v 4.3 89/01/23 17:08:59 steiner Exp $ +.\" $Id: des_crypt.3,v 1.2 1994/07/19 19:27:19 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH DES_CRYPT 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +des_read_password, des_string_to_key, des_random_key, des_set_key, +des_ecb_encrypt, des_cbc_encrypt, des_pcbc_encrypt, des_cbc_cksum, +des_quad_cksum, \- (new) DES encryption +.SH SYNOPSIS +.nf +.nj +.ft B +#include <des.h> +.PP +.ft B +.B int des_read_password(key,prompt,verify) +des_cblock *key; +char *prompt; +int verify; +.PP +.ft B +int des_string_to_key(str,key) +char *str; +des_cblock key; +.PP +.ft B +int des_random_key(key) +des_cblock *key; +.PP +.ft B +int des_set_key(key,schedule) +des_cblock *key; +des_key_schedule schedule; +.PP +.ft B +int des_ecb_encrypt(input,output,schedule,encrypt) +des_cblock *input; +des_cblock *output; +des_key_schedule schedule; +int encrypt; +.PP +.ft B +int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; +.PP +.ft B +int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +int encrypt; +.PP +.ft B +unsigned long des_cbc_cksum(input,output,length,schedule,ivec) +des_cblock *input; +des_cblock *output; +long length; +des_key_schedule schedule; +des_cblock *ivec; +.PP +.ft B +unsigned long quad_cksum(input,output,length,out_count,seed) +des_cblock *input; +des_cblock *output; +long length; +int out_count; +des_cblock *seed; +.PP +.fi +.SH DESCRIPTION +This library supports various DES encryption related operations. It differs +from the +.I crypt, setkey, and encrypt +library routines in that it provides +a true DES encryption, without modifying the algorithm, +and executes much faster. +.PP +For each key that may be simultaneously active, create a +.B des_key_schedule +struct, +defined in "des.h". Next, create key schedules (from the 8-byte keys) as +needed, via +.I des_set_key, +prior to using the encryption or checksum routines. Then +setup the input and output areas. Make sure to note the restrictions +on lengths being multiples of eight bytes. Finally, invoke the +encryption/decryption routines, +.I des_ecb_encrypt +or +.I des_cbc_encrypt +or +.I des_pcbc_encrypt, +or, to generate a cryptographic checksum, use +.I quad_cksum +(fast) or +.I des_cbc_cksum +(slow). +.PP +A +.I des_cblock +struct is an 8 byte block used as the fundamental unit for DES data and +keys, and is defined as: +.PP +.B typedef unsigned char des_cblock[8]; +.PP +and a +.I des_key_schedule, +is defined as: +.PP +.B typedef struct des_ks_struct {des_cblock _;} des_key_schedule[16]; +.PP +.I des_read_password +writes the string specified by +.I prompt +to the standard +output, turns off echo (if possible) +and reads an input string from standard input until terminated with a newline. +If +.I verify +is non-zero, it prompts and reads input again, for use +in applications such as changing a password; both +versions are compared, and the input is requested repeatedly until they +match. Then +.I des_read_password +converts the input string into a valid DES key, internally +using the +.I des_string_to_key +routine. The newly created key is copied to the +area pointed to by the +.I key +argument. +.I des_read_password +returns a zero if no errors occurred, or a -1 +indicating that an error +occurred trying to manipulate the terminal echo. +.PP +.PP +.I des_string_to_key +converts an arbitrary length null-terminated string +to an 8 byte DES key, with odd byte parity, per FIPS specification. +A one-way function is used to convert the string to a key, making it +very difficult to reconstruct the string from the key. +The +.I str +argument is a pointer to the string, and +.I key +should +point to a +.I des_cblock +supplied by the caller to receive the generated key. +No meaningful value is returned. Void is not used for compatibility with +other compilers. +.PP +.PP +.I des_random_key +generates a random DES encryption key (eight bytes), set to odd parity per +FIPS +specifications. +This routine uses the current time, process id, and a counter +as a seed for the random number generator. +The caller must supply space for the output key, pointed to +by argument +.I key, +then after calling +.I des_random_key +should +call the +.I des_set_key +routine when needed. +No meaningful value is returned. Void is not used for compatibility +with other compilers. +.PP +.PP +.I des_set_key +calculates a key schedule from all eight bytes of the input key, pointed +to by the +.I key +argument, and outputs the schedule into the +.I des_key_schedule +indicated by the +.I schedule +argument. Make sure to pass a valid eight byte +key; no padding is done. The key schedule may then be used in subsequent +encryption/decryption/checksum operations. Many key schedules may be +cached for later use. The user is responsible to clear keys and schedules +as soon as no longer needed, to prevent their disclosure. +The routine also checks the key +parity, and returns a zero if the key parity is correct (odd), a -1 +indicating a key parity error, or a -2 indicating use of an illegal +weak key. If an error is returned, the key schedule was not created. +.PP +.PP +.I des_ecb_encrypt +is the basic DES encryption routine that encrypts or decrypts a single 8-byte +block in +.B electronic code book +mode. It always transforms the input data, pointed to by +.I input, +into the output data, pointed to by the +.I output +argument. +.PP +If the +.I encrypt +argument is non-zero, the +.I input +(cleartext) is encrypted into the +.I output +(ciphertext) using the key_schedule specified by the +.I schedule +argument, previously set via +.I des_set_key +.PP +If encrypt is zero, the +.I input +(now ciphertext) is decrypted into the +.I output +(now cleartext). +.PP +Input and output may overlap. +.PP +No meaningful value is returned. Void is not used for compatibility +with other compilers. +.PP +.PP +.I des_cbc_encrypt +encrypts/decrypts using the +.B cipher-block-chaining mode of DES. +If the +.I encrypt +argument is non-zero, the routine cipher-block-chain encrypts +the cleartext data pointed to by the +.I input +argument into the ciphertext pointed to by the +.I output +argument, using the key schedule provided by the +.I schedule +argument, and initialization vector provided by the +.I ivec +argument. +If the +.I length +argument is not an integral +multiple of eight bytes, the last block is copied to a temp and zero +filled (highest addresses). The output is ALWAYS an integral multiple +of eight bytes. +.PP +If +.I encrypt +is zero, the routine cipher-block chain decrypts the (now) ciphertext +data pointed to by the +.I input +argument into (now) cleartext pointed to by the +.I output +argument using the key schedule provided by the +.I schedule +argument, and initialization vector provided by the +.I ivec +argument. Decryption ALWAYS operates on integral +multiples of 8 bytes, so it will round the +.I length +provided up to the +appropriate multiple. Consequently, it will always produce the rounded-up +number of bytes of output cleartext. The application must determine if +the output cleartext was zero-padded due to original cleartext lengths that +were not integral multiples of 8. +.PP +No errors or meaningful values are returned. Void is not used for +compatibility with other compilers. +.PP +A characteristic of cbc mode is that changing a single bit of the +cleartext, then encrypting using cbc mode, +affects ALL the subsequent ciphertext. This makes cryptanalysis +much more difficult. However, modifying a single bit of the ciphertext, +then decrypting, only affects the resulting cleartext from +the modified block and the succeeding block. Therefore, +.I des_pcbc_encrypt +is STRONGLY recommended for applications where +indefinite propagation of errors is required in order to detect modifications. +.PP +.PP +.I des_pcbc_encrypt +encrypts/decrypts using a modified block chaining mode. Its calling +sequence is identical to +.I des_cbc_encrypt. +It differs in its error propagation characteristics. +.PP +.I des_pcbc_encrypt +is highly recommended for most encryption purposes, in that +modification of a single bit of the ciphertext will affect ALL the +subsequent (decrypted) cleartext. Similarly, modifying a single bit of +the cleartext will affect ALL the subsequent (encrypted) ciphertext. +"PCBC" mode, on encryption, "xors" both the +cleartext of block N and the ciphertext resulting from block N with the +cleartext for block N+1 prior to encrypting block N+1. +.PP +.I des_cbc_cksum +produces an 8 byte cryptographic checksum by cipher-block-chain +encrypting the cleartext data pointed to by the +.I input +argument. All of the ciphertext output is discarded, except the +last 8-byte ciphertext block, which is written into the area pointed to by +the +.I output +argument. +It uses the key schedule, +provided by the +.I schedule +argument and initialization vector provided by the +.I ivec +argument. +If the +.I length +argument is not an integral +multiple of eight bytes, the last cleartext block is copied to a temp and zero +filled (highest addresses). The output is ALWAYS eight bytes. +.PP +The routine also returns an unsigned long, which is the last (highest address) +half of the 8 byte checksum computed. +.PP +.PP +.I quad_cksum +produces a checksum by chaining quadratic operations on the cleartext data +pointed to by the +.I input +argument. The +.I length +argument specifies the length of the +input -- only exactly that many bytes are included for the checksum, +without any padding. +.PP +The algorithm may be iterated over the same input data, if the +.I out_count +argument is 2, 3 or 4, and the optional +.I output +argument is a non-null pointer . +The default is one iteration, and it will not run +more than 4 times. Multiple iterations run slower, but provide +a longer checksum if desired. The +.I seed +argument provides an 8-byte seed for the first iteration. If multiple iterations are +requested, the results of one iteration are automatically used as +the seed for the next iteration. +.PP +It returns both an unsigned long checksum value, and +if the +.I output +argument is not a null pointer, up to 16 bytes of +the computed checksum are written into the output. +.PP +.PP +.SH FILES +/usr/include/des.h +.br +/usr/lib/libdes.a +.SH "SEE ALSO" +.SH DIAGNOSTICS +.SH BUGS +This software has not yet been compiled or tested on machines other than the +VAX and the IBM PC. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.SH RESTRICTIONS +COPYRIGHT 1985,1986 Massachusetts Institute of Technology +.PP +This software may not be exported outside of the US without a special +license from the US Dept of Commerce. It may be replaced by any secret +key block cipher with block length and key length of 8 bytes, as long +as the interface is the same as described here. diff --git a/eBones/man/ext_srvtab.8 b/eBones/man/ext_srvtab.8 new file mode 100644 index 0000000..af980a9 --- /dev/null +++ b/eBones/man/ext_srvtab.8 @@ -0,0 +1,63 @@ +.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $ +.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ext_srvtab \- extract service key files from Kerberos key distribution center database +.SH SYNOPSIS +ext_srvtab [ +.B \-n +] [ +.B \-r realm +] [ +.B hostname ... +] +.SH DESCRIPTION +.I ext_srvtab +extracts service key files from the Kerberos key distribution center +(KDC) database. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +For each +.I hostname +specified on the command line, +.I ext_srvtab +creates the service key file +.IR hostname -new-srvtab, +containing all the entries in the database with an instance field of +.I hostname. +This new file contains all the keys registered for Kerberos-mediated +service providing programs which use the +.IR krb_get_phost (3) +principal and instance conventions to run on the host +.IR hostname . +If the +.B \-r +option is specified, the realm fields in the extracted file will +match the given realm rather than the local realm. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +.IR hostname -new-srvtab +Service key file generated for +.I hostname +.TP +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. +.SH SEE ALSO +read_service_key(3), krb_get_phost(3) diff --git a/eBones/man/kadmin.8 b/eBones/man/kadmin.8 new file mode 100644 index 0000000..6e15015 --- /dev/null +++ b/eBones/man/kadmin.8 @@ -0,0 +1,158 @@ +.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $ +.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmin \- network utility for Kerberos database administration +.SH SYNOPSIS +.B kadmin [-u user] [-r default_realm] [-m] +.SH DESCRIPTION +This utility provides a unified administration interface to +the +Kerberos +master database. +Kerberos +administrators +use +.I kadmin +to register new users and services to the master database, +and to change information about existing database entries. +For instance, an administrator can use +.I kadmin +to change a user's +Kerberos +password. +A Kerberos administrator is a user with an ``admin'' instance +whose name appears on one of the Kerberos administration access control +lists. If the \-u option is used, +.I user +will be used as the administrator instead of the local user. +If the \-r option is used, +.I default_realm +will be used as the default realm for transactions. Otherwise, +the local realm will be used by default. +If the \-m option is used, multiple requests will be permitted +on only one entry of the admin password. Some sites won't +support this option. + +The +.I kadmin +program communicates over the network with the +.I kadmind +program, which runs on the machine housing the Kerberos master +database. +The +.I kadmind +creates new entries and makes modifications to the database. + +When you enter the +.I kadmin +command, +the program displays a message that welcomes you and explains +how to ask for help. +Then +.I kadmin +waits for you to enter commands (which are described below). +It then asks you for your +.I admin +password before accessing the database. + +Use the +.I add_new_key +(or +.I ank +for short) +command to register a new principal +with the master database. +The command requires one argument, +the principal's name. The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's +new password. If no realm is specified, +the local realm is used unless another was +given on the commandline with the \-r flag. +If no instance is +specified, a null instance is used. If +a realm other than the default realm is specified, +you will need to supply your admin password for +the other realm. + +Use the +.I change_password (cpw) +to change a principal's +Kerberos +password. +The command requires one argument, +the principal's +name. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's new password. +The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. + +Use the +.I change_admin_password (cap) +to change your +.I admin +instance password. +This command requires no arguments. +It prompts you for your old +.I admin +password, then prompts you twice to enter the new +.I admin +password. If this is your first command, +the default realm is used. Otherwise, the realm +used in the last command is used. + +Use the +.I destroy_tickets (dest) +command to destroy your admin tickets explicitly. + +Use the +.I list_requests (lr) +command to get a list of possible commands. + +Use the +.I help +command to display +.IR kadmin's +various help messages. +If entered without an argument, +.I help +displays a general help message. +You can get detailed information on specific +.I kadmin +commands +by entering +.I help +.IR command_name . + +To quit the program, type +.IR quit . + +.SH BUGS +The user interface is primitive, and the command names could be better. + +.SH "SEE ALSO" +kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8) +.br +``A Subsystem Utilities Package for UNIX'' by Ken Raeburn +.SH AUTHORS +Jeffrey I. Schiller, MIT Project Athena +.br +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/man/kadmind.8 b/eBones/man/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/man/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/man/kdb_destroy.8 b/eBones/man/kdb_destroy.8 new file mode 100644 index 0000000..93db466 --- /dev/null +++ b/eBones/man/kdb_destroy.8 @@ -0,0 +1,33 @@ +.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $ +.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_destroy \- destroy Kerberos key distribution center database +.SH SYNOPSIS +kdb_destroy +.SH DESCRIPTION +.I kdb_destroy +deletes a Kerberos key distribution center database. +.PP +The user is prompted to verify that the database should be destroyed. A +response beginning with `y' or `Y' confirms deletion. +Any other response aborts deletion. +.SH DIAGNOSTICS +.TP 20n +"Database cannot be deleted at /kerberos/principal" +The attempt to delete the database failed (probably due to a system or +access permission error). +.TP +"Database not deleted." +The user aborted the deletion. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.SH SEE ALSO +kdb_init(8) diff --git a/eBones/man/kdb_edit.8 b/eBones/man/kdb_edit.8 new file mode 100644 index 0000000..1cfd6ed --- /dev/null +++ b/eBones/man/kdb_edit.8 @@ -0,0 +1,55 @@ +.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $ +.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_edit \- Kerberos key distribution center database editing utility +.SH SYNOPSIS +kdb_edit [ +.B \-n +] +.SH DESCRIPTION +.I kdb_edit +is used to create or change principals stored in the Kerberos key +distribution center (KDC) database. +.PP +When executed, +.I kdb_edit +prompts for the master key string and verifies that it matches the +master key stored in the database. +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +Once the master key has been verified, +.I kdb_edit +begins a prompt loop. The user is prompted for the principal and +instance to be modified. If the entry is not found the user may create +it. +Once an entry is found or created, the user may set the password, +expiration date, maximum ticket lifetime, and attributes. +Default expiration dates, maximum ticket lifetimes, and attributes are +presented in brackets; if the user presses return the default is selected. +There is no default password. +The password RANDOM is interpreted specially, and if entered +the user may have the program select a random DES key for the +principal. +.PP +Upon successfully creating or changing the entry, ``Edit O.K.'' is +printed. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/man/kdb_init.8 b/eBones/man/kdb_init.8 new file mode 100644 index 0000000..54537ad --- /dev/null +++ b/eBones/man/kdb_init.8 @@ -0,0 +1,41 @@ +.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $ +.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_init \- Initialize Kerberos key distribution center database +.SH SYNOPSIS +kdb_init [ +.B realm +] +.SH DESCRIPTION +.I kdb_init +initializes a Kerberos key distribution center database, creating the +necessary principals. +.PP +If the optional +.I realm +argument is not present, +.I kdb_init +prompts for a realm name (defaulting to the definition in /usr/include/krb.h). +After determining the realm to be created, it prompts for +a master key password. The master key password is used to encrypt +every encryption key stored in the database. +.SH DIAGNOSTICS +.TP 20n +"/kerberos/principal: File exists" +An attempt was made to create a database on a machine which already had +an existing database. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/usr/include/krb.h +Include file defining default realm +.SH SEE ALSO +kdb_destroy(8) diff --git a/eBones/man/kdb_util.8 b/eBones/man/kdb_util.8 new file mode 100644 index 0000000..30a3b9f --- /dev/null +++ b/eBones/man/kdb_util.8 @@ -0,0 +1,64 @@ +.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $ +.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_util \- Kerberos key distribution center database utility +.SH SYNOPSIS +kdb_util +.B operation filename +.SH DESCRIPTION +.I kdb_util +allows the Kerberos key distribution center (KDC) database administrator to +perform utility functions on the database. +.PP +.I Operation +must be one of the following: +.TP 10n +.I load +initializes the KDC database with the records described by the +text contained in the file +.IR filename . +Any existing database is overwritten. +.TP +.I dump +dumps the KDC database into a text representation in the file +.IR filename . +.TP +.I slave_dump +performs a database dump like the +.I dump +operation, and additionally creates a semaphore file signalling the +propagation software that an update is available for distribution to +slave KDC databases. +.TP +.I new_master_key +prompts for the old and new master key strings, and then dumps the KDC +database into a text representation in the file +.IR filename . +The keys in the text representation are encrypted in the new master key. +.TP +.I convert_old_db +prompts for the master key string, and then dumps the KDC database into +a text representation in the file +.IR filename . +The existing database is assumed to be encrypted using the old format +(encrypted by the key schedule of the master key); the dumped database +is encrypted using the new format (encrypted directly with master key). +.PP +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +.IR filename .ok +semaphore file created by +.IR slave_dump. diff --git a/eBones/man/kdestroy.1 b/eBones/man/kdestroy.1 new file mode 100644 index 0000000..7099353 --- /dev/null +++ b/eBones/man/kdestroy.1 @@ -0,0 +1,81 @@ +.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $ +.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdestroy \- destroy Kerberos tickets +.SH SYNOPSIS +.B kdestroy +[ +.B \-f +] +[ +.B \-q +] +.SH DESCRIPTION +The +.I kdestroy +utility destroys the user's active +Kerberos +authorization tickets by writing zeros to the file that contains them. +If the ticket file does not exist, +.I kdestroy +displays a message to that effect. +.PP +After overwriting the file, +.I kdestroy +removes the file from the system. +The utility +displays a message indicating the success or failure of the +operation. +If +.I kdestroy +is unable to destroy the ticket file, +the utility will warn you by making your terminal beep. +.PP +In the Athena workstation environment, +the +.I toehold +service automatically destroys your tickets when you +end a workstation session. +If your site does not provide a similar ticket-destroying mechanism, +you can place the +.I kdestroy +command in your +.I .logout +file so that your tickets are destroyed automatically +when you logout. +.PP +The options to +.I kdestroy +are as follows: +.TP 7 +.B \-f +.I kdestroy +runs without displaying the status message. +.TP +.B \-q +.I kdestroy +will not make your terminal beep if it fails to destroy the tickets. +.SH FILES +KRBTKFILE environment variable if set, otherwise +.br +/tmp/tkt[uid] +.SH SEE ALSO +kerberos(1), kinit(1), klist(1) +.SH BUGS +.PP +Only the tickets in the user's current ticket file are destroyed. +Separate ticket files are used to hold root instance and password +changing tickets. These files should probably be destroyed too, or +all of a user's tickets kept in a single ticket file. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena +.br +Bill Sommerfeld, MIT Project Athena diff --git a/eBones/man/kerberos.1 b/eBones/man/kerberos.1 new file mode 100644 index 0000000..c489b88 --- /dev/null +++ b/eBones/man/kerberos.1 @@ -0,0 +1,259 @@ +.\" from: kerberos.1,v 4.7 89/01/23 11:39:33 jtkohl Exp $ +.\" $Id: kerberos.1,v 1.2 1994/07/19 19:27:33 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KERBEROS 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kerberos \- introduction to the Kerberos system + +.SH DESCRIPTION +The +Kerberos +system authenticates +individual users in a network environment. +After authenticating yourself to +Kerberos, +you can use network utilities such as +.IR rlogin , +.IR rcp , +and +.IR rsh +without +having to present passwords to remote hosts and without having to bother +with +.I \.rhosts +files. +Note that these utilities will work without passwords only if +the remote machines you deal with +support the +Kerberos +system. +All Athena timesharing machines and public workstations support +Kerberos. +.PP +Before you can use +Kerberos, +you must register as an Athena user, +and you must make sure you have been added to +the +Kerberos +database. +You can use the +.I kinit +command to find out. +This command +tries to log you into the +Kerberos +system. +.I kinit +will prompt you for a username and password. +Enter your username and password. +If the utility lets you login without giving you a message, +you have already been registered. +.PP +If you enter your username and +.I kinit +responds with this message: +.nf + +Principal unknown (kerberos) + +.fi +you haven't been registered as a +Kerberos +user. +See your system administrator. +.PP +A Kerberos name contains three parts. +The first is the +.I principal name, +which is usually a user's or service's name. +The second is the +.I instance, +which in the case of a user is usually null. +Some users may have privileged instances, however, +such as ``root'' or ``admin''. +In the case of a service, the instance is the +name of the machine on which it runs; i.e. there +can be an +.I rlogin +service running on the machine ABC, which +is different from the rlogin service running on +the machine XYZ. +The third part of a Kerberos name +is the +.I realm. +The realm corresponds to the Kerberos service providing +authentication for the principal. +For example, at MIT there is a Kerberos running at the +Laboratory for Computer Science and one running at +Project Athena. +.PP +When writing a Kerberos name, the principal name is +separated from the instance (if not null) by a period, +and the realm (if not the local realm) follows, preceded by +an ``@'' sign. +The following are examples of valid Kerberos names: +.sp +.nf +.in +8 +billb +jis.admin +srz@lcs.mit.edu +treese.root@athena.mit.edu +.in -8 +.fi +.PP +When you authenticate yourself with +Kerberos, +through either the workstation +.I toehold +system or the +.I kinit +command, +Kerberos +gives you an initial +Kerberos +.IR ticket . +(A +Kerberos +ticket +is an encrypted protocol message that provides authentication.) +Kerberos +uses this ticket for network utilities +such as +.I rlogin +and +.IR rcp . +The ticket transactions are done transparently, +so you don't have to worry about their management. +.PP +Note, however, that tickets expire. +Privileged tickets, such as root instance tickets, +expire in a few minutes, while tickets that carry more ordinary +privileges may be good for several hours or a day, depending on the +installation's policy. +If your login session extends beyond the time limit, +you will have to re-authenticate yourself to +Kerberos +to get new tickets. +Use the +.IR kinit +command to re-authenticate yourself. +.PP +If you use the +.I kinit +command to get your tickets, +make sure you use the +.I kdestroy +command +to destroy your tickets before you end your login session. +You should probably put the +.I kdestroy +command in your +.I \.logout +file so that your tickets will be destroyed automatically when you logout. +For more information about the +.I kinit +and +.I kdestroy +commands, +see the +.I kinit(1) +and +.I kdestroy(1) +manual pages. +.PP +Currently, +Kerberos +supports the following network services: +.IR rlogin , +.IR rsh , +and +.IR rcp . +Other services are being worked on, +such as the +.IR pop +mail system and NFS (network file system), +but are not yet available. + +.SH "SEE ALSO" +kdestroy(1), kinit(1), klist(1), kpasswd(1), des_crypt(3), kerberos(3), +kadmin(8) +.SH BUGS +Kerberos +will not do authentication forwarding. +In other words, +if you use +.I rlogin +to login to a remote host, +you cannot use +Kerberos +services from that host +until you authenticate yourself explicitly on that host. +Although you may need to authenticate yourself on the remote +host, +be aware that when you do so, +.I rlogin +sends your password across the network in clear text. + +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena + +The following people helped out on various aspects of the system: + +Jeff Schiller designed and wrote the administration server and its +user interface, kadmin. +He also wrote the dbm version of the database management system. + +Mark Colan developed the +Kerberos +versions of +.IR rlogin , +.IR rsh , +and +.IR rcp , +as well as contributing work on the servers. + +John Ostlund developed the +Kerberos +versions of +.I passwd +and +.IR userreg . + +Stan Zanarotti pioneered Kerberos in a foreign realm (LCS), +and made many contributions based on that experience. + +Many people contributed code and/or useful ideas, including +Jim Aspnes, +Bob Baldwin, +John Barba, +Richard Basch, +Jim Bloom, +Bill Bryant, +Rob French, +Dan Geer, +David Jedlinsky, +John Kohl, +John Kubiatowicz, +Bob McKie, +Brian Murphy, +Ken Raeburn, +Chris Reed, +Jon Rochlis, +Mike Shanzer, +Bill Sommerfeld, +Jennifer Steiner, +Ted Ts'o, +and +Win Treese. + +.SH RESTRICTIONS + +COPYRIGHT 1985,1986 Massachusetts Institute of Technology diff --git a/eBones/man/kerberos.3 b/eBones/man/kerberos.3 new file mode 100644 index 0000000..30fa885 --- /dev/null +++ b/eBones/man/kerberos.3 @@ -0,0 +1,461 @@ +.\" from: kerberos.3,v 4.9 89/01/23 16:28:19 steiner Exp $ +.\" $Id: kerberos.3,v 1.2 1994/07/19 19:27:35 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.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/eBones/man/kerberos.point b/eBones/man/kerberos.point new file mode 100644 index 0000000..a75ae2c --- /dev/null +++ b/eBones/man/kerberos.point @@ -0,0 +1 @@ +.so man3/kerberos.3 diff --git a/eBones/man/kinit.1 b/eBones/man/kinit.1 new file mode 100644 index 0000000..f9a97a7 --- /dev/null +++ b/eBones/man/kinit.1 @@ -0,0 +1,133 @@ +.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $ +.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kinit \- Kerberos login utility +.SH SYNOPSIS +.B kinit +[ +.B \-irvl +] +.SH DESCRIPTION +The +.I kinit +command is used to login to the +Kerberos +authentication and authorization system. +Note that only registered +Kerberos +users can use the +Kerberos +system. +For information about registering as a +Kerberos +user, +see the +.I kerberos(1) +manual page. +.PP +If you are logged in to a workstation that is running the +.I toehold +service, +you do not have to use +.I kinit. +The +.I toehold +login procedure will log you into +Kerberos +automatically. +You will need to use +.I kinit +only in those situations in which +your original tickets have expired. +(Tickets expire in about a day.) +Note as well that +.I toehold +will automatically destroy your tickets when you logout from the workstation. +.PP +When you use +.I kinit +without options, +the utility +prompts for your username and Kerberos password, +and tries to authenticate your login with the local +Kerberos +server. +.PP +If +Kerberos +authenticates the login attempt, +.I kinit +retrieves your initial ticket and puts it in the ticket file specified by +your KRBTKFILE environment variable. +If this variable is undefined, +your ticket will be stored in the +.IR /tmp +directory, +in the file +.I tktuid , +where +.I uid +specifies your user identification number. +.PP +If you have logged in to +Kerberos +without the benefit of the workstation +.I toehold +system, +make sure you use the +.I kdestroy +command to destroy any active tickets before you end your login session. +You may want to put the +.I kdestroy +command in your +.I \.logout +file so that your tickets will be destroyed automatically when you logout. +.PP +The options to +.I kinit +are as follows: +.TP 7 +.B \-i +.I kinit +prompts you for a +Kerberos +instance. +.TP +.B \-r +.I kinit +prompts you for a +Kerberos +realm. +This option lets you authenticate yourself with a remote +Kerberos +server. +.TP +.B \-v +Verbose mode. +.I kinit +prints the name of the ticket file used, and +a status message indicating the success or failure of +your login attempt. +.TP +.B \-l +.I kinit +prompts you for a ticket lifetime in minutes. Due to protocol +restrictions in Kerberos Version 4, this value must be between 5 and +1275 minutes. +.SH SEE ALSO +.PP +kerberos(1), kdestroy(1), klist(1), toehold(1) +.SH BUGS +The +.B \-r +option has not been fully implemented. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena diff --git a/eBones/man/klist.1 b/eBones/man/klist.1 new file mode 100644 index 0000000..a66e668 --- /dev/null +++ b/eBones/man/klist.1 @@ -0,0 +1,84 @@ +.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $ +.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +klist \- list currently held Kerberos tickets +.SH SYNOPSIS +.B klist +[ +\fB\-s \fR|\fB \-t\fR +] [ +.B \-file +name ] [ +.B \-srvtab +] +.br +.SH DESCRIPTION +.I klist +prints the name of the tickets file and the +identity of the principal the tickets are for (as listed in the +tickets file), and +lists the principal names of all Kerberos tickets currently held by +the user, along with the issue and expire time for each authenticator. +Principal names are listed in the form +.I name.instance@realm, +with the '.' omitted if the instance is null, +and the '@' omitted if the realm is null. + +If given the +.B \-s +option, +.I klist +does not print the issue and expire times, the name of the tickets file, +or the identity of the principal. + +If given the +.B \-t +option, +.B klist +checks for the existence of a non-expired ticket-granting-ticket in the +ticket file. If one is present, it exits with status 0, else it exits +with status 1. No output is generated when this option is specified. + +If given the +.B \-file +option, the following argument is used as the ticket file. +Otherwise, if the +.B KRBTKFILE +environment variable is set, it is used. +If this environment variable +is not set, the file +.B /tmp/tkt[uid] +is used, where +.B uid +is the current user-id of the user. + +If given the +.B \-srvtab +option, the file is treated as a service key file, and the names of the +keys contained therein are printed. If no file is +specified with a +.B \-file +option, the default is +.IR /etc/srvtab . +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm +.TP +/tmp/tkt[uid] +as the default ticket file ([uid] is the decimal UID of the user). +.TP +/etc/srvtab +as the default service key file +.SH SEE ALSO +.PP +kerberos(1), kinit(1), kdestroy(1) +.SH BUGS +When reading a file as a service key file, very little sanity or error +checking is performed. diff --git a/eBones/man/klogind.8 b/eBones/man/klogind.8 new file mode 100644 index 0000000..459cd26 --- /dev/null +++ b/eBones/man/klogind.8 @@ -0,0 +1,122 @@ +.\" from: klogind.8,v 4.1 89/01/23 11:39:30 jtkohl Exp $ +.\" $Id: klogind.8,v 1.2 1994/07/19 19:27:39 g89r4222 Exp $ +.\" +.\" Copyright (c) 1983 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)rlogind.8 6.4 (Berkeley) 9/19/88 +.\" +.TH KLOGIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.UC 5 +.SH NAME +klogind \- remote login server +.SH SYNOPSIS +.B /usr/etc/klogind +.br +.B /usr/etc/Klogind +.br +.B /usr/etc/eklogind +.SH DESCRIPTION +.I Klogind +is the server for the Kerberos version of the +.IR rlogin (1) +program. The server provides a remote login facility +with authentication provided by Kerberos. +.PP +.I Klogind +listens for service requests at the port indicated in +the ``klogin'' or ``eklogin'' service specification; see +.IR services (5). +.PP +Invocation as Klogind is intended for secure +hosts to which no password access will be granted; invocation as klogind +is intended for normal hosts to which password access may be granted if +Kerberos authorization fails; invocation as eklogind provides an +encrypted communications channel. A host can run either Klogind or +klogind but not both (they use the same port, ``klogin''). Eklogind may +be run independently. +.PP +When a service request is received, the server checks the client's +source address and requests the corresponding host name (see +.IR gethostbyaddr (3N), +.IR hosts (5) +and +.IR named (8)). +If the hostname cannot be determined, +the dot-notation representation of the host address is used. +.PP +Once the source address has been checked, +.I klogind +allocates a pseudo terminal (see +.IR pty (4)), +and manipulates file descriptors so that the slave +half of the pseudo terminal becomes the +.B stdin , +.B stdout , +and +.B stderr +for a login process. +The login process is an instance of the +.IR login (1) +program, invoked with the +.B \-k, +.B \-K, +or +.B \-e +option, depending on whether the klogind was started as klogind, Klogind +or eklogind, respectively. +The login process then proceeds with the +authentication process as described in +.IR kshd (8), +but if automatic authentication fails, it reprompts the user +to login as one finds on a standard terminal line. +.PP +The parent of the login process manipulates the master side of +the pseudo terminal, operating as an intermediary +between the login process and the client instance of the +.I rlogin +program. If klogind is invoked as eklogind, all data passed over +the network are encrypted. +In normal operation, the packet protocol described +in +.IR pty (4) +is invoked to provide ^S/^Q type facilities and propagate +interrupt signals to the remote programs. The login process +propagates the client terminal's baud rate and terminal type, +as found in the environment variable, ``TERM''; see +.IR environ (7). +The screen or window size of the terminal is requested from the client, +and window size changes from the client are propagated to the pseudo terminal. +.SH DIAGNOSTICS +All diagnostic messages are returned on the connection +associated with the +.BR stderr , +after which any network connections are closed. +An error is indicated by a leading byte with a value of 1. +.PP +.B ``Try again.'' +.br +A +.I fork +by the server failed. +.PP +.B ``/bin/sh: ...'' +.br +The user's login shell could not be started. +.SH SEE ALSO +kerberos(3) +.SH BUGS +.PP +A more extensible protocol should be used. diff --git a/eBones/man/kpasswd.1 b/eBones/man/kpasswd.1 new file mode 100644 index 0000000..2283f1f --- /dev/null +++ b/eBones/man/kpasswd.1 @@ -0,0 +1,86 @@ +.\" from: kpasswd.1,v 4.2 89/07/25 17:23:08 jtkohl Exp $ +.\" $Id: kpasswd.1,v 1.2 1994/07/19 19:27:40 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KPASSWD 1 "Kerberos Version 4.0" "MIT Project Athena" +.FM mit +.SH NAME +kpasswd \- change a user's Kerberos password +.SH SYNOPSIS +.B kpasswd +[ +.B \-h +] [ +.B \-n +.I name +] [ +.B \-i +.I instance +] [ +.B \-r +.I realm +] [ +\-u +.IR username[.instance][@realm] ] +.SH DESCRIPTION +The +.I kpasswd +command is used to change a Kerberos principal's password. +.PP +If the +.I \-h +option is specified, a brief summary of the options is printed, and +.I kpasswd +then exits. +.PP +If the +.I \-n +option is specified, +.I name +is used as the principal name rather than the username of the user +running +.IR kpasswd . +(This is determined from the ticket file if it exists; +otherwise, it is determined from the unix user id.) +.PP +If the +.I \-i +option is specified, +.I instance +is used as the instance rather than a null instance. +.PP +If the +.I \-r +option is specified, +.I realm +is used as the realm rather than the local realm. +.PP +If the +.I \-u +option is specified, a fully qualified kerberos +principal can be given. +.PP + +The utility prompts for the current Kerberos password (printing +the name of the principal for which it intends to change the password), +which is verified by the Kerberos server. If the old password is +correct, the user is prompted twice for the new password. A message is +printed indicating the success or failure of the password changing +operation. + +.SH BUGS + +.I kpasswd +does not handle names, instances, or realms with special +characters in them when the -n, -i, or -r options are used. Any +valid fullname is accepted, however, if the -u option is used. + +If the principal whose password you are trying to change does +not exist, you will not be told until after you have entered the +old password. + +.SH SEE ALSO +kerberos(1), kinit(1), passwd(1), kadmin(8) diff --git a/eBones/man/krb.conf.5 b/eBones/man/krb.conf.5 new file mode 100644 index 0000000..ac977bb --- /dev/null +++ b/eBones/man/krb.conf.5 @@ -0,0 +1,32 @@ +.\" from: krb.conf.5,v 4.1 89/01/23 11:10:34 jtkohl Exp $ +.\" $Id: krb.conf.5,v 1.2 1994/07/19 19:27:43 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB.CONF 5 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +/etc/krb.conf \- Kerberos configuration file +.SH DESCRIPTION +.I krb.conf +contains configuration information describing the Kerberos realm and the +Kerberos key distribution center (KDC) servers for known realms. +.PP +.I krb.conf +contains the name of the local realm in the first +line, followed by lines indicating realm/host +entries. The first token is a realm name, and the second is the hostname +of a host running a KDC for that realm. +The words "admin server" following the hostname indicate that +the host also provides an administrative database server. +For example: +.nf +.in +1i +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 +.in -1i +.SH SEE ALSO +krb.realms(5), krb_get_krbhst(3), krb_get_lrealm(3) diff --git a/eBones/man/krb.realms.5 b/eBones/man/krb.realms.5 new file mode 100644 index 0000000..90226a9 --- /dev/null +++ b/eBones/man/krb.realms.5 @@ -0,0 +1,39 @@ +.\" from: krb.realms.5,v 4.1 89/01/23 11:10:41 jtkohl Exp $ +.\" $Id: krb.realms.5,v 1.2 1994/07/19 19:27:45 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB.REALMS 5 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +/etc/krb.realms \- host to Kerberos realm translation file +.SH DESCRIPTION +.I krb.realms +provides a translation from a hostname to the Kerberos realm name for +the services provided by that host. +.PP +Each line of the translation file is in one of the following forms +(domain_name should be of the form .XXX.YYY, e.g. .LCS.MIT.EDU): +.nf +.in +5n +host_name kerberos_realm +domain_name kerberos_realm +.in -5n +.fi +If a hostname exactly matches the +.I host_name +field in a line of the first +form, the corresponding realm is the realm of the host. +If a hostname does not match any +.I host_name +in the file, but its +domain exactly matches the +.I domain_name +field in a line of the second +form, the corresponding realm is the realm of the host. +.PP +If no translation entry applies, the host's realm is considered to be +the hostname's domain portion converted to upper case. +.SH SEE ALSO +krb_realmofhost(3) diff --git a/eBones/man/krb_realmofhost.3 b/eBones/man/krb_realmofhost.3 new file mode 100644 index 0000000..f284069 --- /dev/null +++ b/eBones/man/krb_realmofhost.3 @@ -0,0 +1,161 @@ +.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $ +.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst, +krb_get_lrealm \- additional Kerberos utility routines +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.ft B +char *krb_realmofhost(host) +char *host; +.PP +.ft B +char *krb_get_phost(alias) +char *alias; +.PP +.ft B +krb_get_krbhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_admhst(host,realm,n) +char *host; +char *realm; +int n; +.PP +.ft B +krb_get_lrealm(realm,n) +char *realm; +int n; +.fi +.ft R +.SH DESCRIPTION +.I krb_realmofhost +returns the Kerberos realm of the host +.IR host , +as determined by the translation table +.IR /etc/krb.realms . +.I host +should be the fully-qualified domain-style primary host name of the host +in question. In order to prevent certain security attacks, this routine +must either have +.I a priori +knowledge of a host's realm, or obtain such information securely. +.PP +The format of the translation file is described by +.IR krb.realms (5). +If +.I host +exactly matches a host_name line, the corresponding realm +is returned. +Otherwise, if the domain portion of +.I host +matches a domain_name line, the corresponding realm +is returned. +If +.I host +contains a domain, but no translation is found, +.IR host 's +domain is converted to upper-case and returned. +If +.I host +contains no discernable domain, or an error occurs, +the local realm name, as supplied by +.IR krb_get_lrealm (3), +is returned. +.PP +.I krb_get_phost +converts the hostname +.I alias +(which can be either an official name or an alias) into the instance +name to be used in obtaining Kerberos tickets for most services, +including the Berkeley rcmd suite (rlogin, rcp, rsh). +.br +The current convention is to return the first segment of the official +domain-style name after conversion to lower case. +.PP +.I krb_get_krbhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos key distribution center (KDC) +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +The configuration file is described by +.IR krb.conf (5). +If the host is successfully filled in, the routine +returns KSUCCESS. +If the file cannot be opened, and +.I n +equals 1, then the value of KRB_HOST as defined in +.I <krb.h> +is filled in, and KSUCCESS is returned. If there are fewer than +.I n +hosts running a Kerberos KDC for the requested realm, or the +configuration file is malformed, the routine +returns KFAILURE. +.PP +.I krb_get_admhst +fills in +.I host +with the hostname of the +.IR n th +host running a Kerberos KDC database administration server +for realm +.IR realm , +as specified in the configuration file (\fI/etc/krb.conf\fR). +If the file cannot be opened or is malformed, or there are fewer than +.I n +hosts running a Kerberos KDC database administration server, +the routine returns KFAILURE. +.PP +The character arrays used as return values for +.IR krb_get_krbhst , +.IR krb_get_admhst , +should be large enough to +hold any hostname (MAXHOSTNAMELEN from <sys/param.h>). +.PP +.I krb_get_lrealm +fills in +.I realm +with the +.IR n th +realm of the local host, as specified in the configuration file. +.I realm +should be at least REALM_SZ (from +.IR <krb.h>) characters long. +.PP +.SH SEE ALSO +kerberos(3), krb.conf(5), krb.realms(5) +.SH FILES +.TP 20n +/etc/krb.realms +translation file for host-to-realm mapping. +.TP +/etc/krb.conf +local realm-name and realm/server configuration file. +.SH BUGS +The current convention for instance names is too limited; the full +domain name should be used. +.PP +.I krb_get_lrealm +currently only supports +.I n += 1. It should really consult the user's ticket cache to determine the +user's current realm, rather than consulting a file on the host. diff --git a/eBones/man/krb_sendauth.3 b/eBones/man/krb_sendauth.3 new file mode 100644 index 0000000..f5e95b7 --- /dev/null +++ b/eBones/man/krb_sendauth.3 @@ -0,0 +1,348 @@ +.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $ +.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $ +.\" Copyright 1988 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \- +Kerberos routines for sending authentication via network stream sockets +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +#include <des.h> +#include <netinet/in.h> +.PP +.fi +.HP 1i +.ft B +int krb_sendauth(options, fd, ktext, service, inst, realm, checksum, +msg_data, cred, schedule, laddr, faddr, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst, *realm; +u_long checksum; +MSG_DAT *msg_data; +CREDENTIALS *cred; +Key_schedule schedule; +struct sockaddr_in *laddr, *faddr; +char *version; +.PP +.fi +.HP 1i +.ft B +int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr, +auth_data, filename, schedule, version) +.nf +.RS 0 +.ft B +long options; +int fd; +KTEXT ktext; +char *service, *inst; +struct sockaddr_in *faddr, *laddr; +AUTH_DAT *auth_data; +char *filename; +Key_schedule schedule; +char *version; +.PP +.ft B +int krb_net_write(fd, buf, len) +int fd; +char *buf; +int len; +.PP +.ft B +int krb_net_read(fd, buf, len) +int fd; +char *buf; +int len; +.fi +.SH DESCRIPTION +.PP +These functions, +which are built on top of the core Kerberos library, +provide a convenient means for client and server +programs to send authentication messages +to one another through network connections. +The +.I krb_sendauth +function sends an authenticated ticket from the client program to +the server program by writing the ticket to a network socket. +The +.I krb_recvauth +function receives the ticket from the client by +reading from a network socket. + +.SH KRB_SENDAUTH +.PP +This function writes the ticket to +the network socket specified by the +file descriptor +.IR fd, +returning KSUCCESS if the write proceeds successfully, +and an error code if it does not. + +The +.I ktext +argument should point to an allocated KTEXT_ST structure. +The +.IR service, +.IR inst, +and +.IR realm +arguments specify the server program's Kerberos principal name, +instance, and realm. +If you are writing a client that uses the local realm exclusively, +you can set the +.I realm +argument to NULL. + +The +.I version +argument allows the client program to pass an application-specific +version string that the server program can then match against +its own version string. +The +.I version +string can be up to KSEND_VNO_LEN (see +.IR <krb.h> ) +characters in length. + +The +.I checksum +argument can be used to pass checksum information to the +server program. +The client program is responsible for specifying this information. +This checksum information is difficult to corrupt because +.I krb_sendauth +passes it over the network in encrypted form. +The +.I checksum +argument is passed as the checksum argument to +.IR krb_mk_req . + +You can set +.IR krb_sendauth's +other arguments to NULL unless you want the +client and server programs to mutually authenticate +themselves. +In the case of mutual authentication, +the client authenticates itself to the server program, +and demands that the server in turn authenticate itself to +the client. + +.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION +.PP +If you want mutual authentication, +make sure that you read all pending data from the local socket +before calling +.IR krb_sendauth. +Set +.IR krb_sendauth's +.I options +argument to +.BR KOPT_DO_MUTUAL +(this macro is defined in the +.IR krb.h +file); +make sure that the +.I laddr +argument points to +the address of the local socket, +and that +.I faddr +points to the foreign socket's network address. + +.I Krb_sendauth +fills in the other arguments-- +.IR msg_data , +.IR cred , +and +.IR schedule --before +sending the ticket to the server program. +You must, however, allocate space for these arguments +before calling the function. + +.I Krb_sendauth +supports two other options: +.BR KOPT_DONT_MK_REQ, +and +.BR KOPT_DONT_CANON. +If called with +.I options +set as KOPT_DONT_MK_REQ, +.I krb_sendauth +will not use the +.I krb_mk_req +function to retrieve the ticket from the Kerberos server. +The +.I ktext +argument must point to an existing ticket and authenticator (such as +would be created by +.IR krb_mk_req ), +and the +.IR service, +.IR inst, +and +.IR realm +arguments can be set to NULL. + +If called with +.I options +set as KOPT_DONT_CANON, +.I krb_sendauth +will not convert the service's instance to canonical form using +.IR krb_get_phost (3). + +If you want to call +.I krb_sendauth +with a multiple +.I options +specification, +construct +.I options +as a bitwise-OR of the options you want to specify. + +.SH KRB_RECVAUTH +.PP +The +.I krb_recvauth +function +reads a ticket/authenticator pair from the socket pointed to by the +.I fd +argument. +Set the +.I options +argument +as a bitwise-OR of the options desired. +Currently only KOPT_DO_MUTUAL is useful to the receiver. + +The +.I ktext +argument +should point to an allocated KTEXT_ST structure. +.I Krb_recvauth +fills +.I ktext +with the +ticket/authenticator pair read from +.IR fd , +then passes it to +.IR krb_rd_req . + +The +.I service +and +.I inst +arguments +specify the expected service and instance for which the ticket was +generated. They are also passed to +.IR krb_rd_req. +The +.I inst +argument may be set to "*" if the caller wishes +.I krb_mk_req +to fill in the instance used (note that there must be space in the +.I inst +argument to hold a full instance name, see +.IR krb_mk_req (3)). + +The +.I faddr +argument +should point to the address of the peer which is presenting the ticket. +It is also passed to +.IR krb_rd_req . + +If the client and server plan to mutually authenticate +one another, +the +.I laddr +argument +should point to the local address of the file descriptor. +Otherwise you can set this argument to NULL. + +The +.I auth_data +argument +should point to an allocated AUTH_DAT area. +It is passed to and filled in by +.IR krb_rd_req . +The checksum passed to the corresponding +.I krb_sendauth +is available as part of the filled-in AUTH_DAT area. + +The +.I filename +argument +specifies the filename +which the service program should use to obtain its service key. +.I Krb_recvauth +passes +.I filename +to the +.I krb_rd_req +function. +If you set this argument to "", +.I krb_rd_req +looks for the service key in the file +.IR /etc/srvtab. + +If the client and server are performing mutual authenication, +the +.I schedule +argument +should point to an allocated Key_schedule. +Otherwise it is ignored and may be NULL. + +The +.I version +argument should point to a character array of at least KSEND_VNO_LEN +characters. It is filled in with the version string passed by the client to +.IR krb_sendauth. +.PP +.SH KRB_NET_WRITE AND KRB_NET_READ +.PP +The +.I krb_net_write +function +emulates the write(2) system call, but guarantees that all data +specified is written to +.I fd +before returning, unless an error condition occurs. +.PP +The +.I krb_net_read +function +emulates the read(2) system call, but guarantees that the requested +amount of data is read from +.I fd +before returning, unless an error condition occurs. +.PP +.SH BUGS +.IR krb_sendauth, +.IR krb_recvauth, +.IR krb_net_write, +and +.IR krb_net_read +will not work properly on sockets set to non-blocking I/O mode. + +.SH SEE ALSO + +krb_mk_req(3), krb_rd_req(3), krb_get_phost(3) + +.SH AUTHOR +John T. Kohl, MIT Project Athena +.SH RESTRICTIONS +Copyright 1988, Massachusetts Instititute of Technology. +For copying and distribution information, +please see the file <mit-copyright.h>. diff --git a/eBones/man/krb_set_tkt_string.3 b/eBones/man/krb_set_tkt_string.3 new file mode 100644 index 0000000..c9f3dcf --- /dev/null +++ b/eBones/man/krb_set_tkt_string.3 @@ -0,0 +1,43 @@ +.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $ +.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +krb_set_tkt_string \- set Kerberos ticket cache file name +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +void krb_set_tkt_string(filename) +char *filename; +.fi +.ft R +.SH DESCRIPTION +.I krb_set_tkt_string +sets the name of the file that holds the user's +cache of Kerberos server tickets and associated session keys. +.PP +The string +.I filename +passed in is copied into local storage. +Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are +copied in for use as the cache file name. +.PP +This routine should be called during initialization, before other +Kerberos routines are called; otherwise the routines which fetch the +ticket cache file name may be called and return an undesired ticket file +name until this routine is called. +.SH FILES +.TP 20n +/tmp/tkt[uid] +default ticket file name, unless the environment variable KRBTKFILE is set. +[uid] denotes the user's uid, in decimal. +.SH SEE ALSO +kerberos(3), setenv(3) diff --git a/eBones/man/ksend.point b/eBones/man/ksend.point new file mode 100644 index 0000000..2dbe5de --- /dev/null +++ b/eBones/man/ksend.point @@ -0,0 +1 @@ +.so man3/krb_sendauth.3 diff --git a/eBones/man/kshd.8 b/eBones/man/kshd.8 new file mode 100644 index 0000000..e1ecc22 --- /dev/null +++ b/eBones/man/kshd.8 @@ -0,0 +1,152 @@ +.\" from: kshd.8,v 4.1 89/01/23 11:39:41 jtkohl Exp $ +.\" $Id: kshd.8,v 1.2 1994/07/19 19:27:50 g89r4222 Exp $ +.\" +.\" Copyright (c) 1983 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)rshd.8 6.5 (Berkeley) 9/19/88 +.\" +.TH KSHD 8 "Kerberos Version 4.0" "MIT Project Athena" +.UC 5 +.SH NAME +kshd \- remote shell server +.SH SYNOPSIS +.B /usr/etc/kshd +.SH DESCRIPTION +.I Kshd +is the server for the +.IR kcmd (3) +routine and, consequently, for the +.IR rsh (1) +program. The server provides remote execution facilities +with authentication based on Kerberos. +.PP +.I Kshd +listens for service requests at the port indicated in +the ``kshell'' service specification; see +.IR services (5). +When a service request is received the following protocol +is initiated: +.IP 1) +The server reads characters from the socket up +to a null (`\e0') byte. The resultant string is +interpreted as an ASCII number, base 10. +.IP 2) +If the number received in step 1 is non-zero, +it is interpreted as the port number of a secondary +stream to be used for the +.BR stderr . +A second connection is then created to the specified +port on the client's machine. +.IP 3) +The server checks the client's source address +and requests the corresponding host name (see +.IR gethostbyaddr (3N), +.IR hosts (5) +and +.IR named (8)). +If the hostname cannot be determined, +the dot-notation representation of the host address is used. +.IP 4) +A Kerberos ticket/authenticator pair are retrieved on the initial socket. +.IP 5) +A null terminated user name of at most 16 characters +is retrieved on the initial socket. This user name +is interpreted as a user identity to use on the +.BR server 's +machine. +.IP 6) +A null terminated command to be passed to a +shell is retrieved on the initial socket. The length of +the command is limited by the upper bound on the size of +the system's argument list. +.IP 7) +.I Kshd +then validates the user according to the following steps. +The local (server-end) user name is looked up in the password file +and a +.I chdir +is performed to the user's home directory. If either +the lookup or +.I chdir +fail, the connection is terminated. The \&.klogin file in the home +directory is used to mediate access to the account (via \fIkuserok\fP(3)) +by the Kerberos principal named in the ticket/authenticator. If this +authorization check fails, the connection is terminated. +.IP 8) +A null byte is returned on the initial socket +and the command line is passed to the normal login +shell of the user. The +shell inherits the network connections established +by +.IR kshd . +.SH DIAGNOSTICS +Except for the last one listed below, +all diagnostic messages +are returned on the initial socket, +after which any network connections are closed. +An error is indicated by a leading byte with a value of +1 (0 is returned in step 8 above upon successful completion +of all the steps prior to the execution of the login shell). +.PP +.B ``remuser too long'' +.br +The name of the user on the remote machine is +longer than 16 characters. +.PP +.B ``command too long '' +.br +The command line passed exceeds the size of the argument +list (as configured into the system). +.PP +.B ``Login incorrect.'' +.br +No password file entry for the user name existed. +.PP +.B ``No remote directory.'' +.br +The +.I chdir +command to the home directory failed. +.PP +.B ``Permission denied.'' +.br +The authorization procedure described above failed. +.PP +.B ``Can't make pipe.'' +.br +The pipe needed for the +.BR stderr , +wasn't created. +.PP +.B ``Try again.'' +.br +A +.I fork +by the server failed. +.PP +.B ``<shellname>: ...'' +.br +The user's login shell could not be started. This message is returned +on the connection associated with the +.BR stderr , +and is not preceded by a flag byte. +.SH SEE ALSO +rsh(1), kerberos(3), kuserok(3) +.SH BUGS +A facility to allow all data exchanges to be encrypted should be +present. +.PP +A more extensible protocol should be used. diff --git a/eBones/man/ksrvtgt.1 b/eBones/man/ksrvtgt.1 new file mode 100644 index 0000000..25fd939 --- /dev/null +++ b/eBones/man/ksrvtgt.1 @@ -0,0 +1,51 @@ +.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $ +.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a +service key +.SH SYNOPSIS +.B ksrvtgt +name instance [[realm] srvtab] +.SH DESCRIPTION +.I ksrvtgt +retrieves a ticket-granting ticket with a lifetime of five (5) minutes +for the principal +.I name.instance@realm +(or +.I name.instance@localrealm +if +.I realm +is not supplied on the command line), decrypts the response using +the service key found in +.I srvtab +(or in +.B /etc/srvtab +if +.I srvtab +is not specified on the command line), and stores the ticket in the +standard ticket cache. +.PP +This command is intended primarily for use in shell scripts and other +batch-type facilities. +.SH DIAGNOSTICS +"Generic kerberos failure (kfailure)" can indicate a whole range of +problems, the most common of which is the inability to read the service +key file. +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm. +.TP +/tmp/tkt[uid] +The default ticket file. +.TP +/etc/srvtab +The default service key file. +.SH SEE ALSO +kerberos(1), kinit(1), kdestroy(1) diff --git a/eBones/man/ksrvutil.8 b/eBones/man/ksrvutil.8 new file mode 100644 index 0000000..a7fed82 --- /dev/null +++ b/eBones/man/ksrvutil.8 @@ -0,0 +1,93 @@ +.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $ +.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvutil \- host kerberos keyfile (srvtab) manipulation utility +.SH SYNOPSIS +ksrvutil +.B operation +[ +.B \-k +] [ +.B \-i +] [ +.B \-f filename +] +.SH DESCRIPTION +.I ksrvutil +allows a system manager to list or change keys currently in his +keyfile or to add new keys to the keyfile. +.PP + +Operation must be one of the following: +.TP 10n +.I list +lists the keys in a keyfile showing version number and principal +name. If the \-k option is given, keys will also be shown. +.TP 10n +.I change +changes all the keys in the keyfile by using the regular admin +protocol. If the \-i flag is given, +.I ksrvutil +will prompt for yes or no before changing each key. If the \-k +option is used, the old and new keys will be displayed. +.TP 10n +.I add +allows the user to add a key. +.I add +prompts for name, instance, realm, and key version number, asks +for confirmation, and then asks for a password. +.I ksrvutil +then converts the password to a key and appends the keyfile with +the new information. If the \-k option is used, the key is +displayed. + +.PP +In all cases, the default file used is KEY_FILE as defined in +krb.h unless this is overridden by the \-f option. + +.PP +A good use for +.I ksrvutil +would be for adding keys to a keyfile. A system manager could +ask a kerberos administrator to create a new service key with +.IR kadmin (8) +and could supply an initial password. Then, he could use +.I ksrvutil +to add the key to the keyfile and then to change the key so that +it will be random and unknown to either the system manager or +the kerberos administrator. + +.I ksrvutil +always makes a backup copy of the keyfile before making any +changes. + +.SH DIAGNOSTICS +If +.I ksrvutil +should exit on an error condition at any time during a change or +add, a copy of the +original keyfile can be found in +.IR filename .old +where +.I filename +is the name of the keyfile, and a copy of the file with all new +keys changed or added so far can be found in +.IR filename .work. +The original keyfile is left unmodified until the program exits +at which point it is removed and replaced it with the workfile. +Appending the workfile to the backup copy and replacing the +keyfile with the result should always give a usable keyfile, +although the resulting keyfile will have some out of date keys +in it. + +.SH SEE ALSO +kadmin(8), ksrvtgt(1) + +.SH AUTHOR +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/man/kstash.8 b/eBones/man/kstash.8 new file mode 100644 index 0000000..d83379a --- /dev/null +++ b/eBones/man/kstash.8 @@ -0,0 +1,41 @@ +.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $ +.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kstash \- stash Kerberos key distribution center database master key +.SH SYNOPSIS +kstash +.SH DESCRIPTION +.I kstash +saves the Kerberos key distribution center (KDC) database master key in +the master key cache file. +.PP +The user is prompted to enter the key, to verify the authenticity of the +key and the authorization to store the key in the file. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.TP +"kstash: Unable to open master key file" +The attempt to open the cache file for writing failed (probably due to a +system or access permission error). +.TP +"kstash: Write I/O error on master key file" +The +.BR write (2) +system call returned an error while +.I kstash +was attempting to write the key to the file. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/man/ksu.1 b/eBones/man/ksu.1 new file mode 100644 index 0000000..fe434d3 --- /dev/null +++ b/eBones/man/ksu.1 @@ -0,0 +1,83 @@ +.\" from: ksu.1,v 4.1 89/01/23 11:38:16 jtkohl Exp $ +.\" $Id: ksu.1,v 1.2 1994/07/19 19:27:57 g89r4222 Exp $ +.\" +.\" Copyright (c) 1988 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)su.1 6.7 (Berkeley) 12/7/88 +.\" +.TH KSU 1 "Kerberos Version 4.0" "MIT Project Athena" +.UC +.SH NAME +ksu \- substitute user id, using Kerberos +.SH SYNOPSIS +.B ksu +[-flm] [login] +.SH DESCRIPTION +\fIKsu\fP requests the password for \fIlogin\fP (or for ``root'', if no +login is provided), and switches to that user and group ID. A shell is +then invoked. +.PP +By default, your environment is unmodified with the exception of +\fIUSER\fP, \fIHOME\fP, and \fISHELL\fP. \fIHOME\fP and \fISHELL\fP +are set to the target login's \fI/etc/passwd\fP values. \fIUSER\fP +is set to the target login, unless the target login has a UID of 0, +in which case it is unmodified. The invoked shell is the target +login's. This is the traditional behavior of \fIksu\fP. +.PP +The \fI-l\fP option simulates a full login. The environment is discarded +except for \fIHOME\fP, \fISHELL\fP, \fIPATH\fP, \fITERM\fP, and \fIUSER\fP. +\fIHOME\fP and \fISHELL\fP are modified as above. \fIUSER\fP is set to +the target login. \fIPATH\fP is set to ``/usr/ucb:/bin:/usr/bin''. +\fITERM\fP is imported from your current environment. The invoked shell +is the target login's, and \fIksu\fP will change directory to the target +login's home directory. +.PP +The \fI-m\fP option causes the environment to remain unmodified, and +the invoked shell to be your login shell. No directory changes are +made. As a security precaution, if the +.I -m +option is specified, the target user's shell is a non-standard shell +(as defined by \fIgetusershell\fP(3)) and the caller's real uid is +non-zero, +.I su +will fail. +.PP +If the invoked shell is \fIcsh\fP, the \fI-f\fP option prevents it from +reading the \fI.cshrc\fP file. Otherwise, this option is ignored. +.PP +Only users with root instances listed in /\&.klogin may \fIksu\fP to +``root'' (The format of this file is described by \fIrlogin\fP(1).). When +attempting root access, \fIksu\fP attempts to fetch a +ticket-granting-ticket for ``username.root@localrealm'', where +\fIusername\fP is the username of the process. If possible, the tickets +are used to obtain, use, and verify tickets for the service +``rcmd.host@localrealm'' where \fIhost\fP is the canonical host name (as +determined by +.IR krb_get_phost (3)) +of the machine. If this verification +fails, the \fIksu\fP is disallowed (If the service +``rcmd.host@localrealm'' is not registered, the \fIksu\fP is allowed.). +.PP +By default (unless the prompt is reset by a startup file) the super-user +prompt is set to ``#'' to remind one of its awesome power. +.PP +When not attempting to switch to the ``root'' user, +.I ksu +behaves exactly like +.IR su (1). +.SH "SEE ALSO" +su(1), csh(1), login(1), rlogin(1), sh(1), krb_get_phost(3), passwd(5), +group(5), environ(7) diff --git a/eBones/man/kuserok.3 b/eBones/man/kuserok.3 new file mode 100644 index 0000000..36968ba --- /dev/null +++ b/eBones/man/kuserok.3 @@ -0,0 +1,63 @@ +.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $ +.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kuserok \- Kerberos version of ruserok +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +kuserok(kdata, localuser) +AUTH_DAT *auth_data; +char *localuser; +.fi +.ft R +.SH DESCRIPTION +.I kuserok +determines whether a Kerberos principal described by the structure +.I auth_data +is authorized to login as user +.I localuser +according to the authorization file +("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized, +1 (one) if not authorized. +.PP +If there is no account for +.I localuser +on the local machine, authorization is not granted. +If there is no authorization file, and the Kerberos principal described +by +.I auth_data +translates to +.I localuser +(using +.IR krb_kntoln (3)), +authorization is granted. +If the authorization file +can't be accessed, or the file is not owned by +.IR localuser, +authorization is denied. Otherwise, the file is searched for +a matching principal name, instance, and realm. If a match is found, +authorization is granted, else authorization is denied. +.PP +The file entries are in the format: +.nf +.in +5n + name.instance@realm +.in -5n +.fi +with one entry per line. +.SH SEE ALSO +kerberos(3), ruserok(3), krb_kntoln(3) +.SH FILES +.TP 20n +~\fIlocaluser\fR/.klogin +authorization list diff --git a/eBones/man/rcp.1 b/eBones/man/rcp.1 new file mode 100644 index 0000000..1f298f6 --- /dev/null +++ b/eBones/man/rcp.1 @@ -0,0 +1,129 @@ +.\" from: rcp.1,v 4.1 89/01/23 11:39:00 jtkohl Exp $ +.\" $Id: rcp.1,v 1.2 1994/07/19 19:28:00 g89r4222 Exp $ +.\" +.\" Copyright (c) 1983 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)rcp.1 6.6 (Berkeley) 9/20/88 +.\" +.TH RCP 1 "Kerberos Version 4.0" "MIT Project Athena" +.UC 5 +.SH NAME +rcp \- remote file copy +.SH SYNOPSIS +.B rcp +[ +.B \-p +] [ +.B \-x +] [ +.B \-k +realm ] file1 file2 +.br +.B rcp +[ +.B \-p +] [ +.B \-x +] [ +.B \-k +realm ] [ +.B \-r +] file ... directory +.SH DESCRIPTION +.I Rcp +copies files between machines. Each +.I file +or +.I directory +argument is either a remote file name of the +form ``rhost:path'', or a local file name (containing no `:' characters, +or a `/' before any `:'s). +.PP +If the +.B \-r +option +is specified and any of the source files are directories, +.I rcp +copies each subtree rooted at that name; in this case +the destination must be a directory. +.PP +By default, the mode and owner of +.I file2 +are preserved if it already existed; otherwise the mode of the source file +modified by the +.IR umask (2) +on the destination host is used. +The +.B \-p +option causes +.I rcp +to attempt to preserve (duplicate) in its copies the modification +times and modes of the source files, ignoring the +.IR umask . +.PP +If +.I path +is not a full path name, it is interpreted relative to +your login directory on +.IR rhost . +A +.I path +on a remote host may be quoted (using \e, ", or \(aa) +so that the metacharacters are interpreted remotely. +.PP +.I Rcp +does not prompt for passwords; it uses Kerberos authentication when +connecting to +.IR rhost . +Authorization is as described in +.IR rlogin (1). +.PP +The +.B \-x +option selects encryption of all information transferring between hosts. +The +.B \-k +.I realm +option causes +.I rcp +to obtain tickets for the remote host in +.I realm +instead of the remote host's realm as determined by +.IR krb_realmofhost (3). +.PP +.I Rcp +handles third party copies, where neither source nor target files +are on the current machine. +Hostnames may also take the form ``rname@rhost'' to use +.I rname +rather than the current user name on the remote host. +.SH SEE ALSO +cp(1), ftp(1), rsh(1), rlogin(1), kerberos(3), krb_getrealm(3), +rcp(1) [UCB version] +.SH BUGS +Doesn't detect all cases where the target of a copy might +be a file in cases where only a directory should be legal. +.PP +Is confused by any output generated by commands in a +\&.login, \&.profile, or \&.cshrc file on the remote host. +.PP +The destination user and hostname may have to be specified as +``rhost.rname'' when the destination machine is running the 4.2BSD +version of \fIrcp\fP. +.PP +Kerberos is only used for the first connection of a third-party copy; +the second connection uses the standard Berkeley rcp protocol. + diff --git a/eBones/man/realm.point b/eBones/man/realm.point new file mode 100644 index 0000000..9c6940f --- /dev/null +++ b/eBones/man/realm.point @@ -0,0 +1 @@ +.so man3/krb_realmofhost.3 diff --git a/eBones/man/rlogin.1 b/eBones/man/rlogin.1 new file mode 100644 index 0000000..3e0dc62 --- /dev/null +++ b/eBones/man/rlogin.1 @@ -0,0 +1,199 @@ +.\" from: rlogin.1,v 4.2 89/11/02 11:20:39 jtkohl Exp $ +.\" $Id: rlogin.1,v 1.2 1994/07/19 19:28:01 g89r4222 Exp $ +.\" +.\" Copyright (c) 1983 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)rlogin.1 6.9 (Berkeley) 9/19/88 +.\" +.TH RLOGIN 1 "Kerberos Version 4.0" "MIT Project Athena" +.UC 5 +.SH NAME +rlogin \- remote login +.SH SYNOPSIS +.B rlogin +rhost [ +\fB\-e\fR\fI\|c\fR +] [ +.B \-8 +] [ +.B \-c +] [ +.B \-a +] [ +.B \-t +termtype ] [ +.B \-n +] [ +.B \-7 +] [ +.B \-d +] [ +.B \-k +realm ] [ +.B \-x +] [ +.B \-noflow +] [ +.B \-L +] [ +.B \-l +username ] +.br +rhost [ +\fB\-e\fR\fIc\fR +] [ +.B \-8 +] [ +.B \-c +] [ +.B \-a +] [ +.B \-t +termtype ] [ +.B \-n +] [ +.B \-7 +] [ +.B \-d +] [ +.B \-k +realm ] [ +.B \-x +] [ +.B \-noflow +] [ +.B \-L +] [ +.B \-l +username ] +.SH DESCRIPTION +.I Rlogin +connects your terminal on the current local host system +.I lhost +to the remote host system +.I rhost. +.PP +The version built to use Kerberos authentication is very similar to the +standard Berkeley rlogin(1), except that instead of the \fIrhosts\fP +mechanism, it uses Kerberos authentication to determine the +authorization to use a remote account. +.PP +Each user may have a private authorization list in a file \&.klogin +in his login directory. Each line in this file should contain a +Kerberos principal name of the form +.IR principal.instance@realm . +If the originating user is authenticated to one of the principals named +in \&.klogin, access is granted to the account. The principal +\fIaccountname\fP.@\fIlocalrealm\fP is granted access if there is no +\&.klogin file. +Otherwise +a login and password will be prompted for on the remote machine as in +.IR login (1). +To avoid some security problems, the \&.klogin file must be owned by +the remote user. +.PP +If there is some problem in marshaling the Kerberos authentication +information, an error message is printed and the standard UCB rlogin is +executed in place of the Kerberos rlogin. +.PP +A line of the form ``~.'' disconnects from the remote host, where +``~'' is the escape character. +Similarly, the line ``~^Z'' (where ^Z, control-Z, is the suspend character) +will suspend the rlogin session. +Substitution of the delayed-suspend character (normally ^Y) +for the suspend character suspends the send portion of the rlogin, +but allows output from the remote system. +.PP +The remote terminal type is the same as your local +terminal type (as given in your environment TERM variable), unless the +.B \-t +option is specified (see below). +The terminal or window size is also copied to the remote system +if the server supports the option, +and changes in size are reflected as well. +.PP +All echoing takes place at the remote site, so that (except for +delays) the rlogin is transparent. Flow control via ^S and ^Q and +flushing of input and output on interrupts are handled properly. +.PP +The +.B \-8 +option allows an eight-bit input data path at all times; +otherwise parity bits are stripped except when the remote side's +stop and start characters are other than ^S/^Q. Eight-bit mode is the default. +.PP +The +.B \-L +option allows the rlogin session to be run in litout mode. +.PP +The +.B \-e +option allows specification of a different escape character. +There is no space separating this option flag and the new escape +character. +.PP +The +.B \-c +option requires confirmation before disconnecting via ``~.'' +.PP +The +.B \-a +option forces the remote machine to ask for a password by sending a null local +username. This option has no effect unless the standard UCB rlogin is +executed in place of the Kerberos rlogin (see above). +.PP +The +.B \-t +option replaces the terminal type passed to the remote host with +\fItermtype\fP. +.PP +The +.B \-n +option prevents suspension of rlogin via ``~^Z'' or ``~^Y''. +.PP +The +.B \-7 +option forces seven-bit transmissions. +.PP +The +.B \-d +option turns on socket debugging (via \fIsetsockopt(2)\fR) on the TCP +sockets used for communication with the remote host. +.PP +The +.B \-noflow +option forces transmission of flow control characters (^S/^Q) to the +remote system. +.PP +The +.B \-k +option requests rlogin to obtain tickets for the remote host in realm +.I realm +instead of the remote host's realm as determined by +.IR krb_realmofhost (3). +.PP +The +.B \-x +option turns on DES encryption for all data passed via the +rlogin session. This significantly reduces response time and +significantly increases CPU utilization. +.SH SEE ALSO +rsh(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3), +rlogin(1) [UCB version] +.SH FILES +/usr/hosts/* for \fIrhost\fP version of the command +.SH BUGS +More of the environment should be propagated. diff --git a/eBones/man/rsh.1 b/eBones/man/rsh.1 new file mode 100644 index 0000000..8d0974c --- /dev/null +++ b/eBones/man/rsh.1 @@ -0,0 +1,152 @@ +.\" from: rsh.1,v 4.1 89/01/23 11:39:11 jtkohl Exp $ +.\" $Id: rsh.1,v 1.2 1994/07/19 19:28:03 g89r4222 Exp $ +.\" +.\" Copyright (c) 1983 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)rsh.1 6.2 (Berkeley) 9/20/88 +.\" +.TH RSH 1 "Kerberos Version 4.0" "MIT Project Athena" +.UC 5 +.SH NAME +rsh \- remote shell +.SH SYNOPSIS +.B rsh +host +[ +.B \-l +username +] [ +.B \-n +] [ +.B \-d +] [ +.B \-k +realm ] command +.br +host +[ +.B \-l +username +] [ +.B \-n +] [ +.B \-d +] [ +.B \-k +realm ] command +.SH DESCRIPTION +.I Rsh +connects to the specified +.I host, +and executes the specified \fIcommand\fR. +.I Rsh +copies its standard input to the remote command, the standard +output of the remote command to its standard output, and the +standard error of the remote command to its standard error. +Interrupt, quit and terminate signals are propagated to the remote +command; \fIrsh\fP normally terminates when the remote command does. +.PP +The remote username used is the same as your local username, +unless you specify a different remote name with the +.B \-l +option. +Kerberos authentication is used, and authorization is determined as in +rlogin(1). +.PP +The +.B \-k +\fIrealm\fP option causes +.I rsh +to obtain tickets for the remote host in +.I realm +instead of the remote host's realm as determined by +.IR krb_realmofhost (3). +.PP +The +.B \-d +option turns on socket debugging (via \fIsetsockopt(2)\fR) on the TCP +sockets used for communication with the remote host. +.PP +The +.B \-n +option redirects input from the special device +.I /dev/null +(see the BUGS section below). +.PP +If you omit +.I command, +then instead of executing a single command, you will be logged in +on the remote host using +.IR rlogin (1). +.PP +Shell metacharacters which are not quoted are interpreted +on local machine, while quoted metacharacters are interpreted on +the remote machine. +Thus the command +.PP +\ \ \ rsh otherhost cat remotefile >> localfile +.PP +appends the remote file +.I remotefile +to the local file +.I localfile, +while +.PP +\ \ \ rsh otherhost cat remotefile ">>" otherremotefile +.PP +appends +.I remotefile +to +.I otherremotefile. +.PP +The host names for local machines are also commands in the directory +/usr/hosts; if you put this directory in your search path +then the +.B rsh +on the command line can be omitted. +.SH FILES +.ta 2i +/etc/hosts +.br +/usr/hosts/* +.DT +.SH SEE ALSO +rlogin(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3) +.SH BUGS +If you are using +.IR csh (1) +and put a +.IR rsh (1) +in the background without redirecting its input +away from the terminal, it will block even if no reads +are posted by the remote command. If no input is desired +you should redirect the input of +.I rsh +to /dev/null using the +.B \-n +option. +.PP +You cannot run an interactive command +(like +.IR rogue (6) +or +.IR vi (1)); +use +.IR rlogin (1). +.PP +Stop signals stop the local \fIrsh\fP process only; this is arguably +wrong, but currently hard to fix for reasons too complicated to +explain here. diff --git a/eBones/man/tcom.8 b/eBones/man/tcom.8 new file mode 100644 index 0000000..23317cc --- /dev/null +++ b/eBones/man/tcom.8 @@ -0,0 +1,54 @@ +.\" from: tcom.8,v 4.2 89/05/03 14:34:53 jtkohl Exp $ +.\" $Id: tcom.8,v 1.2 1994/07/19 19:28:04 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TCOM 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tcom \- control operation of server tftp daemon +.SH SYNOPSIS +tcom +.SH DESCRIPTION +.I Tcom +is a program to control the execution of the server trivial file transfer +daemon. It sends user commands to the daemon by writing them into a +shared file and signalling the daemon; it watches the daemon's log to +obtain the results of the commands. The following commands are supported: +.TP 20 +help +display a list of commands +.TP +input trace on|off +turn tracing of input packets on or off +.TP +output trace on|off +turn tracing of output packets on or off +.TP +trace on|off +turn all packet tracing on or off +.TP +times +display server parent and children process times +.TP +uptime +display daemon up time +.TP +exit +force daemon to shut down and exit +.SH FILES +.TP 20 +/tftpd/lock +lock file containing daemon's PID +.TP +/tftpd/command +command file to daemon +.TP +/tftpd/slog +daemon's log file +.SH "SEE ALSO" +tftpd (8) +.SH BUGS +Two tcom's running at the same time will result in chaos. Also, +watching the daemon's log file uses a lot of CPU time. diff --git a/eBones/man/tf_util.3 b/eBones/man/tf_util.3 new file mode 100644 index 0000000..3a9bc94 --- /dev/null +++ b/eBones/man/tf_util.3 @@ -0,0 +1,151 @@ +.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $ +.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \ +\- Routines for manipulating a Kerberos ticket file +.SH SYNOPSIS +.nf +.nj +.ft B +#include <krb.h> +.PP +.ft B +extern char *krb_err_txt[]; +.PP +.ft B +tf_init(tf_name, rw) +char *tf_name; +int rw; +.PP +.ft B +tf_get_pname(pname) +char *pname; +.PP +.ft B +tf_get_pinst(pinst) +char *pinst; +.PP +.ft B +tf_get_cred(c) +CREDENTIALS *c; +.PP +.ft B +tf_close() +.PP +.fi +.SH DESCRIPTION +This group of routines are provided to manipulate the Kerberos tickets +file. A ticket file has the following format: +.nf +.in +4 +.sp +principal's name (null-terminated string) +principal's instance (null-terminated string) +CREDENTIAL_1 +CREDENTIAL_2 + ... +CREDENTIAL_n +EOF +.sp +.in -4 +.LP +Where "CREDENTIAL_x" consists of the following fixed-length +fields from the CREDENTIALS structure (defined in <krb.h>): +.nf +.sp +.in +4 + char service[ANAME_SZ] + char instance[INST_SZ] + char realm[REALM_SZ] + des_cblock session + int lifetime + int kvno + KTEXT_ST ticket_st + long issue_date +.in -4 +.sp +.fi +.PP +.I tf_init +must be called before the other ticket file +routines. +It takes the name of the ticket file to use, +and a read/write flag as arguments. +It tries to open the ticket file, checks the mode and if +everything is okay, locks the file. If it's opened for +reading, the lock is shared. If it's opened for writing, +the lock is exclusive. +KSUCCESS is returned if all went well, otherwise one of the +following: +.nf +.sp +NO_TKT_FIL - file wasn't there +TKT_FIL_ACC - file was in wrong mode, etc. +TKT_FIL_LCK - couldn't lock the file, even after a retry +.sp +.fi +.PP +The +.I tf_get_pname +reads the principal's name from a ticket file. +It should only be called after tf_init has been called. The +principal's name is filled into the +.I pname +parameter. If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If the principal's name was null, or EOF was encountered, or the +name was longer than ANAME_SZ, TKT_FIL_FMT is returned. +.PP +The +.I tf_get_pinst +reads the principal's instance from a ticket file. +It should only be called after tf_init and tf_get_pname +have been called. +The principal's instance is filled into the +.I pinst +parameter. +If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If EOF was encountered, or the +name was longer than INST_SZ, TKT_FIL_FMT is returned. +Note that, unlike the principal name, the instance name may be null. +.PP +The +.I tf_get_cred +routine reads a CREDENTIALS record from a ticket file and +fills in the given structure. +It should only be called after +tf_init, tf_get_pname, and tf_get_pinst have been called. +If all goes well, KSUCCESS is returned. Possible error codes +are: +.nf +.sp +TKT_FIL_INI - tf_init wasn't called first +TKT_FIL_FMT - bad format +EOF - end of file encountered +.sp +.fi +.PP +.I tf_close +closes the ticket file and releases the lock on it. +.SH "SEE ALSO" +krb(3) +.SH DIAGNOSTICS +.SH BUGS +The ticket file routines have to be called in a certain order. +.SH AUTHORS +Jennifer Steiner, MIT Project Athena +.br +Bill Bryant, MIT Project Athena +.SH RESTRICTIONS +Copyright 1987 Massachusetts Institute of Technology diff --git a/eBones/man/tftp.1 b/eBones/man/tftp.1 new file mode 100644 index 0000000..4abd7ac --- /dev/null +++ b/eBones/man/tftp.1 @@ -0,0 +1,66 @@ +.\" from: tftp.1,v 4.1 89/01/23 11:36:23 jtkohl Exp $ +.\" $Id: tftp.1,v 1.2 1994/07/19 19:28:07 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TFTP 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tftp \- trivial file transfer protocol +.SH SYNOPSIS +.B tftp +-action localname host foreignname [mode] +.SH DESCRIPTION +If +.I action +is +.B w, +.B p, +or +.B ap, +.I tftp +writes the local file, called localname, onto the foreign host's +file system as foreignname. If +.I action +is +.B ap, +Kerberos authentication is used. +Note that foreignname must be quoted if it +contains shell special characters. If +.I action +is +.B r, +.B g, +or +.B ag, +.I tftp +reads foreign host's file foreignname into the local file, +localname. If +.I action +is +.B ag, +Kerberos authentication is used. +.I Tftp +will not supersede or overwrite existing local files, however; to do so, +use +.I action +.B o. +.sp 2 +.I Mode +may be +.B netascii, +or +.B image. +Netascii, the default mode, transfers +the file as standard ascii characters. Image mode transfers +the file in binary, with no character conversion. +.sp 1 +If Kerberos authentication is not used with +.B tftp, +access will be denied unless the remote and local host are on the same +local-area network. +.SH "SEE ALSO" +.nf +\fIInternet Protocol Handbook\fR +kerberosintro(1) diff --git a/eBones/man/tftpd.8 b/eBones/man/tftpd.8 new file mode 100644 index 0000000..22a7fe8 --- /dev/null +++ b/eBones/man/tftpd.8 @@ -0,0 +1,39 @@ +.\" from: tftpd.8,v 4.1 89/01/23 11:36:12 jtkohl Exp $ +.\" $Id: tftpd.8,v 1.2 1994/07/19 19:28:08 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH TFTPD 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +tftpd \- server tftp daemon +.SH SYNOPSIS +.B /etc/tftpd +.SH DESCRIPTION +.I Tftpd +is a daemon which runs the trivial file transfer protocol server for the +MIT Internet software. It listens for incoming connections, and forks a +child to perform each requested transfer. It uses the directory +.IR /tftpd ; +the file +.I lock +in that directory is used to prevent two daemons from becoming +active simultaneously; it also contains the daemon's process ID, +which is used by the tftp command program +.IR tcom (8) +to control the daemon's operation. +.SH FILES +.br +.TP 20n +/tftpd/lock +interlock, PID storage +.TP +/dev/net +the network device +.i0 +.dt +.SH "SEE ALSO" +tftp (1), tcom (8) +.br +\fIInternet Protocol Handbook\fR diff --git a/eBones/patchlevel.h b/eBones/patchlevel.h new file mode 100644 index 0000000..836f08e --- /dev/null +++ b/eBones/patchlevel.h @@ -0,0 +1,6 @@ +/*- + * $Id: patchlevel.h,v 1.2 1994/07/19 19:21:10 g89r4222 Exp $ + */ + +#define PATCHLEVEL 9 +#define FreeBSD_PL 0.1 diff --git a/eBones/register/Makefile b/eBones/register/Makefile new file mode 100644 index 0000000..3ab09c3 --- /dev/null +++ b/eBones/register/Makefile @@ -0,0 +1,14 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.4 1994/07/20 09:21:07 g89r4222 Exp $ + +PROG= register +SRCS= register.c +CFLAGS+=-DCRYPT -DDEBUG -DKERBEROS -I${.CURDIR}/../include +.PATH: ${.CURDIR}/../../usr.bin/rlogin +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes -lcrypt +BINDIR= /usr/bin +BINOWN= root +BINMODE=4555 + +.include <bsd.prog.mk> diff --git a/eBones/register/pathnames.h b/eBones/register/pathnames.h new file mode 100644 index 0000000..611c54f --- /dev/null +++ b/eBones/register/pathnames.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/1/93 + */ + +#define SERVER_KEYDIR "/etc/kerberosIV/register_keys" +#define CLIENT_KEYFILE "/etc/kerberosIV/.update.key" +#define KEYFILE_BASE ".update.key" +#define _PATH_KPASSWD "/usr/bin/passwd" diff --git a/eBones/register/register.1 b/eBones/register/register.1 new file mode 100644 index 0000000..d8bf104 --- /dev/null +++ b/eBones/register/register.1 @@ -0,0 +1,63 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)register.1 8.1 (Berkeley) 6/1/93 +.\" +.TH REGISTER 1 "June 1, 1993" +.UC 7 +.SH NAME +register \- register with Kerberos +.SH SYNOPSIS +.B register +.SH DESCRIPTION +The +.I register +command +is used to register a new user with Kerberos. +The Kerberos server keeps record of certain trusted hosts +from which it will accept new registrations. +If the host on which +.I register +is run is trusted by Kerberos, the user +is asked for his current password, and then +a new password to be used with Kerberos. +A user may only register with Kerberos one time. +.SH FILES +.br +/.update.keyxx.xx.xx.xx shared DES key with server +.SH "SEE ALSO" +registerd(8), kerberos(1) +.SH DIAGNOSTICS +\*(lqPrincipal not unique\*(rq +if the user already exists in the Kerberos database. +.br +\*(lqPermission Denied,\*(rq +if the host on which register is being run is untrusted. diff --git a/eBones/register/register.c b/eBones/register/register.c new file mode 100644 index 0000000..d20f848 --- /dev/null +++ b/eBones/register/register.c @@ -0,0 +1,311 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/signal.h> +#include <netinet/in.h> +#include <pwd.h> +#include <stdio.h> +#include <netdb.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include "pathnames.h" +#include "register_proto.h" + +#define SERVICE "krbupdate" /* service to add to KDC's database */ +#define PROTO "tcp" + +char realm[REALM_SZ]; +char krbhst[MAX_HSTNM]; + +static char pname[ANAME_SZ]; +static char iname[INST_SZ]; +static char password[_PASSWORD_LEN]; + +/* extern char *sys_errlist; */ +void die(); +void setup_key(), type_info(), cleanup(); + +main(argc, argv) + int argc; + char **argv; +{ + struct servent *se; + struct hostent *host; + struct sockaddr_in sin, local; + int rval; + int sock, llen; + u_char code; + static struct rlimit rl = { 0, 0 }; + + signal(SIGPIPE, die); + + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + perror("rlimit"); + exit(1); + } + + if ((se = getservbyname(SERVICE, PROTO)) == NULL) { + fprintf(stderr, "couldn't find entry for service %s\n", + SERVICE); + exit(1); + } + if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) { + fprintf(stderr, "couldn't get local Kerberos realm: %s\n", + krb_err_txt[rval]); + exit(1); + } + + if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) { + fprintf(stderr, "couldn't get Kerberos host: %s\n", + krb_err_txt[rval]); + exit(1); + } + + if ((host = gethostbyname(krbhst)) == NULL) { + fprintf(stderr, "couldn't get host entry for host %s\n", + krbhst); + exit(1); + } + + sin.sin_family = host->h_addrtype; + (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); + sin.sin_port = se->s_port; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("socket"); + exit(1); + } + + if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + perror("connect"); + (void)close(sock); + exit(1); + } + + llen = sizeof(local); + if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) { + perror("getsockname"); + (void)close(sock); + exit(1); + } + + setup_key(local); + + type_info(); + + if (!get_user_info()) { + code = ABORT; + (void)des_write(sock, &code, 1); + cleanup(); + exit(1); + } + + code = APPEND_DB; + if (des_write(sock, &code, 1) != 1) { + perror("write 1"); + cleanup(); + exit(1); + } + + if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) { + perror("write principal name"); + cleanup(); + exit(1); + } + + if (des_write(sock, iname, INST_SZ) != INST_SZ) { + perror("write instance name"); + cleanup(); + exit(1); + } + + if (des_write(sock, password, 255) != 255) { + perror("write password"); + cleanup(); + exit(1); + } + + /* get return message */ + + { + int cc; + char msgbuf[BUFSIZ]; + + cc = read(sock, msgbuf, BUFSIZ); + if (cc <= 0) { + fprintf(stderr, "protocol error during key verification\n"); + cleanup(); + exit(1); + } + if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) { + fprintf(stderr, "%s: %s", krbhst, msgbuf); + cleanup(); + exit(1); + } + + cc = des_read(sock, msgbuf, BUFSIZ); + if (cc <= 0) { + fprintf(stderr, "protocol error during read\n"); + cleanup(); + exit(1); + } else { + printf("%s: %s", krbhst, msgbuf); + } + } + + cleanup(); + (void)close(sock); +} + +void +cleanup() +{ + bzero(password, 255); +} + +extern char *crypt(); +extern char *getpass(); + +int +get_user_info() +{ + int uid = getuid(); + int valid = 0, i; + struct passwd *pw; + char *pas, *namep; + + /* NB: we must run setuid-root to get at the real pw file */ + + if ((pw = getpwuid(uid)) == NULL) { + fprintf(stderr, "Who are you?\n"); + return(0); + } + (void)seteuid(uid); + (void)strcpy(pname, pw->pw_name); /* principal name */ + + for (i = 1; i < 3; i++) { + pas = getpass("login password:"); + namep = crypt(pas, pw->pw_passwd); + if (strcmp(namep, pw->pw_passwd)) { + fprintf(stderr, "Password incorrect\n"); + continue; + } else { + valid = 1; + break; + } + } + if (!valid) + return(0); + pas = getpass("Kerberos password (may be the same):"); + while (*pas == NULL) { + printf("<NULL> password not allowed\n"); + pas = getpass("Kerberos password (may be the same):"); + } + (void)strcpy(password, pas); /* password */ + pas = getpass("Retype Kerberos password:"); + if (strcmp(password, pas)) { + fprintf(stderr, "Password mismatch -- aborted\n"); + return(0); + } + + iname[0] = NULL; /* null instance name */ + return(1); +} + +void +setup_key(local) + struct sockaddr_in local; +{ + static struct keyfile_data kdata; + static Key_schedule schedule; + int fd; + char namebuf[MAXPATHLEN]; + extern int errno; + + (void) sprintf(namebuf, "%s%s", + CLIENT_KEYFILE, + inet_ntoa(local.sin_addr)); + + fd = open(namebuf, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "couldn't open key file %s for local host: ", + namebuf); + perror(""); + exit(1); + } + + if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) { + fprintf(stderr,"size error reading key file for local host %s\n", + inet_ntoa(local.sin_addr)); + exit(1); + } + key_sched(kdata.kf_key, schedule); + des_set_key(kdata.kf_key, schedule); + return; +} + +void +type_info() +{ + printf("Kerberos user registration (realm %s)\n\n", realm); + printf("Please enter your login password followed by your new Kerberos password.\n"); + printf("The Kerberos password you enter now will be used in the future\n"); + printf("as your Kerberos password for all machines in the %s realm.\n", realm); + printf("You will only be allowed to perform this operation once, although you may run\n"); + printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD); +} + +void +die() +{ + fprintf(stderr, "\nServer no longer listening\n"); + fflush(stderr); + cleanup(); + exit(1); +} diff --git a/eBones/register/register_proto.h b/eBones/register/register_proto.h new file mode 100644 index 0000000..5478949 --- /dev/null +++ b/eBones/register/register_proto.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)register_proto.h 8.1 (Berkeley) 6/1/93 + */ + +#define APPEND_DB 0x01 +#define ABORT 0x02 + +#define GOTKEY_MSG "GOTKEY" + +struct keyfile_data { + C_Block kf_key; +}; diff --git a/eBones/registerd/Makefile b/eBones/registerd/Makefile new file mode 100644 index 0000000..bc91577 --- /dev/null +++ b/eBones/registerd/Makefile @@ -0,0 +1,20 @@ +# +# Copyright (c) 1990 The Regents of the University of California. +# All rights reserved. +# +# %sccs.include.redist.sh +# +# @(#)Makefile 8.1 (Berkeley) 6/1/93 +# +# $Id: Makefile,v 1.3 1994/07/20 09:20:51 g89r4222 Exp $ + +PROG= registerd +SRCS= registerd.c +CFLAGS+=-DCRYPT -DKERBEROS -I${.CURDIR}/../register +.PATH: ${.CURDIR}/../../usr.bin/rlogin +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN8= registerd.8 +BINDIR= /usr/libexec + +.include <bsd.prog.mk> diff --git a/eBones/registerd/registerd.8 b/eBones/registerd/registerd.8 new file mode 100644 index 0000000..7ceff75 --- /dev/null +++ b/eBones/registerd/registerd.8 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)registerd.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt REGISTERD 8 +.Os +.Sh NAME +.Nm registerd +.Nd Kerberos registration daemon +.Sh SYNOPSIS +.Nm registerd +.Sh DESCRIPTION +Act as a registration agent for a Kerberos domain. +.Sh FILES +.Bl -tag -width /etc/kerberosIV/register_keys -compact +.It Pa /.update.keyxx.xx.xx.xx +shared +.Tn DES +key with server +.It Pa /etc/kerberosIV/principal* +Kerberos database +.It Pa /etc/kerberosIV/register_keys +directory containing keys for trusted hosts +.El +.Sh SEE ALSO +.Xr registerd 8 , +.Xr kerberos 1 +.Sh DIAGNOSTICS +.Dq Already exists , +if the user already exists in the Kerberos database. +.Pp +.Dq Permission Denied , +if the host on which register is being run is untrusted. +.Sh HISTORY +The +.Nm registerd +utility +first appeared in 4.4BSD. + diff --git a/eBones/registerd/registerd.c b/eBones/registerd/registerd.c new file mode 100644 index 0000000..b62e379 --- /dev/null +++ b/eBones/registerd/registerd.c @@ -0,0 +1,341 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/signal.h> +#include <sys/resource.h> +#include <sys/param.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <syslog.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include <kerberosIV/krb_db.h> +#include <stdio.h> +#include "register_proto.h" +#include "pathnames.h" + +#define KBUFSIZ (sizeof(struct keyfile_data)) +#define RCRYPT 0x00 +#define CLEAR 0x01 + +char *progname, msgbuf[BUFSIZ]; + +main(argc, argv) + int argc; + char **argv; +{ + static Key_schedule schedule; + static struct rlimit rl = { 0, 0 }; + struct keyfile_data *kfile; + u_char code; + int kf, retval, sval; + struct sockaddr_in sin; + char keyfile[MAXPATHLEN], keybuf[KBUFSIZ]; + void die(); + + progname = argv[0]; /* for the library routines */ + + openlog("registerd", LOG_PID, LOG_AUTH); + + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGTSTP, SIG_IGN); + (void)signal(SIGPIPE, die); + + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + syslog(LOG_ERR, "setrlimit: %m"); + exit(1); + } + + + /* figure out who we are talking to */ + + sval = sizeof(sin); + if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) { + syslog(LOG_ERR, "getpeername: %m"); + exit(1); + } + + /* get encryption key */ + + (void) sprintf(keyfile, "%s/%s%s", + SERVER_KEYDIR, + KEYFILE_BASE, + inet_ntoa(sin.sin_addr)); + + if ((kf = open(keyfile, O_RDONLY)) < 0) { + syslog(LOG_ERR, + "error opening Kerberos update keyfile (%s): %m", keyfile); + (void) sprintf(msgbuf, + "couldn't open session keyfile for your host"); + send_packet(msgbuf, CLEAR); + exit(1); + } + + if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) { + syslog(LOG_ERR, "wrong read size of Kerberos update keyfile"); + (void) sprintf(msgbuf, + "couldn't read session key from your host's keyfile"); + send_packet(msgbuf, CLEAR); + exit(1); + } + (void) sprintf(msgbuf, GOTKEY_MSG); + send_packet(msgbuf, CLEAR); + kfile = (struct keyfile_data *) keybuf; + key_sched(kfile->kf_key, schedule); + des_set_key(kfile->kf_key, schedule); + + /* read the command code byte */ + + if (des_read(0, &code, 1) == 1) { + + switch(code) { + case APPEND_DB: + retval = do_append(&sin); + break; + case ABORT: + cleanup(); + close(0); + exit(0); + default: + retval = KFAILURE; + syslog(LOG_NOTICE, + "invalid command code on db update (0x%x)", + code); + } + + } else { + retval = KFAILURE; + syslog(LOG_ERR, + "couldn't read command code on Kerberos update"); + } + + code = (u_char) retval; + if (code != KSUCCESS) { + (void) sprintf(msgbuf, "%s", krb_err_txt[code]); + send_packet(msgbuf, RCRYPT); + } else { + (void) sprintf(msgbuf, "Update complete."); + send_packet(msgbuf, RCRYPT); + } + cleanup(); + close(0); + exit(0); +} + +#define MAX_PRINCIPAL 10 +static Principal principal_data[MAX_PRINCIPAL]; +static C_Block key, master_key; +static Key_schedule master_key_schedule; +int +do_append(sinp) + struct sockaddr_in *sinp; +{ + Principal default_princ; + char input_name[ANAME_SZ]; + char input_instance[INST_SZ]; + int j,n, more; + long mkeyversion; + + + + /* get master key from MKEYFILE */ + if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) { + syslog(LOG_ERR, "couldn't get master key"); + return(KFAILURE); + } + + mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL); + if (mkeyversion < 0) { + syslog(LOG_ERR, "couldn't validate master key"); + return(KFAILURE); + } + + n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + + if (n != 1) { + syslog(LOG_ERR, "couldn't get default principal"); + return(KFAILURE); + } + + /* + * get principal name, instance, and password from network. + * convert password to key and store it + */ + + if (net_get_principal(input_name, input_instance, key) != 0) { + return(KFAILURE); + } + + + j = kerb_get_principal( + input_name, + input_instance, + principal_data, + MAX_PRINCIPAL, + &more + ); + + if (j != 0) { + /* already in database, no update */ + syslog(LOG_NOTICE, + "attempt to add duplicate entry for principal %s.%s", + input_name, input_instance); + return(KDC_PR_N_UNIQUE); + } + + /* + * set up principal's name, instance + */ + + strcpy(principal_data[0].name, input_name); + strcpy(principal_data[0].instance, input_instance); + principal_data[0].old = NULL; + + + /* and the expiration date and version #s */ + + principal_data[0].exp_date = default_princ.exp_date; + strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt); + principal_data[0].max_life = default_princ.max_life; + principal_data[0].attributes = default_princ.attributes; + principal_data[0].kdc_key_ver = default_princ.kdc_key_ver; + + + /* and the key */ + + kdb_encrypt_key(key, key, master_key, master_key_schedule, + ENCRYPT); + bcopy(key, &principal_data[0].key_low, 4); + bcopy(((long *) key) + 1, &principal_data[0].key_high,4); + bzero(key, sizeof(key)); + + principal_data[0].key_version = 1; /* 1st entry */ + + /* and write it to the database */ + + if (kerb_put_principal(&principal_data[0], 1)) { + syslog(LOG_INFO, "Kerberos update failure: put_principal failed"); + return(KFAILURE); + } + + syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s", + principal_data[0].name, + principal_data[0].instance, + inet_ntoa(sinp->sin_addr) + ); + + return(KSUCCESS); + +} + +send_packet(msg,flag) + char *msg; + int flag; +{ + int len = strlen(msg); + msg[len++] = '\n'; + msg[len] = '\0'; + if (len > sizeof(msgbuf)) { + syslog(LOG_ERR, "send_packet: invalid msg size"); + return; + } + if (flag == RCRYPT) { + if (des_write(0, msg, len) != len) + syslog(LOG_ERR, "couldn't write reply message"); + } else if (flag == CLEAR) { + if (write(0, msg, len) != len) + syslog(LOG_ERR, "couldn't write reply message"); + } else + syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag); + +} + +net_get_principal(pname, iname, keyp) + char *pname, *iname; + C_Block *keyp; +{ + int cc; + static char password[255]; + + cc = des_read(0, pname, ANAME_SZ); + if (cc != ANAME_SZ) { + syslog(LOG_ERR, "couldn't get principal name"); + return(-1); + } + + cc = des_read(0, iname, INST_SZ); + if (cc != INST_SZ) { + syslog(LOG_ERR, "couldn't get instance name"); + return(-1); + } + + cc = des_read(0, password, 255); + if (cc != 255) { + syslog(LOG_ERR, "couldn't get password"); + bzero(password, 255); + return(-1); + } + + string_to_key(password, *keyp); + bzero(password, 255); + return(0); +} + +cleanup() +{ + bzero(master_key, sizeof(master_key)); + bzero(key, sizeof(key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); +} + +void +die() +{ + syslog(LOG_ERR, "remote end died (SIGPIPE)"); + cleanup(); + exit(1); +} diff --git a/eBones/usr.bin/kadmin/kadmin.8 b/eBones/usr.bin/kadmin/kadmin.8 new file mode 100644 index 0000000..6e15015 --- /dev/null +++ b/eBones/usr.bin/kadmin/kadmin.8 @@ -0,0 +1,158 @@ +.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $ +.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmin \- network utility for Kerberos database administration +.SH SYNOPSIS +.B kadmin [-u user] [-r default_realm] [-m] +.SH DESCRIPTION +This utility provides a unified administration interface to +the +Kerberos +master database. +Kerberos +administrators +use +.I kadmin +to register new users and services to the master database, +and to change information about existing database entries. +For instance, an administrator can use +.I kadmin +to change a user's +Kerberos +password. +A Kerberos administrator is a user with an ``admin'' instance +whose name appears on one of the Kerberos administration access control +lists. If the \-u option is used, +.I user +will be used as the administrator instead of the local user. +If the \-r option is used, +.I default_realm +will be used as the default realm for transactions. Otherwise, +the local realm will be used by default. +If the \-m option is used, multiple requests will be permitted +on only one entry of the admin password. Some sites won't +support this option. + +The +.I kadmin +program communicates over the network with the +.I kadmind +program, which runs on the machine housing the Kerberos master +database. +The +.I kadmind +creates new entries and makes modifications to the database. + +When you enter the +.I kadmin +command, +the program displays a message that welcomes you and explains +how to ask for help. +Then +.I kadmin +waits for you to enter commands (which are described below). +It then asks you for your +.I admin +password before accessing the database. + +Use the +.I add_new_key +(or +.I ank +for short) +command to register a new principal +with the master database. +The command requires one argument, +the principal's name. The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's +new password. If no realm is specified, +the local realm is used unless another was +given on the commandline with the \-r flag. +If no instance is +specified, a null instance is used. If +a realm other than the default realm is specified, +you will need to supply your admin password for +the other realm. + +Use the +.I change_password (cpw) +to change a principal's +Kerberos +password. +The command requires one argument, +the principal's +name. +You are asked to enter your +.I admin +password, +then prompted twice to enter the principal's new password. +The name +given can be fully qualified using +the standard +.I name.instance@realm +convention. + +Use the +.I change_admin_password (cap) +to change your +.I admin +instance password. +This command requires no arguments. +It prompts you for your old +.I admin +password, then prompts you twice to enter the new +.I admin +password. If this is your first command, +the default realm is used. Otherwise, the realm +used in the last command is used. + +Use the +.I destroy_tickets (dest) +command to destroy your admin tickets explicitly. + +Use the +.I list_requests (lr) +command to get a list of possible commands. + +Use the +.I help +command to display +.IR kadmin's +various help messages. +If entered without an argument, +.I help +displays a general help message. +You can get detailed information on specific +.I kadmin +commands +by entering +.I help +.IR command_name . + +To quit the program, type +.IR quit . + +.SH BUGS +The user interface is primitive, and the command names could be better. + +.SH "SEE ALSO" +kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8) +.br +``A Subsystem Utilities Package for UNIX'' by Ken Raeburn +.SH AUTHORS +Jeffrey I. Schiller, MIT Project Athena +.br +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/usr.bin/kdestroy/Makefile b/eBones/usr.bin/kdestroy/Makefile new file mode 100644 index 0000000..5947028 --- /dev/null +++ b/eBones/usr.bin/kdestroy/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:15 g89r4222 Exp $ + +PROG= kdestroy +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42 +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.bin/kdestroy/kdestroy.1 b/eBones/usr.bin/kdestroy/kdestroy.1 new file mode 100644 index 0000000..7099353 --- /dev/null +++ b/eBones/usr.bin/kdestroy/kdestroy.1 @@ -0,0 +1,81 @@ +.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $ +.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdestroy \- destroy Kerberos tickets +.SH SYNOPSIS +.B kdestroy +[ +.B \-f +] +[ +.B \-q +] +.SH DESCRIPTION +The +.I kdestroy +utility destroys the user's active +Kerberos +authorization tickets by writing zeros to the file that contains them. +If the ticket file does not exist, +.I kdestroy +displays a message to that effect. +.PP +After overwriting the file, +.I kdestroy +removes the file from the system. +The utility +displays a message indicating the success or failure of the +operation. +If +.I kdestroy +is unable to destroy the ticket file, +the utility will warn you by making your terminal beep. +.PP +In the Athena workstation environment, +the +.I toehold +service automatically destroys your tickets when you +end a workstation session. +If your site does not provide a similar ticket-destroying mechanism, +you can place the +.I kdestroy +command in your +.I .logout +file so that your tickets are destroyed automatically +when you logout. +.PP +The options to +.I kdestroy +are as follows: +.TP 7 +.B \-f +.I kdestroy +runs without displaying the status message. +.TP +.B \-q +.I kdestroy +will not make your terminal beep if it fails to destroy the tickets. +.SH FILES +KRBTKFILE environment variable if set, otherwise +.br +/tmp/tkt[uid] +.SH SEE ALSO +kerberos(1), kinit(1), klist(1) +.SH BUGS +.PP +Only the tickets in the user's current ticket file are destroyed. +Separate ticket files are used to hold root instance and password +changing tickets. These files should probably be destroyed too, or +all of a user's tickets kept in a single ticket file. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena +.br +Bill Sommerfeld, MIT Project Athena diff --git a/eBones/usr.bin/kdestroy/kdestroy.c b/eBones/usr.bin/kdestroy/kdestroy.c new file mode 100644 index 0000000..f010fcd --- /dev/null +++ b/eBones/usr.bin/kdestroy/kdestroy.c @@ -0,0 +1,78 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This program causes Kerberos tickets to be destroyed. + * Options are: + * + * -q[uiet] - no bell even if tickets not destroyed + * -f[orce] - no message printed at all + * + * from: kdestroy.c,v 4.5 88/03/18 15:16:02 steiner Exp $ + * $Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <krb.h> +#ifdef BSD42 +#include <strings.h> +#endif BSD42 + + +static char *pname; + +static usage() +{ + fprintf(stderr, "Usage: %s [-f] [-q]\n", pname); + exit(1); +} + +main(argc, argv) + char *argv[]; +{ + int fflag=0, qflag=0, k_errno; + register char *cp; + + cp = rindex (argv[0], '/'); + if (cp == NULL) + pname = argv[0]; + else + pname = cp+1; + + if (argc > 2) + usage(); + else if (argc == 2) { + if (!strcmp(argv[1], "-f")) + ++fflag; + else if (!strcmp(argv[1], "-q")) + ++qflag; + else usage(); + } + + k_errno = dest_tkt(); + + if (fflag) { + if (k_errno != 0 && k_errno != RET_TKFIL) + exit(1); + else + exit(0); + } else { + if (k_errno == 0) + printf("Tickets destroyed.\n"); + else if (k_errno == RET_TKFIL) + fprintf(stderr, "No tickets to destroy.\n"); + else { + fprintf(stderr, "Tickets NOT destroyed.\n"); + if (!qflag) + fprintf(stderr, "\007"); + exit(1); + } + } + exit(0); +} diff --git a/eBones/usr.bin/kinit/Makefile b/eBones/usr.bin/kinit/Makefile new file mode 100644 index 0000000..e616f42 --- /dev/null +++ b/eBones/usr.bin/kinit/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:31 g89r4222 Exp $ + +PROG= kinit +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42 +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.bin/kinit/kinit.1 b/eBones/usr.bin/kinit/kinit.1 new file mode 100644 index 0000000..f9a97a7 --- /dev/null +++ b/eBones/usr.bin/kinit/kinit.1 @@ -0,0 +1,133 @@ +.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $ +.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kinit \- Kerberos login utility +.SH SYNOPSIS +.B kinit +[ +.B \-irvl +] +.SH DESCRIPTION +The +.I kinit +command is used to login to the +Kerberos +authentication and authorization system. +Note that only registered +Kerberos +users can use the +Kerberos +system. +For information about registering as a +Kerberos +user, +see the +.I kerberos(1) +manual page. +.PP +If you are logged in to a workstation that is running the +.I toehold +service, +you do not have to use +.I kinit. +The +.I toehold +login procedure will log you into +Kerberos +automatically. +You will need to use +.I kinit +only in those situations in which +your original tickets have expired. +(Tickets expire in about a day.) +Note as well that +.I toehold +will automatically destroy your tickets when you logout from the workstation. +.PP +When you use +.I kinit +without options, +the utility +prompts for your username and Kerberos password, +and tries to authenticate your login with the local +Kerberos +server. +.PP +If +Kerberos +authenticates the login attempt, +.I kinit +retrieves your initial ticket and puts it in the ticket file specified by +your KRBTKFILE environment variable. +If this variable is undefined, +your ticket will be stored in the +.IR /tmp +directory, +in the file +.I tktuid , +where +.I uid +specifies your user identification number. +.PP +If you have logged in to +Kerberos +without the benefit of the workstation +.I toehold +system, +make sure you use the +.I kdestroy +command to destroy any active tickets before you end your login session. +You may want to put the +.I kdestroy +command in your +.I \.logout +file so that your tickets will be destroyed automatically when you logout. +.PP +The options to +.I kinit +are as follows: +.TP 7 +.B \-i +.I kinit +prompts you for a +Kerberos +instance. +.TP +.B \-r +.I kinit +prompts you for a +Kerberos +realm. +This option lets you authenticate yourself with a remote +Kerberos +server. +.TP +.B \-v +Verbose mode. +.I kinit +prints the name of the ticket file used, and +a status message indicating the success or failure of +your login attempt. +.TP +.B \-l +.I kinit +prompts you for a ticket lifetime in minutes. Due to protocol +restrictions in Kerberos Version 4, this value must be between 5 and +1275 minutes. +.SH SEE ALSO +.PP +kerberos(1), kdestroy(1), klist(1), toehold(1) +.SH BUGS +The +.B \-r +option has not been fully implemented. +.SH AUTHORS +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.br +Clifford Neuman, MIT Project Athena diff --git a/eBones/usr.bin/kinit/kinit.c b/eBones/usr.bin/kinit/kinit.c new file mode 100644 index 0000000..94ce0fe --- /dev/null +++ b/eBones/usr.bin/kinit/kinit.c @@ -0,0 +1,214 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Routine to initialize user to Kerberos. Prompts optionally for + * user, instance and realm. Authenticates user and gets a ticket + * for the Kerberos ticket-granting service for future use. + * + * Options are: + * + * -i[instance] + * -r[realm] + * -v[erbose] + * -l[ifetime] + * + * from: kinit.c,v 4.12 90/03/20 16:11:15 jon Exp $ + * $Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <pwd.h> +#include <krb.h> + +#ifndef ORGANIZATION +#define ORGANIZATION "MIT Project Athena" +#endif /*ORGANIZATION*/ + +#ifdef PC +#define LEN 64 /* just guessing */ +#endif PC + +#if defined(BSD42) || defined(__FreeBSD__) +#include <strings.h> +#include <sys/param.h> +#if defined(ultrix) || defined(sun) +#define LEN 64 +#else +#define LEN MAXHOSTNAMELEN +#endif /* defined(ultrix) || defined(sun) */ +#endif /* BSD42 */ + +#define LIFE 96 /* lifetime of ticket in 5-minute units */ + +char *progname; + +void +get_input(s, size, stream) +char *s; +int size; +FILE *stream; +{ + char *p; + + if (fgets(s, size, stream) == NULL) + exit(1); + if ((p = index(s, '\n')) != NULL) + *p = '\0'; +} + +main(argc, argv) + char *argv[]; +{ + char aname[ANAME_SZ]; + char inst[INST_SZ]; + char realm[REALM_SZ]; + char buf[LEN]; + char *username = NULL; + int iflag, rflag, vflag, lflag, lifetime, k_errno; + register char *cp; + register i; + + *inst = *realm = '\0'; + iflag = rflag = vflag = lflag = 0; + lifetime = LIFE; + progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + while (--argc) { + if ((*++argv)[0] != '-') { + if (username) + usage(); + username = *argv; + continue; + } + for (i = 1; (*argv)[i] != '\0'; i++) + switch ((*argv)[i]) { + case 'i': /* Instance */ + ++iflag; + continue; + case 'r': /* Realm */ + ++rflag; + continue; + case 'v': /* Verbose */ + ++vflag; + continue; + case 'l': + ++lflag; + continue; + default: + usage(); + exit(1); + } + } + if (username && + (k_errno = kname_parse(aname, inst, realm, username)) + != KSUCCESS) { + fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]); + iflag = rflag = 1; + username = NULL; + } + if (k_gethostname(buf, LEN)) { + fprintf(stderr, "%s: k_gethostname failed\n", progname); + exit(1); + } + printf("%s (%s)\n", ORGANIZATION, buf); + if (username) { + printf("Kerberos Initialization for \"%s", aname); + if (*inst) + printf(".%s", inst); + if (*realm) + printf("@%s", realm); + printf("\"\n"); + } else { + if (iflag) { + printf("Kerberos Initialization\n"); + printf("Kerberos name: "); + get_input(aname, sizeof(aname), stdin); + } else { + int uid = getuid(); + char *getenv(); + struct passwd *pwd; + + /* default to current user name unless running as root */ + if (uid == 0 && (username = getenv("USER")) && + strcmp(username, "root") != 0) { + strncpy(aname, username, sizeof(aname)); + strncpy(inst, "root", sizeof(inst)); + } else { + pwd = getpwuid(uid); + + if (pwd == (struct passwd *) NULL) { + fprintf(stderr, "Unknown name for your uid\n"); + printf("Kerberos name: "); + gets(aname); + } else + strncpy(aname, pwd->pw_name, sizeof(aname)); + } + } + + if (!*aname) + exit(0); + if (!k_isname(aname)) { + fprintf(stderr, "%s: bad Kerberos name format\n", + progname); + exit(1); + } + } + /* optional instance */ + if (iflag) { + printf("Kerberos instance: "); + get_input(inst, sizeof(inst), stdin); + if (!k_isinst(inst)) { + fprintf(stderr, "%s: bad Kerberos instance format\n", + progname); + exit(1); + } + } + if (rflag) { + printf("Kerberos realm: "); + get_input(realm, sizeof(realm), stdin); + if (!k_isrealm(realm)) { + fprintf(stderr, "%s: bad Kerberos realm format\n", + progname); + exit(1); + } + } + if (lflag) { + printf("Kerberos ticket lifetime (minutes): "); + get_input(buf, sizeof(buf), stdin); + lifetime = atoi(buf); + if (lifetime < 5) + lifetime = 1; + else + lifetime /= 5; + /* This should be changed if the maximum ticket lifetime */ + /* changes */ + if (lifetime > 255) + lifetime = 255; + } + if (!*realm && krb_get_lrealm(realm, 1)) { + fprintf(stderr, "%s: krb_get_lrealm failed\n", progname); + exit(1); + } + k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm, + lifetime, 0); + if (vflag) { + printf("Kerberos realm %s:\n", realm); + printf("%s\n", krb_err_txt[k_errno]); + } else if (k_errno) { + fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]); + exit(1); + } +} + +usage() +{ + fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname); + exit(1); +} diff --git a/eBones/usr.bin/klist/Makefile b/eBones/usr.bin/klist/Makefile new file mode 100644 index 0000000..aa0d720 --- /dev/null +++ b/eBones/usr.bin/klist/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:37 g89r4222 Exp $ + +PROG= klist +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.bin/klist/klist.1 b/eBones/usr.bin/klist/klist.1 new file mode 100644 index 0000000..a66e668 --- /dev/null +++ b/eBones/usr.bin/klist/klist.1 @@ -0,0 +1,84 @@ +.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $ +.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +klist \- list currently held Kerberos tickets +.SH SYNOPSIS +.B klist +[ +\fB\-s \fR|\fB \-t\fR +] [ +.B \-file +name ] [ +.B \-srvtab +] +.br +.SH DESCRIPTION +.I klist +prints the name of the tickets file and the +identity of the principal the tickets are for (as listed in the +tickets file), and +lists the principal names of all Kerberos tickets currently held by +the user, along with the issue and expire time for each authenticator. +Principal names are listed in the form +.I name.instance@realm, +with the '.' omitted if the instance is null, +and the '@' omitted if the realm is null. + +If given the +.B \-s +option, +.I klist +does not print the issue and expire times, the name of the tickets file, +or the identity of the principal. + +If given the +.B \-t +option, +.B klist +checks for the existence of a non-expired ticket-granting-ticket in the +ticket file. If one is present, it exits with status 0, else it exits +with status 1. No output is generated when this option is specified. + +If given the +.B \-file +option, the following argument is used as the ticket file. +Otherwise, if the +.B KRBTKFILE +environment variable is set, it is used. +If this environment variable +is not set, the file +.B /tmp/tkt[uid] +is used, where +.B uid +is the current user-id of the user. + +If given the +.B \-srvtab +option, the file is treated as a service key file, and the names of the +keys contained therein are printed. If no file is +specified with a +.B \-file +option, the default is +.IR /etc/srvtab . +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm +.TP +/tmp/tkt[uid] +as the default ticket file ([uid] is the decimal UID of the user). +.TP +/etc/srvtab +as the default service key file +.SH SEE ALSO +.PP +kerberos(1), kinit(1), kdestroy(1) +.SH BUGS +When reading a file as a service key file, very little sanity or error +checking is performed. diff --git a/eBones/usr.bin/klist/klist.c b/eBones/usr.bin/klist/klist.c new file mode 100644 index 0000000..4a95bc0 --- /dev/null +++ b/eBones/usr.bin/klist/klist.c @@ -0,0 +1,275 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Lists your current Kerberos tickets. + * Written by Bill Sommerfeld, MIT Project Athena. + * + * from: klist.c,v 4.15 89/08/30 11:19:16 jtkohl Exp $ + * $Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include <krb.h> +#include <prot.h> + +char *tkt_string(); +char *short_date(); +char *whoami; /* What was I invoked as?? */ +char *getenv(); + +extern char *krb_err_txt[]; + +/* ARGSUSED */ +main(argc, argv) + int argc; + char **argv; +{ + int long_form = 1; + int tgt_test = 0; + int do_srvtab = 0; + char *tkt_file = NULL; + char *cp; + + whoami = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + while (*(++argv)) { + if (!strcmp(*argv, "-s")) { + long_form = 0; + continue; + } + if (!strcmp(*argv, "-t")) { + tgt_test = 1; + long_form = 0; + continue; + } + if (!strcmp(*argv, "-l")) { /* now default */ + continue; + } + if (!strcmp(*argv, "-file")) { + if (*(++argv)) { + tkt_file = *argv; + continue; + } else + usage(); + } + if (!strcmp(*argv, "-srvtab")) { + if (tkt_file == NULL) /* if no other file spec'ed, + set file to default srvtab */ + tkt_file = KEYFILE; + do_srvtab = 1; + continue; + } + usage(); + } + + if (do_srvtab) + display_srvtab(tkt_file); + else + display_tktfile(tkt_file, tgt_test, long_form); + exit(0); +} + + +display_tktfile(file, tgt_test, long_form) +char *file; +int tgt_test, long_form; +{ + char pname[ANAME_SZ]; + char pinst[INST_SZ]; + char prealm[REALM_SZ]; + char buf1[20], buf2[20]; + int k_errno; + CREDENTIALS c; + int header = 1; + + if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL)) + file = TKT_FILE; + + if (long_form) + printf("Ticket file: %s\n", file); + + /* + * Since krb_get_tf_realm will return a ticket_file error, + * we will call tf_init and tf_close first to filter out + * things like no ticket file. Otherwise, the error that + * the user would see would be + * klist: can't find realm of ticket file: No ticket file (tf_util) + * instead of + * klist: No ticket file (tf_util) + */ + + /* Open ticket file */ + if (k_errno = tf_init(file, R_TKT_FIL)) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + /* Close ticket file */ + (void) tf_close(); + + /* + * We must find the realm of the ticket file here before calling + * tf_init because since the realm of the ticket file is not + * really stored in the principal section of the file, the + * routine we use must itself call tf_init and tf_close. + */ + if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) { + if (!tgt_test) + fprintf(stderr, "%s: can't find realm of ticket file: %s\n", + whoami, krb_err_txt[k_errno]); + exit(1); + } + + /* Open ticket file */ + if (k_errno = tf_init(file, R_TKT_FIL)) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + /* Get principal name and instance */ + if ((k_errno = tf_get_pname(pname)) || + (k_errno = tf_get_pinst(pinst))) { + if (!tgt_test) + fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]); + exit(1); + } + + /* + * You may think that this is the obvious place to get the + * realm of the ticket file, but it can't be done here as the + * routine to do this must open the ticket file. This is why + * it was done before tf_init. + */ + + if (!tgt_test && long_form) + printf("Principal:\t%s%s%s%s%s\n\n", pname, + (pinst[0] ? "." : ""), pinst, + (prealm[0] ? "@" : ""), prealm); + while ((k_errno = tf_get_cred(&c)) == KSUCCESS) { + if (!tgt_test && long_form && header) { + printf("%-15s %-15s %s\n", + " Issued", " Expires", " Principal"); + header = 0; + } + if (tgt_test) { + c.issue_date += ((unsigned char) c.lifetime) * 5 * 60; + if (!strcmp(c.service, TICKET_GRANTING_TICKET) && + !strcmp(c.instance, prealm)) { + if (time(0) < c.issue_date) + exit(0); /* tgt hasn't expired */ + else + exit(1); /* has expired */ + } + continue; /* not a tgt */ + } + if (long_form) { + (void) strcpy(buf1, short_date(&c.issue_date)); + c.issue_date += ((unsigned char) c.lifetime) * 5 * 60; + (void) strcpy(buf2, short_date(&c.issue_date)); + printf("%s %s ", buf1, buf2); + } + printf("%s%s%s%s%s\n", + c.service, (c.instance[0] ? "." : ""), c.instance, + (c.realm[0] ? "@" : ""), c.realm); + } + if (tgt_test) + exit(1); /* no tgt found */ + if (header && long_form && k_errno == EOF) { + printf("No tickets in file.\n"); + } +} + +char * +short_date(dp) + long *dp; +{ + register char *cp; + extern char *ctime(); + cp = ctime(dp) + 4; + cp[15] = '\0'; + return (cp); +} + +usage() +{ + fprintf(stderr, + "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami); + exit(1); +} + +display_srvtab(file) +char *file; +{ + int stab; + char serv[SNAME_SZ]; + char inst[INST_SZ]; + char rlm[REALM_SZ]; + unsigned char key[8]; + unsigned char vno; + int count; + + printf("Server key file: %s\n", file); + + if ((stab = open(file, O_RDONLY, 0400)) < 0) { + perror(file); + exit(1); + } + printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm", + "Key Version"); + printf("------------------------------------------------------\n"); + + /* argh. getst doesn't return error codes, it silently fails */ + while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0) + && ((count = ok_getst(stab, inst, INST_SZ)) > 0) + && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) { + if (((count = read(stab,(char *) &vno,1)) != 1) || + ((count = read(stab,(char *) key,8)) != 8)) { + if (count < 0) + perror("reading from key file"); + else + fprintf(stderr, "key file truncated\n"); + exit(1); + } + printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno); + } + if (count < 0) + perror(file); + (void) close(stab); +} + +/* adapted from getst() in librkb */ +/* + * ok_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. ok_getst() returns the number of characters read, including + * the null terminator. + * + * If there is a read error, it returns -1 (like the read(2) system call) + */ + +ok_getst(fd, s, n) + int fd; + register char *s; +{ + register count = n; + int err; + while ((err = read(fd, s, 1)) > 0 && --count) + if (*s++ == '\0') + return (n - count); + if (err < 0) + return(-1); + *s = '\0'; + return (n - count); +} diff --git a/eBones/usr.bin/ksrvtgt/Makefile b/eBones/usr.bin/ksrvtgt/Makefile new file mode 100644 index 0000000..5e8944d --- /dev/null +++ b/eBones/usr.bin/ksrvtgt/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:26:54 g89r4222 Exp $ + +PROG= ksrvtgt +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +BINDIR= /usr/bin +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.bin/ksrvtgt/ksrvtgt.1 b/eBones/usr.bin/ksrvtgt/ksrvtgt.1 new file mode 100644 index 0000000..25fd939 --- /dev/null +++ b/eBones/usr.bin/ksrvtgt/ksrvtgt.1 @@ -0,0 +1,51 @@ +.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $ +.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a +service key +.SH SYNOPSIS +.B ksrvtgt +name instance [[realm] srvtab] +.SH DESCRIPTION +.I ksrvtgt +retrieves a ticket-granting ticket with a lifetime of five (5) minutes +for the principal +.I name.instance@realm +(or +.I name.instance@localrealm +if +.I realm +is not supplied on the command line), decrypts the response using +the service key found in +.I srvtab +(or in +.B /etc/srvtab +if +.I srvtab +is not specified on the command line), and stores the ticket in the +standard ticket cache. +.PP +This command is intended primarily for use in shell scripts and other +batch-type facilities. +.SH DIAGNOSTICS +"Generic kerberos failure (kfailure)" can indicate a whole range of +problems, the most common of which is the inability to read the service +key file. +.SH FILES +.TP 2i +/etc/krb.conf +to get the name of the local realm. +.TP +/tmp/tkt[uid] +The default ticket file. +.TP +/etc/srvtab +The default service key file. +.SH SEE ALSO +kerberos(1), kinit(1), kdestroy(1) diff --git a/eBones/usr.bin/ksrvtgt/ksrvtgt.c b/eBones/usr.bin/ksrvtgt/ksrvtgt.c new file mode 100644 index 0000000..46bbd56 --- /dev/null +++ b/eBones/usr.bin/ksrvtgt/ksrvtgt.c @@ -0,0 +1,60 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Get a ticket-granting-ticket given a service key file (srvtab) + * The lifetime is the shortest allowed [1 five-minute interval] + * + * from: ksrvtgt.c,v 4.3 89/07/28 10:17:28 jtkohl Exp $ + * $Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $ + */ + +#ifndef lint +const char rcsid[] = +"$Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $"; +#endif /* lint */ + +#include <stdio.h> +#include <sys/param.h> +#include <krb.h> +#include <conf.h> + +main(argc,argv) + int argc; + char **argv; +{ + char realm[REALM_SZ + 1]; + register int code; + char srvtab[MAXPATHLEN + 1]; + + bzero(realm, sizeof(realm)); + bzero(srvtab, sizeof(srvtab)); + + if (argc < 3 || argc > 5) { + fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n", + argv[0]); + exit(1); + } + + if (argc == 4) + (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1); + + if (argc == 5) { + (void) strncpy(realm, argv[3], sizeof(realm) - 1); + (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1); + } + + if (srvtab[0] == 0) + (void) strcpy(srvtab, KEYFILE); + + if (realm[0] == 0) + if (krb_get_lrealm(realm) != KSUCCESS) + (void) strcpy(realm, KRB_REALM); + + code = krb_get_svc_in_tkt(argv[1], argv[2], realm, + "krbtgt", realm, 1, srvtab); + if (code) + fprintf(stderr, "%s\n", krb_err_txt[code]); + exit(code); +} diff --git a/eBones/usr.bin/register/Makefile b/eBones/usr.bin/register/Makefile new file mode 100644 index 0000000..3ab09c3 --- /dev/null +++ b/eBones/usr.bin/register/Makefile @@ -0,0 +1,14 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.4 1994/07/20 09:21:07 g89r4222 Exp $ + +PROG= register +SRCS= register.c +CFLAGS+=-DCRYPT -DDEBUG -DKERBEROS -I${.CURDIR}/../include +.PATH: ${.CURDIR}/../../usr.bin/rlogin +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes -lcrypt +BINDIR= /usr/bin +BINOWN= root +BINMODE=4555 + +.include <bsd.prog.mk> diff --git a/eBones/usr.bin/register/pathnames.h b/eBones/usr.bin/register/pathnames.h new file mode 100644 index 0000000..611c54f --- /dev/null +++ b/eBones/usr.bin/register/pathnames.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/1/93 + */ + +#define SERVER_KEYDIR "/etc/kerberosIV/register_keys" +#define CLIENT_KEYFILE "/etc/kerberosIV/.update.key" +#define KEYFILE_BASE ".update.key" +#define _PATH_KPASSWD "/usr/bin/passwd" diff --git a/eBones/usr.bin/register/register.1 b/eBones/usr.bin/register/register.1 new file mode 100644 index 0000000..d8bf104 --- /dev/null +++ b/eBones/usr.bin/register/register.1 @@ -0,0 +1,63 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)register.1 8.1 (Berkeley) 6/1/93 +.\" +.TH REGISTER 1 "June 1, 1993" +.UC 7 +.SH NAME +register \- register with Kerberos +.SH SYNOPSIS +.B register +.SH DESCRIPTION +The +.I register +command +is used to register a new user with Kerberos. +The Kerberos server keeps record of certain trusted hosts +from which it will accept new registrations. +If the host on which +.I register +is run is trusted by Kerberos, the user +is asked for his current password, and then +a new password to be used with Kerberos. +A user may only register with Kerberos one time. +.SH FILES +.br +/.update.keyxx.xx.xx.xx shared DES key with server +.SH "SEE ALSO" +registerd(8), kerberos(1) +.SH DIAGNOSTICS +\*(lqPrincipal not unique\*(rq +if the user already exists in the Kerberos database. +.br +\*(lqPermission Denied,\*(rq +if the host on which register is being run is untrusted. diff --git a/eBones/usr.bin/register/register.c b/eBones/usr.bin/register/register.c new file mode 100644 index 0000000..d20f848 --- /dev/null +++ b/eBones/usr.bin/register/register.c @@ -0,0 +1,311 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/signal.h> +#include <netinet/in.h> +#include <pwd.h> +#include <stdio.h> +#include <netdb.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include "pathnames.h" +#include "register_proto.h" + +#define SERVICE "krbupdate" /* service to add to KDC's database */ +#define PROTO "tcp" + +char realm[REALM_SZ]; +char krbhst[MAX_HSTNM]; + +static char pname[ANAME_SZ]; +static char iname[INST_SZ]; +static char password[_PASSWORD_LEN]; + +/* extern char *sys_errlist; */ +void die(); +void setup_key(), type_info(), cleanup(); + +main(argc, argv) + int argc; + char **argv; +{ + struct servent *se; + struct hostent *host; + struct sockaddr_in sin, local; + int rval; + int sock, llen; + u_char code; + static struct rlimit rl = { 0, 0 }; + + signal(SIGPIPE, die); + + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + perror("rlimit"); + exit(1); + } + + if ((se = getservbyname(SERVICE, PROTO)) == NULL) { + fprintf(stderr, "couldn't find entry for service %s\n", + SERVICE); + exit(1); + } + if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) { + fprintf(stderr, "couldn't get local Kerberos realm: %s\n", + krb_err_txt[rval]); + exit(1); + } + + if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) { + fprintf(stderr, "couldn't get Kerberos host: %s\n", + krb_err_txt[rval]); + exit(1); + } + + if ((host = gethostbyname(krbhst)) == NULL) { + fprintf(stderr, "couldn't get host entry for host %s\n", + krbhst); + exit(1); + } + + sin.sin_family = host->h_addrtype; + (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); + sin.sin_port = se->s_port; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("socket"); + exit(1); + } + + if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + perror("connect"); + (void)close(sock); + exit(1); + } + + llen = sizeof(local); + if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) { + perror("getsockname"); + (void)close(sock); + exit(1); + } + + setup_key(local); + + type_info(); + + if (!get_user_info()) { + code = ABORT; + (void)des_write(sock, &code, 1); + cleanup(); + exit(1); + } + + code = APPEND_DB; + if (des_write(sock, &code, 1) != 1) { + perror("write 1"); + cleanup(); + exit(1); + } + + if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) { + perror("write principal name"); + cleanup(); + exit(1); + } + + if (des_write(sock, iname, INST_SZ) != INST_SZ) { + perror("write instance name"); + cleanup(); + exit(1); + } + + if (des_write(sock, password, 255) != 255) { + perror("write password"); + cleanup(); + exit(1); + } + + /* get return message */ + + { + int cc; + char msgbuf[BUFSIZ]; + + cc = read(sock, msgbuf, BUFSIZ); + if (cc <= 0) { + fprintf(stderr, "protocol error during key verification\n"); + cleanup(); + exit(1); + } + if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) { + fprintf(stderr, "%s: %s", krbhst, msgbuf); + cleanup(); + exit(1); + } + + cc = des_read(sock, msgbuf, BUFSIZ); + if (cc <= 0) { + fprintf(stderr, "protocol error during read\n"); + cleanup(); + exit(1); + } else { + printf("%s: %s", krbhst, msgbuf); + } + } + + cleanup(); + (void)close(sock); +} + +void +cleanup() +{ + bzero(password, 255); +} + +extern char *crypt(); +extern char *getpass(); + +int +get_user_info() +{ + int uid = getuid(); + int valid = 0, i; + struct passwd *pw; + char *pas, *namep; + + /* NB: we must run setuid-root to get at the real pw file */ + + if ((pw = getpwuid(uid)) == NULL) { + fprintf(stderr, "Who are you?\n"); + return(0); + } + (void)seteuid(uid); + (void)strcpy(pname, pw->pw_name); /* principal name */ + + for (i = 1; i < 3; i++) { + pas = getpass("login password:"); + namep = crypt(pas, pw->pw_passwd); + if (strcmp(namep, pw->pw_passwd)) { + fprintf(stderr, "Password incorrect\n"); + continue; + } else { + valid = 1; + break; + } + } + if (!valid) + return(0); + pas = getpass("Kerberos password (may be the same):"); + while (*pas == NULL) { + printf("<NULL> password not allowed\n"); + pas = getpass("Kerberos password (may be the same):"); + } + (void)strcpy(password, pas); /* password */ + pas = getpass("Retype Kerberos password:"); + if (strcmp(password, pas)) { + fprintf(stderr, "Password mismatch -- aborted\n"); + return(0); + } + + iname[0] = NULL; /* null instance name */ + return(1); +} + +void +setup_key(local) + struct sockaddr_in local; +{ + static struct keyfile_data kdata; + static Key_schedule schedule; + int fd; + char namebuf[MAXPATHLEN]; + extern int errno; + + (void) sprintf(namebuf, "%s%s", + CLIENT_KEYFILE, + inet_ntoa(local.sin_addr)); + + fd = open(namebuf, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "couldn't open key file %s for local host: ", + namebuf); + perror(""); + exit(1); + } + + if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) { + fprintf(stderr,"size error reading key file for local host %s\n", + inet_ntoa(local.sin_addr)); + exit(1); + } + key_sched(kdata.kf_key, schedule); + des_set_key(kdata.kf_key, schedule); + return; +} + +void +type_info() +{ + printf("Kerberos user registration (realm %s)\n\n", realm); + printf("Please enter your login password followed by your new Kerberos password.\n"); + printf("The Kerberos password you enter now will be used in the future\n"); + printf("as your Kerberos password for all machines in the %s realm.\n", realm); + printf("You will only be allowed to perform this operation once, although you may run\n"); + printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD); +} + +void +die() +{ + fprintf(stderr, "\nServer no longer listening\n"); + fflush(stderr); + cleanup(); + exit(1); +} diff --git a/eBones/usr.bin/register/register_proto.h b/eBones/usr.bin/register/register_proto.h new file mode 100644 index 0000000..5478949 --- /dev/null +++ b/eBones/usr.bin/register/register_proto.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)register_proto.h 8.1 (Berkeley) 6/1/93 + */ + +#define APPEND_DB 0x01 +#define ABORT 0x02 + +#define GOTKEY_MSG "GOTKEY" + +struct keyfile_data { + C_Block kf_key; +}; diff --git a/eBones/usr.sbin/ext_srvtab/Makefile b/eBones/usr.sbin/ext_srvtab/Makefile new file mode 100644 index 0000000..f30bbbb --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:22:34 g89r4222 Exp $ + +PROG= ext_srvtab +CFLAGS+=-DKERBEROS -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD+= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 new file mode 100644 index 0000000..af980a9 --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 @@ -0,0 +1,63 @@ +.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $ +.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ext_srvtab \- extract service key files from Kerberos key distribution center database +.SH SYNOPSIS +ext_srvtab [ +.B \-n +] [ +.B \-r realm +] [ +.B hostname ... +] +.SH DESCRIPTION +.I ext_srvtab +extracts service key files from the Kerberos key distribution center +(KDC) database. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +For each +.I hostname +specified on the command line, +.I ext_srvtab +creates the service key file +.IR hostname -new-srvtab, +containing all the entries in the database with an instance field of +.I hostname. +This new file contains all the keys registered for Kerberos-mediated +service providing programs which use the +.IR krb_get_phost (3) +principal and instance conventions to run on the host +.IR hostname . +If the +.B \-r +option is specified, the realm fields in the extracted file will +match the given realm rather than the local realm. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +.IR hostname -new-srvtab +Service key file generated for +.I hostname +.TP +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. +.SH SEE ALSO +read_service_key(3), krb_get_phost(3) diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.c b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c new file mode 100644 index 0000000..3a5dcec --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c @@ -0,0 +1,164 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $ + * $Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <signal.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +#define TRUE 1 +#define FALSE 0 + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +char progname[] = "ext_srvtab"; +char realm[REALM_SZ]; + +main(argc, argv) + int argc; + char *argv[]; +{ + FILE *fout; + char fname[1024]; + int fopen_errs = 0; + int arg; + Principal princs[40]; + int more; + int prompt = TRUE; + register int n, i; + + bzero(realm, sizeof(realm)); + + /* Parse commandline arguments */ + if (argc < 2) + usage(); + else { + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-n") == 0) + prompt = FALSE; + else if (strcmp(argv[i], "-r") == 0) { + if (++i >= argc) + usage(); + else { + strcpy(realm, argv[i]); + /* + * This is to humor the broken way commandline + * argument parsing is done. Later, this + * program ignores everything that starts with -. + */ + argv[i][0] = '-'; + } + } + else if (argv[i][0] == '-') + usage(); + else + if (!k_isinst(argv[i])) { + fprintf(stderr, "%s: bad instance name: %s\n", + progname, argv[i]); + usage(); + } + } + } + + if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + fflush (stderr); + exit(1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + exit(1); + } + + /* For each arg, search for instances of arg, and produce */ + /* srvtab file */ + if (!realm[0]) + if (krb_get_lrealm(realm, 1) != KSUCCESS) { + fprintf(stderr, "%s: couldn't get local realm\n", progname); + exit(1); + } + (void) umask(077); + + for (arg = 1; arg < argc; arg++) { + if (argv[arg][0] == '-') + continue; + sprintf(fname, "%s-new-srvtab", argv[arg]); + if ((fout = fopen(fname, "w")) == NULL) { + fprintf(stderr, "Couldn't create file '%s'.\n", fname); + fopen_errs++; + continue; + } + printf("Generating '%s'....\n", fname); + n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more); + if (more) + fprintf(stderr, "More than 40 found...\n"); + for (i = 0; i < n; i++) { + FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout); + FWrite(princs[i].instance, strlen(princs[i].instance) + 1, + 1, fout); + FWrite(realm, strlen(realm) + 1, 1, fout); + FWrite(&princs[i].key_version, + sizeof(princs[i].key_version), 1, fout); + bcopy(&princs[i].key_low, session_key, sizeof(long)); + bcopy(&princs[i].key_high, session_key + sizeof(long), + sizeof(long)); + kdb_encrypt_key (session_key, session_key, + master_key, master_key_schedule, DES_DECRYPT); + FWrite(session_key, sizeof session_key, 1, fout); + } + fclose(fout); + } + + StampOutSecrets(); + + exit(fopen_errs); /* 0 errors if successful */ + +} + +Die() +{ + StampOutSecrets(); + exit(1); +} + +FWrite(p, size, n, f) + char *p; + int size; + int n; + FILE *f; +{ + if (fwrite(p, size, n, f) != n) { + printf("Error writing output file. Terminating.\n"); + Die(); + } +} + +StampOutSecrets() +{ + bzero(master_key, sizeof master_key); + bzero(session_key, sizeof session_key); + bzero(master_key_schedule, sizeof master_key_schedule); +} + +usage() +{ + fprintf(stderr, + "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname); + exit(1); +} diff --git a/eBones/usr.sbin/kadmin/kadmind.8 b/eBones/usr.sbin/kadmin/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/usr.sbin/kadmin/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/usr.sbin/kadmind/kadmind.8 b/eBones/usr.sbin/kadmind/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/usr.sbin/kadmind/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/usr.sbin/kdb_destroy/Makefile b/eBones/usr.sbin/kdb_destroy/Makefile new file mode 100644 index 0000000..a48805b --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/Makefile @@ -0,0 +1,8 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:23:46 g89r4222 Exp $ + +PROG= kdb_destroy +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 new file mode 100644 index 0000000..93db466 --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 @@ -0,0 +1,33 @@ +.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $ +.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_destroy \- destroy Kerberos key distribution center database +.SH SYNOPSIS +kdb_destroy +.SH DESCRIPTION +.I kdb_destroy +deletes a Kerberos key distribution center database. +.PP +The user is prompted to verify that the database should be destroyed. A +response beginning with `y' or `Y' confirms deletion. +Any other response aborts deletion. +.SH DIAGNOSTICS +.TP 20n +"Database cannot be deleted at /kerberos/principal" +The attempt to delete the database failed (probably due to a system or +access permission error). +.TP +"Database not deleted." +The user aborted the deletion. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.SH SEE ALSO +kdb_init(8) diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.c b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c new file mode 100644 index 0000000..0c45896 --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c @@ -0,0 +1,45 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $ + * $Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $"; +#endif lint + +#include <strings.h> +#include <stdio.h> +#include "krb.h" +#include "krb_db.h" + +main() +{ + char answer[10]; /* user input */ + char dbm[256]; /* database path and name */ + char dbm1[256]; /* database path and name */ + char *file1, *file2; /* database file names */ + + strcpy(dbm, DBM_FILE); + strcpy(dbm1, DBM_FILE); + file1 = strcat(dbm, ".dir"); + file2 = strcat(dbm1, ".pag"); + + printf("You are about to destroy the Kerberos database "); + printf("on this machine.\n"); + printf("Are you sure you want to do this (y/n)? "); + fgets(answer, sizeof(answer), stdin); + + if (answer[0] == 'y' || answer[0] == 'Y') { + if (unlink(file1) == 0 && unlink(file2) == 0) + fprintf(stderr, "Database deleted at %s\n", DBM_FILE); + else + fprintf(stderr, "Database cannot be deleted at %s\n", + DBM_FILE); + } else + fprintf(stderr, "Database not deleted.\n"); +} diff --git a/eBones/usr.sbin/kdb_edit/Makefile b/eBones/usr.sbin/kdb_edit/Makefile new file mode 100644 index 0000000..65a5e5a --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/Makefile @@ -0,0 +1,12 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $ + +PROG= kdb_edit +CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include +SRCS= kdb_edit.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.8 b/eBones/usr.sbin/kdb_edit/kdb_edit.8 new file mode 100644 index 0000000..1cfd6ed --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/kdb_edit.8 @@ -0,0 +1,55 @@ +.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $ +.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_edit \- Kerberos key distribution center database editing utility +.SH SYNOPSIS +kdb_edit [ +.B \-n +] +.SH DESCRIPTION +.I kdb_edit +is used to create or change principals stored in the Kerberos key +distribution center (KDC) database. +.PP +When executed, +.I kdb_edit +prompts for the master key string and verifies that it matches the +master key stored in the database. +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +Once the master key has been verified, +.I kdb_edit +begins a prompt loop. The user is prompted for the principal and +instance to be modified. If the entry is not found the user may create +it. +Once an entry is found or created, the user may set the password, +expiration date, maximum ticket lifetime, and attributes. +Default expiration dates, maximum ticket lifetimes, and attributes are +presented in brackets; if the user presses return the default is selected. +There is no default password. +The password RANDOM is interpreted specially, and if entered +the user may have the program select a random DES key for the +principal. +.PP +Upon successfully creating or changing the entry, ``Edit O.K.'' is +printed. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c new file mode 100644 index 0000000..4c02db6 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c @@ -0,0 +1,470 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine changes the Kerberos encryption keys for principals, + * i.e., users or services. + * + * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $ + * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $ + */ + +/* + * exit returns 0 ==> success -1 ==> error + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#include <strings.h> +#include <sys/ioctl.h> +#include <sys/file.h> +#include "time.h" +#include <des.h> +#include <krb.h> +#include <krb_db.h> +/* MKEYFILE is now defined in kdc.h */ +#include <kdc.h> + +extern char *errmsg(); +extern int errno; +extern char *strcpy(); + +void sig_exit(); + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +char prog[32]; +char *progname = prog; +int nflag = 0; +int cflag; +int lflag; +int uflag; +int debug; +extern kerb_debug; + +Key_schedule KS; +C_Block new_key; +unsigned char *input; + +unsigned char *ivec; +int i, j; +int more; + +char *in_ptr; +char input_name[ANAME_SZ]; +char input_instance[INST_SZ]; +char input_string[ANAME_SZ]; + +#define MAX_PRINCIPAL 10 +Principal principal_data[MAX_PRINCIPAL]; + +static Principal old_principal; +static Principal default_princ; + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +static char pw_str[255]; +static long master_key_version; + +/* + * gets replacement + */ +static char * s_gets(char * str, int len) +{ + int i; + char *s; + + if((s = fgets(str, len, stdin)) == NULL) + return(s); + if(str[i = (strlen(str)-1)] == '\n') + str[i] = '\0'; + return(s); +} + +main(argc, argv) + int argc; + char *argv[]; + +{ + /* Local Declarations */ + + long n; + + prog[sizeof prog - 1] = '\0'; /* make sure terminated */ + strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking + * program */ + + /* Assume a long is four bytes */ + if (sizeof(long) != 4) { + fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog); + exit(-1); + } + /* Assume <=32 signals */ + if (NSIG > 32) { + fprintf(stderr, "%s: more than 32 signals defined.\n", prog); + exit(-1); + } + while (--argc > 0 && (*++argv)[0] == '-') + for (i = 1; argv[0][i] != '\0'; i++) { + switch (argv[0][i]) { + + /* debug flag */ + case 'd': + debug = 1; + continue; + + /* debug flag */ + case 'l': + kerb_debug |= 1; + continue; + + case 'n': /* read MKEYFILE for master key */ + nflag = 1; + continue; + + default: + fprintf(stderr, "%s: illegal flag \"%c\"\n", + progname, argv[0][i]); + Usage(); /* Give message and die */ + } + }; + + fprintf(stdout, "Opening database...\n"); + fflush(stdout); + kerb_init(); + if (argc > 0) { + if (kerb_db_set_name(*argv) != 0) { + fprintf(stderr, "Could not open altername database name\n"); + exit(1); + } + } + +#ifdef notdef + no_core_dumps(); /* diddle signals to avoid core dumps! */ + + /* ignore whatever is reasonable */ + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + +#endif + + if (kdb_get_master_key ((nflag == 0), + master_key, master_key_schedule) != 0) { + fprintf (stdout, "Couldn't read master key.\n"); + fflush (stdout); + exit (-1); + } + + if ((master_key_version = kdb_verify_master_key(master_key, + master_key_schedule, + stdout)) < 0) + exit (-1); + + /* lookup the default values */ + n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + if (n != 1) { + fprintf(stderr, + "%s: Kerberos error on default value lookup, %d found.\n", + progname, n); + exit(-1); + } + fprintf(stdout, "Previous or default values are in [brackets] ,\n"); + fprintf(stdout, "enter return to leave the same, or new value.\n"); + + while (change_principal()) { + } + + cleanup(); +} + +change_principal() +{ + static char temp[255]; + int creating = 0; + int editpw = 0; + int changed = 0; + long temp_long; + int n; + struct tm *tp, edate, *localtime(); + long maketime(); + + fprintf(stdout, "\nPrincipal name: "); + fflush(stdout); + if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0') + return 0; + fprintf(stdout, "Instance: "); + fflush(stdout); + /* instance can be null */ + s_gets(input_instance, INST_SZ-1); + j = kerb_get_principal(input_name, input_instance, principal_data, + MAX_PRINCIPAL, &more); + if (!j) { + fprintf(stdout, "\n\07\07<Not found>, Create [y] ? "); + s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */ + if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0') + return -1; + /* make a new principal, fill in defaults */ + j = 1; + creating = 1; + strcpy(principal_data[0].name, input_name); + strcpy(principal_data[0].instance, input_instance); + principal_data[0].old = NULL; + principal_data[0].exp_date = default_princ.exp_date; + principal_data[0].max_life = default_princ.max_life; + principal_data[0].attributes = default_princ.attributes; + principal_data[0].kdc_key_ver = (unsigned char) master_key_version; + principal_data[0].key_version = 0; /* bumped up later */ + } + tp = localtime(&principal_data[0].exp_date); + (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d", + tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900, + tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */ + for (i = 0; i < j; i++) { + for (;;) { + fprintf(stdout, + "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d", + principal_data[i].name, principal_data[i].instance, + principal_data[i].kdc_key_ver); + editpw = 1; + changed = 0; + if (!creating) { + /* + * copy the existing data so we can use the old values + * for the qualifier clause of the replace + */ + principal_data[i].old = (char *) &old_principal; + bcopy(&principal_data[i], &old_principal, + sizeof(old_principal)); + printf("\nChange password [n] ? "); + s_gets(temp, sizeof(temp)-1); + if (strcmp("y", temp) && strcmp("Y", temp)) + editpw = 0; + } + /* password */ + if (editpw) { +#ifdef NOENCRYPTION + placebo_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#else + des_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#endif + if (!strcmp(pw_str, "RANDOM")) { + printf("\nRandom password [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "RANDOM" */ + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + } else if (!strcmp(pw_str, "NULL")) { + printf("\nNull Key [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "NULL" */ + } else { + + principal_data[i].key_low = 0; + principal_data[i].key_high = 0; + goto null_key; + } + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str,new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + + /* seal it under the kerberos master key */ + kdb_encrypt_key (new_key, new_key, + master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal_data[i].key_low, 4); + bcopy(((long *) new_key) + 1, + &principal_data[i].key_high, 4); + bzero(new_key, sizeof(new_key)); + null_key: + /* set master key version */ + principal_data[i].kdc_key_ver = + (unsigned char) master_key_version; + /* bump key version # */ + principal_data[i].key_version++; + fprintf(stdout, + "\nPrincipal's new key version = %d\n", + principal_data[i].key_version); + fflush(stdout); + changed = 1; + } + /* expiration date */ + fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) > + sizeof(principal_data[0].exp_date_txt))) { + bad_date: + fprintf(stdout, "\07\07Date Invalid\n"); + fprintf(stdout, + "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + } + + if (*temp) { + if (sscanf(temp, "%d-%d-%d", &edate.tm_year, + &edate.tm_mon, &edate.tm_mday) != 3) + goto bad_date; + (void) strcpy(principal_data[i].exp_date_txt, temp); + edate.tm_mon--; /* January is 0, not 1 */ + edate.tm_hour = 23; /* nearly midnight at the end of the */ + edate.tm_min = 59; /* specified day */ + if (!(principal_data[i].exp_date = maketime(&edate, 1))) + goto bad_date; + changed = 1; + } + + /* maximum lifetime */ + fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_life; + if (temp_long > 255 || (temp_long < 0)) { + bad_life: + fprintf(stdout, "\07\07Invalid, choose 0-255\n"); + fprintf(stdout, + "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].max_life = (unsigned short) temp_long; + break; + } + + /* attributes */ + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_att; + if (temp_long > 65535 || (temp_long < 0)) { + bad_att: + fprintf(stdout, "\07\07Invalid, choose 0-65535\n"); + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].attributes = + (unsigned short) temp_long; + break; + } + + /* + * remaining fields -- key versions and mod info, should + * not be directly manipulated + */ + if (changed) { + if (kerb_put_principal(&principal_data[i], 1)) { + fprintf(stdout, + "\nError updating Kerberos database"); + } else { + fprintf(stdout, "Edit O.K."); + } + } else { + fprintf(stdout, "Unchanged"); + } + + + bzero(&principal_data[i].key_low, 4); + bzero(&principal_data[i].key_high, 4); + fflush(stdout); + break; + } + } + if (more) { + fprintf(stdout, "\nThere were more tuples found "); + fprintf(stdout, "than there were space for"); + } + return 1; +} + + +no_core_dumps() +{ + + signal(SIGQUIT, sig_exit); + signal(SIGILL, sig_exit); + signal(SIGTRAP, sig_exit); + signal(SIGIOT, sig_exit); + signal(SIGEMT, sig_exit); + signal(SIGFPE, sig_exit); + signal(SIGBUS, sig_exit); + signal(SIGSEGV, sig_exit); + signal(SIGSYS, sig_exit); +} + +void +sig_exit(sig, code, scp) + int sig, code; + struct sigcontext *scp; +{ + cleanup(); + fprintf(stderr, + "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting", + sig, code, scp->sc_pc); + exit(-1); +} + + +cleanup() +{ + + bzero(master_key, sizeof(master_key)); + bzero(session_key, sizeof(session_key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(principal_data, sizeof(principal_data)); + bzero(new_key, sizeof(new_key)); + bzero(pw_str, sizeof(pw_str)); +} +Usage() +{ + fprintf(stderr, "Usage: %s [-n]\n", progname); + exit(1); +} diff --git a/eBones/usr.sbin/kdb_edit/maketime.c b/eBones/usr.sbin/kdb_edit/maketime.c new file mode 100644 index 0000000..057ecc3 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/maketime.c @@ -0,0 +1,83 @@ +/* + * Copyright 1990 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Convert a struct tm * to a UNIX time. + * + * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $ + * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp "; +#endif lint + +#include <sys/time.h> + +#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) + +#define SECSPERDAY 24*60*60 +#define SECSPERHOUR 60*60 +#define SECSPERMIN 60 + +static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, + 365}; + +static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +long +maketime(tp, local) +register struct tm *tp; +int local; +{ + register long retval; + int foo; + int *marray; + + if (tp->tm_mon < 0 || tp->tm_mon > 11 || + tp->tm_hour < 0 || tp->tm_hour > 23 || + tp->tm_min < 0 || tp->tm_min > 59 || + tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */ + return 0; + + retval = 0; + if (tp->tm_year < 1900) + foo = tp->tm_year + 1900; + else + foo = tp->tm_year; + + if (foo < 1901 || foo > 2038) /* year is too small/large */ + return 0; + + if (daysinyear(foo) == 366) { + if (tp->tm_mon > 1) + retval+= SECSPERDAY; /* add leap day */ + marray = leapyear; + } else + marray = nonleapyear; + + if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon]) + return 0; /* out of range */ + + while (--foo >= 1970) + retval += daysinyear(foo) * SECSPERDAY; + + retval += cumdays[tp->tm_mon] * SECSPERDAY; + retval += (tp->tm_mday-1) * SECSPERDAY; + retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec; + + if (local) { + /* need to use local time, so we retrieve timezone info */ + struct timezone tz; + struct timeval tv; + if (gettimeofday(&tv, &tz) < 0) { + /* some error--give up? */ + return(retval); + } + retval += tz.tz_minuteswest * SECSPERMIN; + } + return(retval); +} diff --git a/eBones/usr.sbin/kdb_edit/time.h b/eBones/usr.sbin/kdb_edit/time.h new file mode 100644 index 0000000..ed128d8 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/time.h @@ -0,0 +1,45 @@ +/* Structure for use by time manipulating subroutines. + * The following library routines use it: + * libc: ctime, localtime, gmtime, asctime + * libcx: partime, maketime (may not be installed yet) + */ + +/* + * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $ + * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $ + */ + +struct tm { /* See defines below for allowable ranges */ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + int tm_zon; /* NEW: mins westward of Greenwich */ + int tm_ampm; /* NEW: 1 if AM, 2 if PM */ +}; + +#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/ +#define TMNULL (-1) /* Items not specified are given this value + * in order to distinguish null specs from zero + * specs. This is only used by partime and + * maketime. */ + + /* Indices into TM structure */ +#define TM_SEC 0 /* 0-59 */ +#define TM_MIN 1 /* 0-59 */ +#define TM_HOUR 2 /* 0-23 */ +#define TM_MDAY 3 /* 1-31 day of month */ +#define TM_DAY TM_MDAY /* " synonym */ +#define TM_MON 4 /* 0-11 */ +#define TM_YEAR 5 /* (year-1900) (year) */ +#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */ +#define TM_YDAY 7 /* 0-365 day of year */ +#define TM_ISDST 8 /* 0 Std, 1 DST */ + /* New stuff */ +#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */ +#define TM_AMPM 10 /* 1 AM, 2 PM */ diff --git a/eBones/usr.sbin/kdb_init/Makefile b/eBones/usr.sbin/kdb_init/Makefile new file mode 100644 index 0000000..ce51a9f --- /dev/null +++ b/eBones/usr.sbin/kdb_init/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:03 g89r4222 Exp $ + +PROG= kdb_init +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_init/kdb_init.8 b/eBones/usr.sbin/kdb_init/kdb_init.8 new file mode 100644 index 0000000..54537ad --- /dev/null +++ b/eBones/usr.sbin/kdb_init/kdb_init.8 @@ -0,0 +1,41 @@ +.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $ +.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_init \- Initialize Kerberos key distribution center database +.SH SYNOPSIS +kdb_init [ +.B realm +] +.SH DESCRIPTION +.I kdb_init +initializes a Kerberos key distribution center database, creating the +necessary principals. +.PP +If the optional +.I realm +argument is not present, +.I kdb_init +prompts for a realm name (defaulting to the definition in /usr/include/krb.h). +After determining the realm to be created, it prompts for +a master key password. The master key password is used to encrypt +every encryption key stored in the database. +.SH DIAGNOSTICS +.TP 20n +"/kerberos/principal: File exists" +An attempt was made to create a database on a machine which already had +an existing database. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/usr/include/krb.h +Include file defining default realm +.SH SEE ALSO +kdb_destroy(8) diff --git a/eBones/usr.sbin/kdb_init/kdb_init.c b/eBones/usr.sbin/kdb_init/kdb_init.c new file mode 100644 index 0000000..dc7055e --- /dev/null +++ b/eBones/usr.sbin/kdb_init/kdb_init.c @@ -0,0 +1,178 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * program to initialize the database, reports error if database file + * already exists. + * + * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $ + * $Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/time.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> +#include <string.h> + +#define TRUE 1 + +enum ap_op { + NULL_KEY, /* setup null keys */ + MASTER_KEY, /* use master key as new key */ + RANDOM_KEY, /* choose a random key */ +}; + +int debug = 0; +char *progname, *rindex(); +C_Block master_key; +Key_schedule master_key_schedule; + +main(argc, argv) + char *argv[]; +{ + char realm[REALM_SZ]; + char *cp; + int code; + char *database; + + progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + if (argc > 3) { + fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]); + exit(1); + } + if (argc == 3) { + database = argv[2]; + --argc; + } else + database = DBM_FILE; + + /* Do this first, it'll fail if the database exists */ + if ((code = kerb_db_create(database)) != 0) { + fprintf(stderr, "Couldn't create database: %s\n", + sys_errlist[code]); + exit(1); + } + kerb_db_set_name(database); + + if (argc == 2) + strncpy(realm, argv[1], REALM_SZ); + else { + fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM); + if (fgets(realm, sizeof(realm), stdin) == NULL) { + fprintf(stderr, "\nEOF reading realm\n"); + exit(1); + } + if (cp = index(realm, '\n')) + *cp = '\0'; + if (!*realm) /* no realm given */ + strcpy(realm, KRB_REALM); + } + if (!k_isrealm(realm)) { + fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n", + progname, realm); + exit(1); + } + printf("You will be prompted for the database Master Password.\n"); + printf("It is important that you NOT FORGET this password.\n"); + fflush(stdout); + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + exit (-1); + } + + if ( + add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) || + add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) || + add_principal("krbtgt", realm, RANDOM_KEY) || + add_principal("changepw", KRB_MASTER, RANDOM_KEY) + ) { + fprintf(stderr, "\n%s: couldn't initialize database.\n", + progname); + exit(1); + } + + /* play it safe */ + bzero (master_key, sizeof (C_Block)); + bzero (master_key_schedule, sizeof (Key_schedule)); + exit(0); +} + +/* use a return code to indicate success or failure. check the return */ +/* values of the routines called by this routine. */ + +add_principal(name, instance, aap_op) + char *name, *instance; + enum ap_op aap_op; +{ + Principal principal; + char datestring[50]; + char pw_str[255]; + void read_pw_string(); + void string_to_key(); + void random_key(); + struct tm *tm, *localtime(); + C_Block new_key; + + bzero(&principal, sizeof(principal)); + strncpy(principal.name, name, ANAME_SZ); + strncpy(principal.instance, instance, INST_SZ); + switch (aap_op) { + case NULL_KEY: + principal.key_low = 0; + principal.key_high = 0; + break; + case RANDOM_KEY: +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + case MASTER_KEY: + bcopy (master_key, new_key, sizeof (C_Block)); + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + } + principal.exp_date = 946702799; /* Happy new century */ + strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ); + principal.mod_date = time(0); + + tm = localtime(&principal.mod_date); + principal.attributes = 0; + principal.max_life = 255; + + principal.kdc_key_ver = 1; + principal.key_version = 1; + + strncpy(principal.mod_name, "db_creation", ANAME_SZ); + strncpy(principal.mod_instance, "", INST_SZ); + principal.old = 0; + + kerb_db_put_principal(&principal, 1); + + /* let's play it safe */ + bzero (new_key, sizeof (C_Block)); + bzero (&principal.key_low, 4); + bzero (&principal.key_high, 4); + return 0; +} diff --git a/eBones/usr.sbin/kdb_util/Makefile b/eBones/usr.sbin/kdb_util/Makefile new file mode 100644 index 0000000..b3513d6 --- /dev/null +++ b/eBones/usr.sbin/kdb_util/Makefile @@ -0,0 +1,13 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:24:09 g89r4222 Exp $ + +PROG= kdb_util +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../kdb_edit \ + -I${.CURDIR}/../include +SRCS= kdb_util.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_util/kdb_util.8 b/eBones/usr.sbin/kdb_util/kdb_util.8 new file mode 100644 index 0000000..30a3b9f --- /dev/null +++ b/eBones/usr.sbin/kdb_util/kdb_util.8 @@ -0,0 +1,64 @@ +.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $ +.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_util \- Kerberos key distribution center database utility +.SH SYNOPSIS +kdb_util +.B operation filename +.SH DESCRIPTION +.I kdb_util +allows the Kerberos key distribution center (KDC) database administrator to +perform utility functions on the database. +.PP +.I Operation +must be one of the following: +.TP 10n +.I load +initializes the KDC database with the records described by the +text contained in the file +.IR filename . +Any existing database is overwritten. +.TP +.I dump +dumps the KDC database into a text representation in the file +.IR filename . +.TP +.I slave_dump +performs a database dump like the +.I dump +operation, and additionally creates a semaphore file signalling the +propagation software that an update is available for distribution to +slave KDC databases. +.TP +.I new_master_key +prompts for the old and new master key strings, and then dumps the KDC +database into a text representation in the file +.IR filename . +The keys in the text representation are encrypted in the new master key. +.TP +.I convert_old_db +prompts for the master key string, and then dumps the KDC database into +a text representation in the file +.IR filename . +The existing database is assumed to be encrypted using the old format +(encrypted by the key schedule of the master key); the dumped database +is encrypted using the new format (encrypted directly with master key). +.PP +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +.IR filename .ok +semaphore file created by +.IR slave_dump. diff --git a/eBones/usr.sbin/kdb_util/kdb_util.c b/eBones/usr.sbin/kdb_util/kdb_util.c new file mode 100644 index 0000000..8465b5b --- /dev/null +++ b/eBones/usr.sbin/kdb_util/kdb_util.c @@ -0,0 +1,506 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Kerberos database manipulation utility. This program allows you to + * dump a kerberos database to an ascii readable file and load this + * file into the database. Read locking of the database is done during a + * dump operation. NO LOCKING is done during a load operation. Loads + * should happen with other processes shutdown. + * + * Written July 9, 1987 by Jeffrey I. Schiller + * + * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $ + * $Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "time.h" +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <sys/file.h> +#include <krb_db.h> + +#define TRUE 1 + +Principal aprinc; + +static des_cblock master_key, new_master_key; +static des_key_schedule master_key_schedule, new_master_key_schedule; + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +extern long kdb_get_master_key(), kdb_verify_master_key(); +extern char *malloc(); +extern int errno; + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + FILE *file; + enum { + OP_LOAD, + OP_DUMP, + OP_SLAVE_DUMP, + OP_NEW_MASTER, + OP_CONVERT_OLD_DB, + } op; + char *file_name; + char *prog = argv[0]; + char *db_name; + + progname = prog; + + if (argc != 3 && argc != 4) { + fprintf(stderr, "Usage: %s operation file-name [database name].\n", + argv[0]); + exit(1); + } + if (argc == 3) + db_name = DBM_FILE; + else + db_name = argv[3]; + + if (kerb_db_set_name (db_name) != 0) { + perror("Can't open database"); + exit(1); + } + + if (!strcmp(argv[1], "load")) + op = OP_LOAD; + else if (!strcmp(argv[1], "dump")) + op = OP_DUMP; + else if (!strcmp(argv[1], "slave_dump")) + op = OP_SLAVE_DUMP; + else if (!strcmp(argv[1], "new_master_key")) + op = OP_NEW_MASTER; + else if (!strcmp(argv[1], "convert_old_db")) + op = OP_CONVERT_OLD_DB; + else { + fprintf(stderr, + "%s: %s is an invalid operation.\n", prog, argv[1]); + fprintf(stderr, + "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]); + fprintf(stderr, + "\"load\", \"new_master_key\", and \"convert_old_db\".\n"); + exit(1); + } + + file_name = argv[2]; + file = fopen(file_name, op == OP_LOAD ? "r" : "w"); + if (file == NULL) { + fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]); + (void) fflush(stderr); + perror("open"); + exit(1); + } + + switch (op) { + case OP_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + break; + case OP_SLAVE_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + update_ok_file (file_name); + break; + case OP_LOAD: + load_db (db_name, file); + break; + case OP_NEW_MASTER: + convert_new_master_key (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + case OP_CONVERT_OLD_DB: + convert_old_format_db (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + } + exit(0); + } + +clear_secrets () +{ + bzero((char *)master_key, sizeof (des_cblock)); + bzero((char *)master_key_schedule, sizeof (Key_schedule)); + bzero((char *)new_master_key, sizeof (des_cblock)); + bzero((char *)new_master_key_schedule, sizeof (Key_schedule)); +} + +/* cv_key is a procedure which takes a principle and changes its key, + either for a new method of encrypting the keys, or a new master key. + if cv_key is null no transformation of key is done (other than net byte + order). */ + +struct callback_args { + void (*cv_key)(); + FILE *output_file; +}; + +static int dump_db_1(arg, principal) + char *arg; + Principal *principal; +{ /* replace null strings with "*" */ + struct callback_args *a = (struct callback_args *)arg; + + if (principal->instance[0] == '\0') { + principal->instance[0] = '*'; + principal->instance[1] = '\0'; + } + if (principal->mod_name[0] == '\0') { + principal->mod_name[0] = '*'; + principal->mod_name[1] = '\0'; + } + if (principal->mod_instance[0] == '\0') { + principal->mod_instance[0] = '*'; + principal->mod_instance[1] = '\0'; + } + if (a->cv_key != NULL) { + (*a->cv_key) (principal); + } + fprintf(a->output_file, "%s %s %d %d %d %d %x %x", + principal->name, + principal->instance, + principal->max_life, + principal->kdc_key_ver, + principal->key_version, + principal->attributes, + htonl (principal->key_low), + htonl (principal->key_high)); + print_time(a->output_file, principal->exp_date); + print_time(a->output_file, principal->mod_date); + fprintf(a->output_file, " %s %s\n", + principal->mod_name, + principal->mod_instance); + return 0; +} + +dump_db (db_file, output_file, cv_key) + char *db_file; + FILE *output_file; + void (*cv_key)(); +{ + struct callback_args a; + + a.cv_key = cv_key; + a.output_file = output_file; + + kerb_db_iterate (dump_db_1, (char *)&a); + return fflush(output_file); +} + +load_db (db_file, input_file) + char *db_file; + FILE *input_file; +{ + char exp_date_str[50]; + char mod_date_str[50]; + int temp1, temp2, temp3; + long time_explode(); + int code; + char *temp_db_file; + temp1 = strlen(db_file+2); + temp_db_file = malloc (temp1); + strcpy(temp_db_file, db_file); + strcat(temp_db_file, "~"); + + /* Create the database */ + if ((code = kerb_db_create(temp_db_file)) != 0) { + fprintf(stderr, "Couldn't create temp database %s: %s\n", + temp_db_file, sys_errlist[code]); + exit(1); + } + kerb_db_set_name(temp_db_file); + for (;;) { /* explicit break on eof from fscanf */ + bzero((char *)&aprinc, sizeof(aprinc)); + if (fscanf(input_file, + "%s %s %d %d %d %hd %x %x %s %s %s %s\n", + aprinc.name, + aprinc.instance, + &temp1, + &temp2, + &temp3, + &aprinc.attributes, + &aprinc.key_low, + &aprinc.key_high, + exp_date_str, + mod_date_str, + aprinc.mod_name, + aprinc.mod_instance) == EOF) + break; + aprinc.key_low = ntohl (aprinc.key_low); + aprinc.key_high = ntohl (aprinc.key_high); + aprinc.max_life = (unsigned char) temp1; + aprinc.kdc_key_ver = (unsigned char) temp2; + aprinc.key_version = (unsigned char) temp3; + aprinc.exp_date = time_explode(exp_date_str); + aprinc.mod_date = time_explode(mod_date_str); + if (aprinc.instance[0] == '*') + aprinc.instance[0] = '\0'; + if (aprinc.mod_name[0] == '*') + aprinc.mod_name[0] = '\0'; + if (aprinc.mod_instance[0] == '*') + aprinc.mod_instance[0] = '\0'; + if (kerb_db_put_principal(&aprinc, 1) != 1) { + fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n", + aprinc.name, aprinc.instance, + sys_errlist[errno]); + exit(1); + }; + } + if ((code = kerb_db_rename(temp_db_file, db_file)) != 0) + perror("database rename failed"); + (void) fclose(input_file); + free(temp_db_file); +} + +print_time(file, timeval) + FILE *file; + unsigned long timeval; +{ + struct tm *tm; + struct tm *gmtime(); + tm = gmtime((long *)&timeval); + fprintf(file, " %04d%02d%02d%02d%02d", + tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min); +} + +/*ARGSUSED*/ +update_ok_file (file_name) + char *file_name; +{ + /* handle slave locking/failure stuff */ + char *file_ok; + int fd; + static char ok[]=".dump_ok"; + + if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1)) + == NULL) { + fprintf(stderr, "kdb_util: out of memory.\n"); + (void) fflush (stderr); + perror ("malloc"); + exit (1); + } + strcpy(file_ok, file_name); + strcat(file_ok, ok); + if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) { + fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok); + perror(""); + (void) fflush (stderr); + exit (1); + } + free(file_ok); + close(fd); +} + +void +convert_key_new_master (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + /* move current key to des_cblock for encryption, special case master key + since that's changing */ + if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) && + (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) { + bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock)); + (p->key_version)++; + } else { + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4); + kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT); + } + + kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ + + (p->kdc_key_ver)++; +} + +convert_new_master_key (db_file, out) + char *db_file; + FILE *out; +{ + + printf ("\n\nEnter the CURRENT master key."); + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets (); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets (); + exit (-1); + } + + printf ("\n\nNow enter the NEW master key. Do not forget it!!"); + if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get new master key.\n"); + clear_secrets (); + exit (-1); + } + + dump_db (db_file, out, convert_key_new_master); +} + +void +convert_key_old_db (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4); + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key, + (long)sizeof(des_cblock),master_key_schedule, + (des_cblock *)master_key_schedule,DECRYPT); +#endif + + /* make new key, new style */ + kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ +} + +convert_old_format_db (db_file, out) + char *db_file; + FILE *out; +{ + des_cblock key_from_db; + Principal principal_data[1]; + int n, more; + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets(); + exit (-1); + } + + /* can't call kdb_verify_master_key because this is an old style db */ + /* lookup the master key version */ + n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data, + 1 /* only one please */, &more); + if ((n != 1) || more) { + fprintf(stderr, "verify_master_key: ", + "Kerberos error on master key lookup, %d found.\n", + n); + exit (-1); + } + + /* set up the master key */ + fprintf(stderr, "Current Kerberos master key version is %d.\n", + principal_data[0].kdc_key_ver); + + /* + * now use the master key to decrypt (old style) the key in the db, had better + * be the same! + */ + bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4); + bcopy((char *)&principal_data[0].key_high, + (char *)(((long *) key_from_db) + 1), 4); +#ifndef NOENCRYPTION + des_pcbc_encrypt(key_from_db,key_from_db,(long)sizeof(key_from_db), + master_key_schedule,(des_cblock *)master_key_schedule,DECRYPT); +#endif + /* the decrypted database key had better equal the master key */ + n = bcmp((char *) master_key, (char *) key_from_db, + sizeof(master_key)); + bzero((char *)key_from_db, sizeof(key_from_db)); + + if (n) { + fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, "); + fprintf(stderr, "does not match database.\n"); + exit (-1); + } + + fprintf(stderr, "Master key verified.\n"); + (void) fflush(stderr); + + dump_db (db_file, out, convert_key_old_db); +} + +long +time_explode(cp) +register char *cp; +{ + char wbuf[5]; + struct tm tp; + long maketime(); + int local; + + zaptime(&tp); /* clear out the struct */ + + if (strlen(cp) > 10) { /* new format */ + (void) strncpy(wbuf, cp, 4); + wbuf[4] = 0; + tp.tm_year = atoi(wbuf); + cp += 4; /* step over the year */ + local = 0; /* GMT */ + } else { /* old format: local time, + year is 2 digits, assuming 19xx */ + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_year = 1900 + atoi(wbuf); + local = 1; /* local */ + } + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_mon = atoi(wbuf)-1; + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_mday = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_hour = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_min = atoi(wbuf); + + + return(maketime(&tp, local)); +} diff --git a/eBones/usr.sbin/kerberos/Makefile b/eBones/usr.sbin/kerberos/Makefile new file mode 100644 index 0000000..7f36cf7 --- /dev/null +++ b/eBones/usr.sbin/kerberos/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:22 g89r4222 Exp $ + +PROG= kerberos +SRCS= kerberos.c cr_err_reply.c +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kerberos/cr_err_reply.c b/eBones/usr.sbin/kerberos/cr_err_reply.c new file mode 100644 index 0000000..585fd03 --- /dev/null +++ b/eBones/usr.sbin/kerberos/cr_err_reply.c @@ -0,0 +1,95 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $ + * $Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/types.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +extern int req_act_vno; /* this is defined in the kerberos + * server code */ + +/* + * 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_long time_ws; /* Workstation time */ + u_long 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) req_act_vno; /* KRB_PROT_VERSION; */ + *t = (unsigned char) AUTH_MSG_ERR_REPLY; + *t |= HOST_BYTE_ORDER; + + /* 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/eBones/usr.sbin/kerberos/kerberos.c b/eBones/usr.sbin/kerberos/kerberos.c new file mode 100644 index 0000000..b980577 --- /dev/null +++ b/eBones/usr.sbin/kerberos/kerberos.c @@ -0,0 +1,810 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $ + * $Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> +#include <ctype.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +struct sockaddr_in s_in = {AF_INET}; +int f; + +/* XXX several files in libkdb know about this */ +char *progname; + +static Key_schedule master_key_schedule; +static C_Block master_key; + +static struct timeval kerb_time; +static Principal a_name_data; /* for requesting user */ +static Principal s_name_data; /* for services requested */ +static C_Block session_key; +static C_Block user_key; +static C_Block service_key; +static u_char master_key_version; +static char k_instance[INST_SZ]; +static char log_text[128]; +static char *lt; +static int more; + +static int mflag; /* Are we invoked manually? */ +static int lflag; /* Have we set an alterate log file? */ +static char *log_file; /* name of alt. log file */ +static int nflag; /* don't check max age */ +static int rflag; /* alternate realm specified */ + +/* fields within the received request packet */ +static u_char req_msg_type; +static u_char req_version; +static char *req_name_ptr; +static char *req_inst_ptr; +static char *req_realm_ptr; +static u_char req_no_req; +static u_long req_time_ws; + +int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */ + +static char local_realm[REALM_SZ]; + +/* statistics */ +static long q_bytes; /* current bytes remaining in queue */ +static long q_n; /* how many consecutive non-zero + * q_bytes */ +static long max_q_bytes; +static long max_q_n; +static long n_auth_req; +static long n_appl_req; +static long n_packets; +static long n_user; +static long n_server; + +static long max_age = -1; +static long pause_int = -1; + +static void check_db_age(); +static void hang(); + +/* + * Print usage message and exit. + */ +static void usage() +{ + fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname, + " [-a max_age] [-l log_file] [-r realm]" + ," [database_pathname]" + ); + exit(1); +} + + +main(argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in from; + register int n; + int on = 1; + int child; + struct servent *sp; + int fromlen; + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + Principal *p; + int more, kerror; + C_Block key; + int c; + extern char *optarg; + extern int optind; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) { + switch(c) { + case 's': + /* + * Set parameters to slave server defaults. + */ + if (max_age == -1 && !nflag) + max_age = ONE_DAY; /* 24 hours */ + if (pause_int == -1) + pause_int = FIVE_MINUTES; /* 5 minutes */ + if (lflag == 0) { + log_file = KRBSLAVELOG; + lflag++; + } + break; + case 'n': + max_age = -1; /* don't check max age. */ + nflag++; + break; + case 'm': + mflag++; /* running manually; prompt for master key */ + break; + case 'p': + /* Set pause interval. */ + if (!isdigit(optarg[0])) + usage(); + pause_int = atoi(optarg); + if ((pause_int < 5) || (pause_int > ONE_HOUR)) { + fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n"); + usage(); + } + break; + case 'a': + /* Set max age. */ + if (!isdigit(optarg[0])) + usage(); + max_age = atoi(optarg); + if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) { + fprintf(stderr, "max_age must be between one hour and three days, in seconds\n"); + usage(); + } + break; + case 'l': + /* Set alternate log file */ + lflag++; + log_file = optarg; + break; + case 'r': + /* Set realm name */ + rflag++; + strcpy(local_realm, optarg); + break; + default: + usage(); + break; + } + } + + if (optind == (argc-1)) { + if (kerb_db_set_name(argv[optind]) != 0) { + fprintf(stderr, "Could not set alternate database name\n"); + exit(1); + } + optind++; + } + + if (optind != argc) + usage(); + + printf("Kerberos server starting\n"); + + if ((!nflag) && (max_age != -1)) + printf("\tMaximum database age: %d seconds\n", max_age); + if (pause_int != -1) + printf("\tSleep for %d seconds on error\n", pause_int); + else + printf("\tSleep forever on error\n"); + if (mflag) + printf("\tMaster key will be entered manually\n"); + + printf("\tLog file is %s\n", lflag ? log_file : KRBLOG); + + if (lflag) + kset_logfile(log_file); + + /* find our hostname, and use it as the instance */ + if (gethostname(k_instance, INST_SZ)) { + fprintf(stderr, "%s: gethostname error\n", progname); + exit(1); + } + + if ((sp = getservbyname("kerberos", "udp")) == 0) { + fprintf(stderr, "%s: udp/kerberos unknown service\n", progname); + exit(1); + } + s_in.sin_port = sp->s_port; + + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "%s: Can't open socket\n", progname); + exit(1); + } + if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname); + + if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) { + fprintf(stderr, "%s: Can't bind socket\n", progname); + exit(1); + } + /* do all the database and cache inits */ + if (n = kerb_init()) { + if (mflag) { + printf("Kerberos db and cache init "); + printf("failed = %d ...exiting\n", n); + exit(-1); + } else { + klog(L_KRB_PERR, + "Kerberos db and cache init failed = %d ...exiting", n); + hang(); + } + } + + /* Make sure database isn't stale */ + check_db_age(); + + /* setup master key */ + if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) { + klog (L_KRB_PERR, "kerberos: couldn't get master key.\n"); + exit (-1); + } + kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout); + if (kerror < 0) { + klog (L_KRB_PERR, "Can't verify master key."); + bzero (master_key, sizeof (master_key)); + bzero (master_key_schedule, sizeof (master_key_schedule)); + exit (-1); + } + + master_key_version = (u_char) kerror; + + fprintf(stdout, "\nCurrent Kerberos master key version is %d\n", + master_key_version); + + if (!rflag) { + /* Look up our local realm */ + krb_get_lrealm(local_realm, 1); + } + fprintf(stdout, "Local realm: %s\n", local_realm); + fflush(stdout); + + if (set_tgtkey(local_realm)) { + /* Ticket granting service unknown */ + klog(L_KRB_PERR, "Ticket granting ticket service unknown"); + fprintf(stderr, "Ticket granting ticket service unknown\n"); + exit(1); + } + if (mflag) { + if ((child = fork()) != 0) { + printf("Kerberos started, PID=%d\n", child); + exit(0); + } + setup_disc(); + } + /* receive loop */ + for (;;) { + fromlen = S_AD_SZ; + n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from, + &fromlen); + if (n > 0) { + pkt->length = n; + pkt->mbz = 0; /* force zeros to catch runaway strings */ + /* see what is left in the input queue */ + ioctl(f, FIONREAD, &q_bytes); + gettimeofday(&kerb_time, NULL); + q_n++; + max_q_n = max(max_q_n, q_n); + n_packets++; + klog(L_NET_INFO, + "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d", + q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0); + max_q_bytes = max(max_q_bytes, q_bytes); + if (!q_bytes) + q_n = 0; /* reset consecutive packets */ + kerberos(&from, pkt); + } else + klog(L_NET_ERR, + "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0); + } +} + + +kerberos(client, pkt) + struct sockaddr_in *client; + KTEXT pkt; +{ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; + static KTEXT_ST ciph_st; + KTEXT ciph = &ciph_st; + static KTEXT_ST tk_st; + KTEXT tk = &tk_st; + static KTEXT_ST auth_st; + KTEXT auth = &auth_st; + AUTH_DAT ad_st; + AUTH_DAT *ad = &ad_st; + + + static struct in_addr client_host; + static int msg_byte_order; + static int swap_bytes; + static u_char k_flags; + char *p_name, *instance; + u_long lifetime; + int i; + C_Block key; + Key_schedule key_s; + char *ptr; + + + + ciph->length = 0; + + client_host = client->sin_addr; + + /* eval macros and correct the byte order and alignment as needed */ + req_version = pkt_version(pkt); /* 1 byte, version */ + req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */ + + req_act_vno = req_version; + + /* check packet version */ + if (req_version != KRB_PROT_VERSION) { + lt = klog(L_KRB_PERR, + "KRB prot version mismatch: KRB =%d request = %d", + KRB_PROT_VERSION, req_version, 0); + /* send an error reply */ + kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt); + return; + } + msg_byte_order = req_msg_type & 1; + + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + klog(L_KRB_PINFO, + "Prot version: %d, Byte order: %d, Message type: %d", + req_version, msg_byte_order, req_msg_type); + + switch (req_msg_type & ~1) { + + case AUTH_MSG_KDC_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + n_auth_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + + /* set up and correct for byte order and alignment */ + req_name_ptr = (char *) pkt_a_name(pkt); + req_inst_ptr = (char *) pkt_a_inst(pkt); + req_realm_ptr = (char *) pkt_a_realm(pkt); + bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws)); + /* time has to be diddled */ + if (swap_bytes) { + swap_u_long(req_time_ws); + } + ptr = (char *) pkt_time_ws(pkt) + 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + rpkt = &rpkt_st; + klog(L_INI_REQ, + "Initial ticket request Host: %s User: \"%s\" \"%s\"", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + + if (i = check_princ(req_name_ptr, req_inst_ptr, 0, + &a_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + tk->length = 0; /* init */ + if (strcmp(service, "krbtgt")) + klog(L_NTGT_INTK, + "INITIAL request from %s.%s for %s.%s", + req_name_ptr, req_inst_ptr, service, instance, 0); + /* this does all the checking */ + if (i = check_princ(service, instance, lifetime, + &s_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, ((u_long) s_name_data.max_life)); + lifetime = min(lifetime, ((u_long) a_name_data.max_life)); + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + krb_create_ticket(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + /* + * get the user's key, unseal it from the server's key, and + * use it to seal the cipher + */ + + /* a_name_data.key_low a_name_data.key_high */ + bcopy(&a_name_data.key_low, key, 4); + bcopy(&a_name_data.key_high, ((long *) key) + 1, 4); + + /* unseal the a_name key from the master key */ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + + create_ciph(ciph, session_key, s_name_data.name, + s_name_data.instance, local_realm, lifetime, + s_name_data.key_version, tk, kerb_time.tv_sec, key); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(key, sizeof(key)); + + + + /* always send a reply packet */ + rpkt = create_auth_reply(req_name_ptr, req_inst_ptr, + req_realm_ptr, req_time_ws, 0, a_name_data.exp_date, + a_name_data.key_version, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&a_name_data, sizeof(a_name_data)); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + case AUTH_MSG_APPL_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + char tktrlm[REALM_SZ]; + + n_appl_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + auth->length = 4 + strlen(pkt->dat + 3); + auth->length += (int) *(pkt->dat + auth->length) + + (int) *(pkt->dat + auth->length + 1) + 2; + + bcopy(pkt->dat, auth->dat, auth->length); + + strncpy(tktrlm, auth->dat + 3, REALM_SZ); + if (set_tgtkey(tktrlm)) { + lt = klog(L_ERR_UNK, + "FAILED realm %s unknown. Host: %s ", + tktrlm, inet_ntoa(client_host)); + kerb_err_reply(client, pkt, kerno, lt); + return; + } + kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, + ad, 0); + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", + inet_ntoa(client_host), krb_err_txt[kerno]); + kerb_err_reply(client, pkt, kerno, "krb_rd_req failed"); + return; + } + ptr = (char *) pkt->dat + auth->length; + + bcopy(ptr, &time_ws, 4); + ptr += 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s", + ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host), + service, instance, 0); + + if (strcmp(ad->prealm, tktrlm)) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't hop realms"); + return; + } + if (!strcmp(service, "changepw")) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't authorize password changed based on TGT"); + return; + } + kerno = check_princ(service, instance, req_life, + &s_name_data); + if (kerno) { + kerb_err_reply(client, pkt, kerno, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, + (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300))); + lifetime = min(lifetime, ((u_long) s_name_data.max_life)); + + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + + krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, + ad->prealm, client_host, + session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + create_ciph(ciph, session_key, service, instance, + local_realm, + lifetime, s_name_data.key_version, tk, + kerb_time.tv_sec, ad->session); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(ad->session, sizeof(ad->session)); + + rpkt = create_auth_reply(ad->pname, ad->pinst, + ad->prealm, time_ws, + 0, 0, 0, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + + +#ifdef notdef_DIE + case AUTH_MSG_DIE: + { + lt = klog(L_DEATH_REQ, + "Host: %s User: \"%s\" \"%s\" Kerberos killed", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + exit(0); + } +#endif notdef_DIE + + default: + { + lt = klog(L_KRB_PERR, + "Unknown message type: %d from %s port %u", + req_msg_type, inet_ntoa(client_host), + ntohs(client->sin_port)); + break; + } + } +} + + +/* + * setup_disc + * + * disconnect all descriptors, remove ourself from the process + * group that spawned us. + */ + +setup_disc() +{ + + int s; + + for (s = 0; s < 3; s++) { + (void) close(s); + } + + (void) open("/dev/null", 0); + (void) dup2(0, 1); + (void) dup2(0, 2); + + s = open("/dev/tty", 2); + + if (s >= 0) { + ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); + (void) close(s); + } + (void) chdir("/tmp"); + return; +} + + +/* + * kerb_er_reply creates an error reply packet and sends it to the + * client. + */ + +kerb_err_reply(client, pkt, err, string) + struct sockaddr_in *client; + KTEXT pkt; + long err; + char *string; + +{ + static KTEXT_ST e_pkt_st; + KTEXT e_pkt = &e_pkt_st; + static char e_msg[128]; + + strcpy(e_msg, "\nKerberos error -- "); + strcat(e_msg, string); + cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, + req_time_ws, err, e_msg); + sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + +} + +/* + * Make sure that database isn't stale. + * + * Exit if it is; we don't want to tell lies. + */ + +static void check_db_age() +{ + long age; + + if (max_age != -1) { + /* Requires existance of kerb_get_db_age() */ + gettimeofday(&kerb_time, 0); + age = kerb_get_db_age(); + if (age == 0) { + klog(L_KRB_PERR, "Database currently being updated!"); + hang(); + } + if ((age + max_age) < kerb_time.tv_sec) { + klog(L_KRB_PERR, "Database out of date!"); + hang(); + /* NOTREACHED */ + } + } +} + +check_princ(p_name, instance, lifetime, p) + char *p_name; + char *instance; + unsigned lifetime; + + Principal *p; +{ + static int n; + static int more; + long trans; + + n = kerb_get_principal(p_name, instance, p, 1, &more); + klog(L_ALL_REQ, + "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", + p_name, instance, lifetime, n, 0); + + if (n < 0) { + lt = klog(L_KRB_PERR, "Database unavailable!"); + hang(); + } + + /* + * if more than one p_name, pick one, randomly create a session key, + * compute maximum lifetime, lookup authorizations if applicable, + * and stuff into cipher. + */ + if (n == 0) { + /* service unknown, log error, skip to next request */ + lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_PRINCIPAL_UNKNOWN; + } + if (more) { + /* not unique, log error */ + lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"", + p_name, instance, 0); + return KERB_ERR_PRINCIPAL_NOT_UNIQUE; + } + /* If the user's key is null, we want to return an error */ + if ((p->key_low == 0) && (p->key_high == 0)) { + /* User has a null key */ + lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_NULL_KEY; + } + if (master_key_version != p->kdc_key_ver) { + /* log error reply */ + lt = klog(L_ERR_MKV, + "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d", + master_key_version, p->name, p->instance, p->kdc_key_ver, + 0); + return KERB_ERR_NAME_MAST_KEY_VER; + } + /* make sure the service hasn't expired */ + if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) { + /* service did expire, log it */ + lt = klog(L_ERR_SEXP, + "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance, + stime(&(p->exp_date)), 0); + return KERB_ERR_NAME_EXP; + } + /* ok is zero */ + return 0; +} + + +/* Set the key for krb_rd_req so we can check tgt */ +set_tgtkey(r) + char *r; /* Realm for desired key */ +{ + int n; + static char lastrealm[REALM_SZ]; + Principal p_st; + Principal *p = &p_st; + C_Block key; + + if (!strcmp(lastrealm, r)) + return (KSUCCESS); + + log("Getting key for %s", r); + + n = kerb_get_principal("krbtgt", r, p, 1, &more); + if (n == 0) + return (KFAILURE); + + /* unseal tgt key from master key */ + bcopy(&p->key_low, key, 4); + bcopy(&p->key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + krb_set_key(key, 0); + strcpy(lastrealm, r); + return (KSUCCESS); +} + +static void +hang() +{ + if (pause_int == -1) { + klog(L_KRB_PERR, "Kerberos will pause so as not to loop init"); + for (;;) + pause(); + } else { + char buf[256]; + sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int); + klog(L_KRB_PERR, buf); + sleep(pause_int); + klog(L_KRB_PERR, "Do svedania....\n"); + exit(1); + } +} diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.8 b/eBones/usr.sbin/ksrvutil/ksrvutil.8 new file mode 100644 index 0000000..a7fed82 --- /dev/null +++ b/eBones/usr.sbin/ksrvutil/ksrvutil.8 @@ -0,0 +1,93 @@ +.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $ +.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvutil \- host kerberos keyfile (srvtab) manipulation utility +.SH SYNOPSIS +ksrvutil +.B operation +[ +.B \-k +] [ +.B \-i +] [ +.B \-f filename +] +.SH DESCRIPTION +.I ksrvutil +allows a system manager to list or change keys currently in his +keyfile or to add new keys to the keyfile. +.PP + +Operation must be one of the following: +.TP 10n +.I list +lists the keys in a keyfile showing version number and principal +name. If the \-k option is given, keys will also be shown. +.TP 10n +.I change +changes all the keys in the keyfile by using the regular admin +protocol. If the \-i flag is given, +.I ksrvutil +will prompt for yes or no before changing each key. If the \-k +option is used, the old and new keys will be displayed. +.TP 10n +.I add +allows the user to add a key. +.I add +prompts for name, instance, realm, and key version number, asks +for confirmation, and then asks for a password. +.I ksrvutil +then converts the password to a key and appends the keyfile with +the new information. If the \-k option is used, the key is +displayed. + +.PP +In all cases, the default file used is KEY_FILE as defined in +krb.h unless this is overridden by the \-f option. + +.PP +A good use for +.I ksrvutil +would be for adding keys to a keyfile. A system manager could +ask a kerberos administrator to create a new service key with +.IR kadmin (8) +and could supply an initial password. Then, he could use +.I ksrvutil +to add the key to the keyfile and then to change the key so that +it will be random and unknown to either the system manager or +the kerberos administrator. + +.I ksrvutil +always makes a backup copy of the keyfile before making any +changes. + +.SH DIAGNOSTICS +If +.I ksrvutil +should exit on an error condition at any time during a change or +add, a copy of the +original keyfile can be found in +.IR filename .old +where +.I filename +is the name of the keyfile, and a copy of the file with all new +keys changed or added so far can be found in +.IR filename .work. +The original keyfile is left unmodified until the program exits +at which point it is removed and replaced it with the workfile. +Appending the workfile to the backup copy and replacing the +keyfile with the result should always give a usable keyfile, +although the resulting keyfile will have some out of date keys +in it. + +.SH SEE ALSO +kadmin(8), ksrvtgt(1) + +.SH AUTHOR +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/usr.sbin/kstash/Makefile b/eBones/usr.sbin/kstash/Makefile new file mode 100644 index 0000000..8331c97a --- /dev/null +++ b/eBones/usr.sbin/kstash/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.2 (Berkeley) 3/5/91 +# $Id: Makefile,v 1.2 1994/07/19 19:27:04 g89r4222 Exp $ + +PROG= kstash +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kstash/kstash.8 b/eBones/usr.sbin/kstash/kstash.8 new file mode 100644 index 0000000..d83379a --- /dev/null +++ b/eBones/usr.sbin/kstash/kstash.8 @@ -0,0 +1,41 @@ +.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $ +.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kstash \- stash Kerberos key distribution center database master key +.SH SYNOPSIS +kstash +.SH DESCRIPTION +.I kstash +saves the Kerberos key distribution center (KDC) database master key in +the master key cache file. +.PP +The user is prompted to enter the key, to verify the authenticity of the +key and the authorization to store the key in the file. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.TP +"kstash: Unable to open master key file" +The attempt to open the cache file for writing failed (probably due to a +system or access permission error). +.TP +"kstash: Write I/O error on master key file" +The +.BR write (2) +system call returned an error while +.I kstash +was attempting to write the key to the file. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/usr.sbin/kstash/kstash.c b/eBones/usr.sbin/kstash/kstash.c new file mode 100644 index 0000000..696e4e1 --- /dev/null +++ b/eBones/usr.sbin/kstash/kstash.c @@ -0,0 +1,92 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $ + * $Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +/* change this later, but krblib_dbm needs it for now */ +char *progname; + +static C_Block master_key; +static Key_schedule master_key_schedule; +static Principal s_name_data; /* for services requested */ +static unsigned char master_key_version; +int debug; +static int more; +static int kfile; +static void clear_secrets(); + +main(argc, argv) + int argc; + char **argv; +{ + long n; + if (n = kerb_init()) { + fprintf(stderr, "Kerberos db and cache init failed = %d\n", n); + exit(1); + } + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]); + fflush (stderr); + clear_secrets(); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets(); + exit (-1); + } + + kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600); + if (kfile < 0) { + clear_secrets(); + fprintf(stderr, "\n\07\07%s: Unable to open master key file\n", + argv[0]); + exit(1); + } + if (write(kfile, (char *) master_key, 8) < 0) { + clear_secrets(); + fprintf(stderr, "\n%s: Write I/O error on master key file\n", + argv[0]); + exit(1); + } + (void) close(kfile); + clear_secrets(); +} + +static void +clear_secrets() +{ + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(master_key, sizeof(master_key)); +} diff --git a/eBones/usr.sbin/make_keypair/Makefile b/eBones/usr.sbin/make_keypair/Makefile new file mode 100644 index 0000000..b00048e --- /dev/null +++ b/eBones/usr.sbin/make_keypair/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 + +PROG= make_keypair +MAN8= make_keypair.8 +CFLAGS+=-DKERBEROS -I${.CURDIR}/../register +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/make_keypair/make_keypair.8 b/eBones/usr.sbin/make_keypair/make_keypair.8 new file mode 100644 index 0000000..d0b7b88 --- /dev/null +++ b/eBones/usr.sbin/make_keypair/make_keypair.8 @@ -0,0 +1,87 @@ +.\" Copyright (c) 1988, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)make_keypair.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt MAKE_KEYPAIR 8 +.Os +.Sh NAME +.Nm make_keypair +.Nd generate Kerberos host key pair +.Sh SYNOPSIS +.Nm make_keypair +.Ar hostname +.Op Ar hostname ... +.Sh DESCRIPTION +The +.Nm make_keypair +command +is used to create pairs of +.Tn DES +keys for +each +.Ar hostname . +The keys are used by privileged programs such as +.Xr register 1 +to make remote updates to the Kerberos database without +having to have first acquired a Kerberos ticket granting ticket +.Pq Tn TGT . +The keys created by +.Nm make_keypair +are placed (by hand) in the filesystems of the +kerberos server in +.Pa /etc/kerberosIV/register_keys , +and in the root directory of the clients. +For example, the file +.Pa /.update.key128.32.130.3 +would +contain a copy of the key of the client with +IP address 128.32.130.3. +These keys provide a shared secret which may be used to establish +a secure channel between the client hosts and the Kerberos server. +.Sh FILES +.Bl -tag -width /etc/kerberosIV/register_keysxx -compact +.It Pa /.update.keyxx.xx.xx.xx +shared +.Tn DES +key with server +.It Pa /etc/kerberosIV/register_keys +server's key storage directory +.El +.Sh SEE ALSO +.Xr register 1 , +.Xr registerd 8 , +.Xr kerberos 1 +.Sh HISTORY +The +.Nm make_keypair +utility first appeared in 4.4BSD. diff --git a/eBones/usr.sbin/make_keypair/make_keypair.c b/eBones/usr.sbin/make_keypair/make_keypair.c new file mode 100644 index 0000000..c9883ed --- /dev/null +++ b/eBones/usr.sbin/make_keypair/make_keypair.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <stdio.h> +#include <netdb.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include "pathnames.h" +#include "register_proto.h" + +extern void random_key(), herror(); +void make_key(), usage(); + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + char *addr; + int i; + struct sockaddr_in sin; + + progname = *argv; /* argv[0] */ + + if (argc != 2) { + usage(argv[0]); + exit(1); + } + + if ((hp = gethostbyname(argv[1])) == NULL) { + herror(argv[1]); + exit(1); + } + + for (i = 0; addr = hp->h_addr_list[i]; i++) { + addr = hp->h_addr_list[i]; + bcopy(addr, &sin.sin_addr, hp->h_length); + + printf("Making key for host %s (%s)\n", + argv[1], inet_ntoa(sin.sin_addr)); + make_key(sin.sin_addr); + } + printf("==========\n"); + printf("One copy of the each key should be put in %s on the\n", + SERVER_KEYDIR); + printf("Kerberos server machine (mode 600, owner root).\n"); + printf("Another copy of each key should be put on the named\n"); + printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n", + CLIENT_KEYFILE); + printf("where the X's refer to digits of the host's inet address.\n"); + (void)fflush(stdout); + exit(0); +} + +void +make_key(addr) + struct in_addr addr; +{ + struct keyfile_data kfile; + char namebuf[255]; + int fd; + + (void)sprintf(namebuf, "%s%s", + CLIENT_KEYFILE, + inet_ntoa(addr)); + fd = open(namebuf, O_WRONLY|O_CREAT, 0600); + if (fd < 0) { + perror("open"); + exit(1); + } + random_key(kfile.kf_key); + printf("writing to file -> %s ...", namebuf); + if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) { + fprintf(stderr, "error writing file %s\n", namebuf); + } + printf("done.\n"); + (void)close(fd); + return; +} + +void +usage(name) + char *name; +{ + fprintf(stderr, "usage: %s host\n", name); +} diff --git a/usr.bin/compile_et/Makefile b/usr.bin/compile_et/Makefile new file mode 100644 index 0000000..9b988267 --- /dev/null +++ b/usr.bin/compile_et/Makefile @@ -0,0 +1,15 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:21:23 g89r4222 Exp $ + +PROG= compile_et +CFLAGS+=-I. -I${.CURDIR} +SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c +OBJS+= error_table.o +DPADD= ${LIBL} +LDADD= -ll +CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c +NOMAN= noman + +error_table.c: et_lex.lex.c + +.include <bsd.prog.mk> diff --git a/usr.bin/compile_et/compile_et.c b/usr.bin/compile_et/compile_et.c new file mode 100644 index 0000000..25be70b --- /dev/null +++ b/usr.bin/compile_et/compile_et.c @@ -0,0 +1,172 @@ +/* + * + * Copyright 1986, 1987 by MIT Student Information Processing Board + * For copyright info, see "Copyright.SIPB". + * + * $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $ + */ + +#include <stdio.h> +#include <sys/file.h> +#include <strings.h> +#include <sys/param.h> + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +extern char *gensym(); +extern char *current_token; +extern int table_number, current; +char buffer[BUFSIZ]; +char *table_name = (char *)NULL; +FILE *hfile, *cfile; + +/* C library */ +extern char *malloc(); +extern int errno; + +/* lex stuff */ +extern FILE *yyin; +extern int yylineno; + +/* pathnames */ +char c_file[MAXPATHLEN]; /* temporary file */ +char h_file[MAXPATHLEN]; /* output */ +char o_file[MAXPATHLEN]; /* output */ +char et_file[MAXPATHLEN]; /* input */ + +main(argc, argv) + int argc; + char **argv; +{ + register char *p; + int n_flag = 0, debug = 0; + + while (argc > 2) { + register char *arg, ch; + arg = argv[--argc]; + if (strlen(arg) != 2 || arg[0] != '-') + goto usage; + ch = arg[1]; + if (ch == 'n') + n_flag++; + else if (ch == 'd') + debug++; + else + goto usage; + } + + if (argc != 2) { + usage: + fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]); + exit(1); + } + + strcpy(et_file, argv[1]); + p = rindex(et_file, '/'); + if (p == (char *)NULL) + p = et_file; + else + p++; + p = rindex(p, '.'); + if (!strcmp(p, ".et")) + *++p = '\0'; + else { + if (!p) + p = et_file; + while (*p) + p++; + *p++ = '.'; + *p = '\0'; + } + /* p points at null where suffix should be */ + strcpy(p, "et.c"); + strcpy(c_file, et_file); + p[0] = 'h'; + p[1] = '\0'; + strcpy(h_file, et_file); + p[0] = 'o'; + strcpy(o_file, et_file); + p[0] = 'e'; + p[1] = 't'; + p[2] = '\0'; + + yyin = fopen(et_file, "r"); + if (!yyin) { + perror(et_file); + exit(1); + } + + hfile = fopen(h_file, "w"); + if (hfile == (FILE *)NULL) { + perror(h_file); + exit(1); + } + + cfile = fopen(c_file, "w"); + if (cfile == (FILE *)NULL) { + perror("Can't open temp file"); + exit(1); + } + + /* parse it */ + fputs("#define NULL 0\n", cfile); + fputs("static char *_et[] = {\n", cfile); + + yyparse(); + fclose(yyin); /* bye bye input file */ + + fputs("\t(char *)0\n};\n", cfile); + fputs("extern int init_error_table();\n\n", cfile); + fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number); + fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name); + fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n", + table_number, current); + fclose(cfile); + + fputs("extern int init_", hfile); + fputs(table_name, hfile); + fputs("_err_tbl();\nextern int ", hfile); + fputs(table_name, hfile); + fputs("_err_base;\n", hfile); + fclose(hfile); /* bye bye hfile */ + + if (n_flag) + exit(0); + + if (!fork()) { + p = rindex(c_file, '/'); + if (p) { + *p++ = '\0'; + chdir(c_file); + } + else + p = c_file; + execlp("cc", "cc", "-c", "-R", "-O", p, 0); + perror("cc"); + exit(1); + } + else wait(0); + + if (!debug) + (void) unlink(c_file); + /* make it .o file name */ + c_file[strlen(c_file)-1] = 'o'; + if (!fork()) { + execlp("cp", "cp", c_file, o_file, 0); + perror("cp"); + exit(1); + } + else wait(0); + if (!debug) + (void) unlink(c_file); + + exit(0); +} + +yyerror(s) + char *s; +{ + fputs(s, stderr); + fprintf(stderr, "\nLine number %d; last token was '%s'\n", + yylineno, current_token); +} diff --git a/usr.bin/compile_et/error_message.c b/usr.bin/compile_et/error_message.c new file mode 100644 index 0000000..92cec57 --- /dev/null +++ b/usr.bin/compile_et/error_message.c @@ -0,0 +1,77 @@ +/* + * Copyright 1987 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * For copyright info, see "Copyright.SIPB". + * + * from: error_message.c,v 1.1 86/11/10 21:34:34 spook Exp $ + * $Id: error_message.c,v 1.3 1994/09/09 21:43:22 g89r4222 Exp $ + */ + +#include <stdio.h> +#include "error_table.h" +extern int sys_nerr; + +static char buffer[25]; + +char * +error_message(code) + int code; +{ + register int offset; + register error_table **et; + register int table_num; + register int div; + register char *cp; + + offset = code & ((1<<ERRCODE_RANGE)-1); + table_num = code - offset; + if ((_et_list == (error_table **)NULL) && table_num) + goto oops; + if (!table_num) { + if (offset < sys_nerr) + return(sys_errlist[offset]); + else + goto oops; + } + for (et = _et_list; *et != (error_table *)NULL; et++) { + if ((*et)->base == table_num) { + /* This is the right table */ + if ((*et)->n_msgs <= offset) + goto oops; + return((*et)->msgs[offset]); + } + } + oops: + cp = buffer; + { + register char *cp1; + for (cp1 = "Unknown code "; *cp1; cp1++, cp++) + *cp = *cp1; + if (table_num) { + for (cp1 = error_table_name(table_num); *cp1; cp1++, cp++) + *cp = *cp1; + *cp++ = ' '; + *cp = '\0'; + } + } + div = 1000000000; + if (offset == 0) { + *cp++ = '0'; + *cp = '\0'; + return(buffer); + } + while (div > offset) + div /= 10; + do { + register int n = offset / div; + *cp++ = '0' + n; + offset -= n * div; + div /= 10; + } while (offset && div); + while (div) { + *cp++ = '0'; + div /= 10; + } + *cp = '\0'; + return(buffer); +} diff --git a/usr.bin/compile_et/error_table.h b/usr.bin/compile_et/error_table.h new file mode 100644 index 0000000..e32ec30 --- /dev/null +++ b/usr.bin/compile_et/error_table.h @@ -0,0 +1,17 @@ +#ifndef _ET +extern int errno; +typedef struct { + char **msgs; + int base; + int n_msgs; +} error_table; +extern error_table **_et_list; + +#define ERROR_CODE "int" /* type used for error codes */ + +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ + +extern char *error_table_name(); +#define _ET +#endif diff --git a/usr.bin/compile_et/error_table.y b/usr.bin/compile_et/error_table.y new file mode 100644 index 0000000..3913a84 --- /dev/null +++ b/usr.bin/compile_et/error_table.y @@ -0,0 +1,205 @@ +%{ +#include <stdio.h> +char *str_concat(), *ds(), *quote(), *malloc(), *realloc(); +char *current_token = (char *)NULL; +extern char *table_name; +%} +%union { + char *dynstr; +} + +%token ERROR_TABLE ERROR_CODE_ENTRY END +%token <dynstr> STRING QUOTED_STRING +%type <dynstr> ec_name description table_id +%{ +%} +%start error_table +%% + +error_table : ERROR_TABLE table_id error_codes END + { table_name = ds($2); + current_token = table_name; + put_ecs(); } + ; + +table_id : STRING + { current_token = $1; + set_table_num($1); + $$ = $1; } + ; + +error_codes : error_codes ec_entry + | ec_entry + ; + +ec_entry : ERROR_CODE_ENTRY ec_name ',' description + { add_ec($2, $4); + free($2); + free($4); } + | ERROR_CODE_ENTRY ec_name '=' STRING ',' description + { add_ec_val($2, $4, $6); + free($2); + free($4); + free($6); + } + ; + +ec_name : STRING + { $$ = ds($1); + current_token = $$; } + ; + +description : QUOTED_STRING + { $$ = ds($1); + current_token = $$; } + ; + +%% +/* + * Copyright 1986, 1987 by the MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + */ + +#include <stdlib.h> +#include <strings.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/time.h> +#include "error_table.h" + +extern FILE *hfile, *cfile; + +static long gensym_n = 0; +char * +gensym(x) + char *x; +{ + char *symbol; + if (!gensym_n) { + struct timeval tv; + struct timezone tzp; + gettimeofday(&tv, &tzp); + gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000; + } + symbol = malloc(32 * sizeof(char)); + gensym_n++; + sprintf(symbol, "et%ld", gensym_n); + return(symbol); +} + +char * +ds(string) + char *string; +{ + char *rv; + rv = malloc(strlen(string)+1); + strcpy(rv, string); + return(rv); +} + +char * +quote(string) + char *string; +{ + char *rv; + rv = malloc(strlen(string)+3); + strcpy(rv, "\""); + strcat(rv, string); + strcat(rv, "\""); + return(rv); +} + +int table_number; +int current = 0; +char **error_codes = (char **)NULL; + +add_ec(name, description) + char *name, *description; +{ + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +add_ec_val(name, val, description) + char *name, *val, *description; +{ + int ncurrent = atoi(val); + if (ncurrent < current) { + printf("Error code %s (%d) out of order", name, + current); + return; + } + + while (ncurrent > current) + fputs("\t(char *)NULL,\n", cfile), current++; + + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +put_ecs() +{ + int i; + for (i = 0; i < current; i++) { + if (error_codes[i] != (char *)NULL) + fprintf(hfile, "#define %-40s ((%s)%d)\n", + error_codes[i], ERROR_CODE, table_number + i); + } +} + +/* + * char_to_num -- maps letters and numbers into a small numbering space + * uppercase -> 1-26 + * lowercase -> 27-52 + * digits -> 53-62 + * underscore-> 63 + */ +int +char_to_num(c) + char c; +{ + if (isupper(c)) + return(c-'A'+1); + else if (islower(c)) + return(c-'a'+27); + else if (isdigit(c)) + return(c-'0'+53); + else { + fprintf(stderr, "Illegal character in name: %c\n", c); + exit(1); + /*NOTREACHED*/ + } +} + +set_table_num(string) + char *string; +{ + if (strlen(string) > 4) { + fprintf(stderr, "Table name %s too long, truncated ", + string); + string[4] = '\0'; + fprintf(stderr, "to %s\n", string); + } + while (*string != '\0') { + table_number = (table_number << BITS_PER_CHAR) + + char_to_num(*string); + string++; + } + table_number = table_number << ERRCODE_RANGE; +} + +#include "et_lex.lex.c" diff --git a/usr.bin/compile_et/et_lex.lex.l b/usr.bin/compile_et/et_lex.lex.l new file mode 100644 index 0000000..c041819 --- /dev/null +++ b/usr.bin/compile_et/et_lex.lex.l @@ -0,0 +1,29 @@ +%{ +extern int yylineno; +int yylineno = 1; +%} + +PC [^\"\n] +AN [A-Z_a-z0-9] +%% + +error_table return ERROR_TABLE; +et return ERROR_TABLE; +error_code return ERROR_CODE_ENTRY; +ec return ERROR_CODE_ENTRY; +end return END; + +[\t ]+ ; +\n ++yylineno; + +\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1); + if (p=rindex(yylval.dynstr, '"')) *p='\0'; + return QUOTED_STRING; + } + +{AN}* { yylval.dynstr = ds(yytext); return STRING; } + +#.*\n ++yylineno; + +. { return (*yytext); } +%% diff --git a/usr.bin/compile_et/et_name.c b/usr.bin/compile_et/et_name.c new file mode 100644 index 0000000..98ccb08 --- /dev/null +++ b/usr.bin/compile_et/et_name.c @@ -0,0 +1,44 @@ +/* + * Copyright 1987 by MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + * + * $Id: et_name.c,v 1.2 1994/07/19 19:21:27 g89r4222 Exp $ + */ + +#include "error_table.h" + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +char *malloc(); + +char * +error_table_name(num) + int num; +{ + register int ch; + register int i; + register char *buf, *p; + + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ + buf = malloc(5); + p = buf; + num >>= ERRCODE_RANGE; + /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ + num &= 077777777; + /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ + for (i = 0; i < 5; i++) { + ch = (num >> 24-6*i) & 077; + if (ch == 0) + continue; + else if (ch < 27) + *p++ = ch - 1 + 'A'; + else if (ch < 53) + *p++ = ch - 27 + 'a'; + else if (ch < 63) + *p++ = ch - 53 + '0'; + else /* ch == 63 */ + *p++ = '_'; + } + return(buf); +} + diff --git a/usr.bin/compile_et/init_et.c b/usr.bin/compile_et/init_et.c new file mode 100644 index 0000000..c23facb --- /dev/null +++ b/usr.bin/compile_et/init_et.c @@ -0,0 +1,67 @@ +/* + * Copyright 1986 by MIT Information Systems and + * MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB. + * + * form: init_et.c,v 1.1 86/11/10 21:42:26 spook Exp $ + * $Id: init_et.c,v 1.2 1994/07/19 19:21:28 g89r4222 Exp $ + */ + +#include <stdio.h> +#include "error_table.h" + +static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board"; + +extern char *malloc(), *realloc(); + +/* useful */ +typedef error_table *etp; +typedef etp *etpp; + +etpp _et_list = (etpp)NULL; +static int n_allocated = 0, n_used = 0; + +int +init_error_table(msgs, base, count) + char **msgs; + register int base; + int count; +{ + register int i; + register etp new_et; + register etpp list; + + if (!base || !count || !msgs) + return; + + new_et = (etp)malloc(sizeof(error_table)); + new_et->msgs = msgs; + new_et->base = base; + new_et->n_msgs= count; + + list = _et_list; + if (list == (etpp)NULL) { + _et_list = (etpp) malloc(10*sizeof(etp)); + list = _et_list; + if (list == (etpp)NULL) + return; /* oops */ + list[0] = new_et; + list[1] = (etp)NULL; + n_allocated = 10; + n_used = 1; + return; + } + for (i = 0; i < n_used; i++) + if (list[i]->base == base) + return; /* avoid duplicates */ + if (n_used+2 > n_allocated) { + n_allocated += 10; /* don't re-allocate too often */ + list = (etpp) realloc((char *)list, + (unsigned)n_allocated * sizeof(etp)); + _et_list = list; + if (list == (etpp)NULL) + return; /* oops */ + } + list[n_used++] = new_et; + list[n_used] = (etp)NULL; +} diff --git a/usr.bin/compile_et/perror.c b/usr.bin/compile_et/perror.c new file mode 100644 index 0000000..ef50e07 --- /dev/null +++ b/usr.bin/compile_et/perror.c @@ -0,0 +1,76 @@ +/* + * Copyright 1987 by MIT Student Information Processing Board + * For copyright info, see Copyright.SIPB + * + * $Id: perror.c,v 1.2 1994/07/19 19:21:30 g89r4222 Exp $ + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/uio.h> +#include "error_table.h" + +typedef int (*int_func)(); + +#if defined(mips) && defined(ultrix) +int errno; /* this is needed to keep the loader from complaining */ +#endif + +int_func com_err_hook = (int_func) NULL; +char *error_message(); + +void +com_err(whoami, code, message) + char *whoami; + int code; + char *message; +{ + struct iovec strings[6]; + + if (com_err_hook) { + (*com_err_hook)(whoami, code, message); + return; + } + + strings[0].iov_base = whoami; + strings[0].iov_len = strlen(whoami); + if (whoami) { + strings[1].iov_base = ": "; + strings[1].iov_len = 2; + } else + strings[1].iov_len = 0; + if (code) { + register char *errmsg = error_message(code); + strings[2].iov_base = errmsg; + strings[2].iov_len = strlen(errmsg); + } else + strings[2].iov_len = 0; + strings[3].iov_base = " "; + strings[3].iov_len = 1; + strings[4].iov_base = message; + strings[4].iov_len = strlen(message); + strings[5].iov_base = "\n"; + strings[5].iov_len = 1; + (void) writev(2, strings, 6); +} + +int_func +set_com_err_hook(new_proc) + int_func new_proc; +{ + register int_func x = com_err_hook; + com_err_hook = new_proc; + return (x); +} + +reset_com_err_hook() +{ + com_err_hook = (int_func) NULL; +} + +void +perror(msg) + register const char *msg; +{ + com_err(msg, errno, (char *)NULL); +} diff --git a/usr.bin/compile_et/test/test.c b/usr.bin/compile_et/test/test.c new file mode 100644 index 0000000..df430da --- /dev/null +++ b/usr.bin/compile_et/test/test.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <errno.h> +#include "test1.h" +#include "test2.h" +char *error_message(); +extern int sys_nerr, errno; + +main() +{ + printf("\nBefore initiating error table:\n\n"); + printf("Table name '%s'\n", error_table_name(KRB_MK_AP_TGTEXP)); + printf("UNIX name '%s'\n", error_table_name(EPERM)); + printf("Msg TGT-expired is '%s'\n", error_message(KRB_MK_AP_TGTEXP)); + printf("Msg EPERM is '%s'\n", error_message(EPERM)); + printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR)); + printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1)); + printf("Msg {sys_nerr} is '%s'\n", error_message(sys_nerr)); + + init_error_table(0, 0, 0); + printf("With 0: tgt-expired -> %s\n", error_message(KRB_MK_AP_TGTEXP)); + + init_krb_err_tbl(); + printf("KRB error table initialized: base %d (%s), name %s\n", + krb_err_base, error_message(krb_err_base), + error_table_name(krb_err_base)); + printf("With krb: tgt-expired -> %s\n", + error_message(KRB_MK_AP_TGTEXP)); + + init_quux_err_tbl(); + printf("QUUX error table initialized: base %d (%s), name %s\n", + quux_err_base, error_message(quux_err_base), + error_table_name(quux_err_base)); + + printf("Msg for TGT-expired is '%s'\n", + error_message(KRB_MK_AP_TGTEXP)); + printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1)); + printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR)); + printf("Msg KRB_SKDC_CANT is '%s'\n", + error_message(KRB_SKDC_CANT)); + printf("Msg 1e6 is '%s'\n", error_message(1000000)); + errno = FOO_ERR; + perror("FOO_ERR"); +} diff --git a/usr.bin/compile_et/test/test1.et b/usr.bin/compile_et/test/test1.et new file mode 100644 index 0000000..4c7b77f --- /dev/null +++ b/usr.bin/compile_et/test/test1.et @@ -0,0 +1,69 @@ + error_table krb + + error_code KRB_MK_AP_TKFIL, + "Can't read ticket file" + + ec KRB_MK_AP_NOTKT, + "Can't find ticket or TGT" + + ec KRB_MK_AP_TGTEXP, + "TGT expired" + + ec KRB_RD_AP_UNDEC, + "Can't decode authenticator" + + ec KRB_RD_AP_EXP, + "Ticket expired" + + ec KRB_RD_AP_REPEAT, + "Repeated request" + + ec KRB_RD_AP_NOT_US, + "The ticket isn't for us" + + ec KRB_RD_AP_INCON, + "Request is inconsistent" + + ec KRB_RD_AP_TIME, + "Delta-T too big" + + ec KRB_RD_AP_BADD, + "Incorrect net address" + + ec KRB_RD_AP_VERSION, + "Protocol version mismatch" + + ec KRB_RD_AP_MSG_TYPE, + "Invalid message type" + + ec KRB_RD_AP_MODIFIED, + "Message stream modified" + + ec KRB_RD_AP_ORDER, + "Message out of order" + + ec KRB_RD_AP_UNAUTHOR, + "Unauthorized request" + + ec KRB_GT_PW_NULL, + "Current password is null" + + ec KRB_GT_PW_BADPW, + "Incorrect current password" + + ec KRB_GT_PW_PROT, + "Protocol error" + + ec KRB_GT_PW_KDCERR, + "Error returned by KDC" + + ec KRB_GT_PW_NULLTKT, + "Null ticket returned by KDC" + + ec KRB_SKDC_RETRY, + "Retry count exceeded" + + ec KRB_SKDC_CANT, + "Can't send request" + + end diff --git a/usr.bin/compile_et/test/test2.et b/usr.bin/compile_et/test/test2.et new file mode 100644 index 0000000..55ad74e --- /dev/null +++ b/usr.bin/compile_et/test/test2.et @@ -0,0 +1,9 @@ + error_table quux + + ec FOO_ERR, "foo" + + ec BAR_ERR, "bar" + + ec BAZ_ERR, "meow" + + end |