From: tholo Date: Thu, 14 Dec 1995 06:52:32 +0000 (+0000) Subject: Kerberos IV code, based on a merge of fixed code from KTH and original X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=782641ca95560311582bf978631e6676d950a9d0;p=openbsd Kerberos IV code, based on a merge of fixed code from KTH and original 4.4BSD Lite code (international edition). Provides all functionality from the original 4.4BSD code plus standard Kerberos elements that were omitted in the 4.4BSD code. --- diff --git a/kerberosIV/Makefile b/kerberosIV/Makefile new file mode 100644 index 00000000000..b8075408a36 --- /dev/null +++ b/kerberosIV/Makefile @@ -0,0 +1,20 @@ +# from @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ + +# do compile_et and mk_cmds first, used by other directories + +.ifmake install +SUBDIR= include +.else +SUBDIR= compile_et mk_cmds +.endif + +SUBDIR+=acl com_err des krb kadm kafs kdb ss + +SUBDIR+=ext_srvtab kadmin kadmind kdb_destroy kdb_edit kdb_init kdb_util \ + kdestroy kerberos kinit klist kpasswdd kprop kpropd ksrvtgt ksrvutil \ + kstash make_keypair register registerd + +SUBDIR+=man + +.include diff --git a/kerberosIV/Makefile.inc b/kerberosIV/Makefile.inc new file mode 100644 index 00000000000..4a570157baf --- /dev/null +++ b/kerberosIV/Makefile.inc @@ -0,0 +1,23 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/1/93 +# $Id: Makefile.inc,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ + +CFLAGS+=-I${.CURDIR}/../include +BINDIR?=/usr/sbin + +.if exists(${.CURDIR}/../mk_cmds/obj) +MK_CMDS=${.CURDIR}/../mk_cmds/obj/mk_cmds +.else +MK_CMDS=${.CURDIR}/../mk_cmds/mk_cmds +.endif + +.if exists(${.CURDIR}/../compile_et/obj) +COMPILE_ET=${.CURDIR}/../compile_et/obj/compile_et +.else +COMPILE_ET=${.CURDIR}/../compile_et/compile_et +.endif + +.if exists(${.CURDIR}/../com_err/obj) +COM_ERR=-L${.CURDIR}/../com_err/obj -lcom_err_pic +.else +COM_ERR=-L${.CURDIR}/../com_err -lcom_err_pic +.endif diff --git a/kerberosIV/acl/Makefile b/kerberosIV/acl/Makefile new file mode 100644 index 00000000000..8b19ea8bd60 --- /dev/null +++ b/kerberosIV/acl/Makefile @@ -0,0 +1,11 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ + +LIB= acl +SRCS= acl_files.c +MAN= acl_check.3 +MLINKS+=acl_check.3 acl_canonicalize_principal.3 \ + acl_check.3 acl_exact_match.3 \ + acl_check.3 acl_add.3 acl_check.3 acl_delete.3 \ + acl_check.3 acl_initialize.3 + +.include diff --git a/kerberosIV/acl/acl_check.3 b/kerberosIV/acl/acl_check.3 new file mode 100644 index 00000000000..85315728302 --- /dev/null +++ b/kerberosIV/acl/acl_check.3 @@ -0,0 +1,182 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: acl_check.3,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ +.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 \-lacl \-lkrb +.PP +.ft B +#include +.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 +[.][@] +.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/kerberosIV/acl/acl_files.c b/kerberosIV/acl/acl_files.c new file mode 100644 index 00000000000..cc9dd5e313a --- /dev/null +++ b/kerberosIV/acl/acl_files.c @@ -0,0 +1,557 @@ +/* $Id: acl_files.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * Copyright (C) 1989 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/*** Routines for manipulating access control list files ***/ + +/* "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)) + +/* 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 */ +void +acl_canonicalize_principal(principal, canon) + char *principal; + char *canon; +{ + char *dot, *atsign, *end; + int len; + + dot = strchr(principal, INST_SEP); + atsign = strchr(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); + } +} + +/* 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); + } +} + +/* 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); +} + +/* 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 void +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 void +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 int +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 void +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 int +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 */ +int +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 *.*@* */ +int +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 = strchr(canon, REALM_SEP); + *strchr(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 */ +int +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) == 0 + || 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 */ +int +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/kerberosIV/acl/shlib_version b/kerberosIV/acl/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/acl/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/com_err/Makefile b/kerberosIV/com_err/Makefile new file mode 100644 index 00000000000..709fc8124fb --- /dev/null +++ b/kerberosIV/com_err/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ + +LIB= com_err +SRCS= com_err.c error_message.c et_name.c init_et.c +CFLAGS+=-I${.CURDIR} +MAN= com_err.3 + +.include diff --git a/kerberosIV/com_err/com_err.3 b/kerberosIV/com_err/com_err.3 new file mode 100644 index 00000000000..7be3a640302 --- /dev/null +++ b/kerberosIV/com_err/com_err.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 1988 Massachusetts Institute of Technology, +.\" Student Information Processing Board. All rights reserved. +.\" +.\" $Id: com_err.3,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ +.TH COM_ERR 3 "22 Nov 1988" SIPB +.SH NAME +com_err \- common error display routine +.SH SYNOPSIS +.nf + #include +.PP +void com_err (whoami, code, format, ...); + const char *whoami; + long code; + const char *format; +.PP +proc = set_com_err_hook (proc); +.fi +void (* +.I proc +) (const char *, long, const char *, va_list); +.nf +.PP +proc = reset_com_err_hook (); +.PP +void initialize_XXXX_error_table (); +.fi +.SH DESCRIPTION +.I Com_err +displays an error message on the standard error stream +.I stderr +(see +.IR stdio (3S)) +composed of the +.I whoami +string, which should specify the program name or some subportion of +a program, followed by an error message generated from the +.I code +value (derived from +.IR compile_et (1)), +and a string produced using the +.I format +string and any following arguments, in the same style as +.IR fprintf (3). + +The behavior of +.I com_err +can be modified using +.I set_com_err_hook; +this defines a procedure which is called with the arguments passed to +.I com_err, +instead of the default internal procedure which sends the formatted +text to error output. Thus the error messages from a program can all +easily be diverted to another form of diagnostic logging, such as +.IR syslog (3). +.I Reset_com_err_hook +may be used to restore the behavior of +.I com_err +to its default form. Both procedures return the previous ``hook'' +value. These ``hook'' procedures must have the declaration given for +.I proc +above in the synopsis. + +The +.I initialize_XXXX_error_table +routine is generated mechanically by +.IR compile_et (1) +from a source file containing names and associated strings. Each +table has a name of up to four characters, which is used in place of +the +.B XXXX +in the name of the routine. These routines should be called before +any of the corresponding error codes are used, so that the +.I com_err +library will recognize error codes from these tables when they are +used. + +The +.B com_err.h +header file should be included in any source file that uses routines +from the +.I com_err +library; executable files must be linked using +.I ``-lcom_err'' +in order to cause the +.I com_err +library to be included. + +.\" .IR for manual entries +.\" .PP for paragraph breaks + +.SH "SEE ALSO" +compile_et (1), syslog (3). + +Ken Raeburn, "A Common Error Description Library for UNIX". diff --git a/kerberosIV/com_err/com_err.c b/kerberosIV/com_err/com_err.c new file mode 100644 index 00000000000..415cb83d740 --- /dev/null +++ b/kerberosIV/com_err/com_err.c @@ -0,0 +1,151 @@ +/* $Id: com_err.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include + +#if __STDC__ +# undef VARARGS +# include +#else +# undef VARARGS +# define VARARGS 1 +# include +#endif + +#include "kerberosIV/com_err.h" +#include "error_table.h" + +/* + * Protect us from header version (externally visible) of com_err, so + * we can survive in a environment. I think. + */ +#if VARARGS +#define com_err com_err_external +#include "kerberosIV/com_err.h" +#undef com_err +#endif + +#ifdef NPOSIX +#undef vfprintf +#define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream) +#endif + +#if !defined(lint) +static const char rcsid[] = + "$Id: com_err.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $"; +#endif /* ! lint */ + +static void +#ifdef __STDC__ + default_com_err_proc (const char *whoami, long code, const char *fmt, va_list args) +#else + default_com_err_proc (whoami, code, fmt, args) + const char *whoami; + long code; + const char *fmt; + va_list args; +#endif +{ + if (whoami) { + fputs(whoami, stderr); + fputs(": ", stderr); + } +#ifdef SOLARIS + if (code) { + fputs(error_message(code), stderr); + fputs(" ", stderr); + } else { + vfprintf (stderr, fmt, args); + } +#else + if (code) { + fputs(error_message(code), stderr); + fputs(" ", stderr); + } + if (fmt) { + vfprintf (stderr, fmt, args); + } +#endif + putc('\n', stderr); + /* should do this only on a tty in raw mode */ + putc('\r', stderr); + fflush(stderr); +} + +typedef void (*errf) __P((const char *, long, const char *, va_list)); + +errf com_err_hook = default_com_err_proc; + +void com_err_va (whoami, code, fmt, args) + const char *whoami; + long code; + const char *fmt; + va_list args; +{ + if (! com_err_hook) + com_err_hook = default_com_err_proc; + (*com_err_hook) (whoami, code, fmt, args); +} + +#if ! VARARGS +void com_err (const char *whoami, + long code, + const char *fmt, ...) +{ +#else +void com_err (va_alist) + va_dcl +{ + const char *whoami, *fmt; + long code; +#endif + va_list pvar; + + if (!com_err_hook) + com_err_hook = default_com_err_proc; +#if VARARGS + va_start (pvar); + whoami = va_arg (pvar, const char *); + code = va_arg (pvar, long); + fmt = va_arg (pvar, const char *); +#else + va_start(pvar, fmt); +#endif + com_err_va (whoami, code, fmt, pvar); + va_end(pvar); +} + +errf set_com_err_hook (new_proc) + errf new_proc; +{ + errf x = com_err_hook; + + if (new_proc) + com_err_hook = new_proc; + else + com_err_hook = default_com_err_proc; + + return x; +} + +errf reset_com_err_hook () { + errf x = com_err_hook; + com_err_hook = default_com_err_proc; + return x; +} diff --git a/kerberosIV/com_err/error_message.c b/kerberosIV/com_err/error_message.c new file mode 100644 index 00000000000..601a4e1dfcf --- /dev/null +++ b/kerberosIV/com_err/error_message.c @@ -0,0 +1,79 @@ +/* $Id: error_message.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include "error_table.h" + +static const char rcsid[] = + "$Id: error_message.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $"; +static const char copyright[] = + "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology"; + +static char buffer[25]; + +struct et_list * _et_list = (struct et_list *) NULL; + +const char * +error_message (code) + long code; +{ + int offset; + struct et_list *et; + int table_num; + int started = 0; + char *cp; + + offset = code & ((1<next) { + if (et->table->base == table_num) { + /* This is the right table */ + if (et->table->n_msgs <= offset) + goto oops; + return(et->table->msgs[offset]); + } + } +oops: + strcpy (buffer, "Unknown code "); + if (table_num) { + strcat (buffer, error_table_name (table_num)); + strcat (buffer, " "); + } + for (cp = buffer; *cp; cp++) + ; + if (offset >= 100) { + *cp++ = '0' + offset / 100; + offset %= 100; + started++; + } + if (started || offset >= 10) { + *cp++ = '0' + offset / 10; + offset %= 10; + } + *cp++ = '0' + offset; + *cp = '\0'; + return(buffer); +} diff --git a/kerberosIV/com_err/error_table.h b/kerberosIV/com_err/error_table.h new file mode 100644 index 00000000000..a96775320ad --- /dev/null +++ b/kerberosIV/com_err/error_table.h @@ -0,0 +1,41 @@ +/* $Id: error_table.h,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#ifndef _ET_H +#define _ET_H + +struct error_table { + char const * const * msgs; + long base; + int n_msgs; +}; + +struct et_list { + struct et_list *next; + const struct error_table *table; +}; + +extern struct et_list * _et_list; + +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ + +extern const char *error_table_name(); + +#endif diff --git a/kerberosIV/com_err/et_name.c b/kerberosIV/com_err/et_name.c new file mode 100644 index 00000000000..68267d87025 --- /dev/null +++ b/kerberosIV/com_err/et_name.c @@ -0,0 +1,55 @@ +/* $Id: et_name.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include "error_table.h" + +#ifndef lint +static const char copyright[] = + "Copyright 1987,1988 by Student Information Processing Board, Massachusetts Institute of Technology"; +static const char rcsid_et_name_c[] = + "$Id: et_name.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $"; +#endif + +static const char char_set[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +static char buf[6]; + +const char * +error_table_name(num) + int num; +{ + int ch; + int i; + char *p; + + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ + 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 = 4; i >= 0; i--) { + ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); + if (ch != 0) + *p++ = char_set[ch-1]; + } + *p = '\0'; + return(buf); +} diff --git a/kerberosIV/com_err/init_et.c b/kerberosIV/com_err/init_et.c new file mode 100644 index 00000000000..b2b8602c457 --- /dev/null +++ b/kerberosIV/com_err/init_et.c @@ -0,0 +1,63 @@ +/* $Id: init_et.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include +#include "error_table.h" + +#ifndef __STDC__ +#define const +#endif + +#ifndef lint +static const char rcsid_init_et_c[] = + "$Id: init_et.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $"; +#endif + +struct foobar { + struct et_list etl; + struct error_table et; +}; + +extern struct et_list * _et_list; + +int +init_error_table(msgs, base, count) + const char * const * msgs; + int base; + int count; +{ + struct foobar * new_et; + + if (!base || !count || !msgs) + return 0; + + new_et = (struct foobar *) malloc(sizeof(struct foobar)); + if (!new_et) + return errno; /* oops */ + new_et->etl.table = &new_et->et; + new_et->et.msgs = msgs; + new_et->et.base = base; + new_et->et.n_msgs= count; + + new_et->etl.next = _et_list; + _et_list = &new_et->etl; + return 0; +} diff --git a/kerberosIV/compile_et/Makefile b/kerberosIV/compile_et/Makefile new file mode 100644 index 00000000000..d3d3abcaa1b --- /dev/null +++ b/kerberosIV/compile_et/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ + +PROG= compile_et +SRCS= compile_et.c error_table.y #et_lex.lex.l +CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../com_err +DPADD= ${LIBL} +LDADD= -ll +CLEANFILES=error_table.c y.tab.h et_lex.lex.c + +beforedepend: et_lex.lex.c +error_table.o: et_lex.lex.c + +install: + +.include diff --git a/kerberosIV/compile_et/compile_et.1 b/kerberosIV/compile_et/compile_et.1 new file mode 100644 index 00000000000..7606d901281 --- /dev/null +++ b/kerberosIV/compile_et/compile_et.1 @@ -0,0 +1,79 @@ +.\" Copyright (c) 1988 Massachusetts Institute of Technology, +.\" Student Information Processing Board. All rights reserved. +.\" +.\" $Id: compile_et.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ +.\" +.TH COMPILE_ET 1 "22 Nov 1988" SIPB +.SH NAME +compile_et \- error table compiler +.SH SYNOPSIS +.B compile_et +file +.SH DESCRIPTION +.B Compile_et +converts a table listing error-code names and associated messages into +a C source file suitable for use with the +.IR com_err (3) +library. + +The source file name must end with a suffix of ``.et''; the file +consists of a declaration supplying the name (up to four characters +long) of the error-code table: + +.B error_table +.I name + +followed by up to 256 entries of the form: + +.B error_code +.I name, +" +.I string +" + +and a final + +.B end + +to indicate the end of the table. + +The name of the table is used to construct the name of a subroutine +.I initialize_XXXX_error_table +which must be called in order for the +.I com_err +library to recognize the error table. + +The various error codes defined are assigned sequentially increasing +numbers (starting with a large number computed as a hash function of +the name of the table); thus for compatibility it is suggested that +new codes be added only to the end of an existing table, and that no +codes be removed from tables. + +The names defined in the table are placed into a C header file with +preprocessor directives defining them as integer constants of up to +32 bits in magnitude. + +A C source file is also generated which should be compiled and linked +with the object files which reference these error codes; it contains +the text of the messages and the initialization subroutine. Both C +files have names derived from that of the original source file, with +the ``.et'' suffix replaced by ``.c'' and ``.h''. + +A ``#'' in the source file is treated as a comment character, and all +remaining text to the end of the source line will be ignored. + +.SH BUGS + +Since +.B compile_et +uses a very simple parser based on +.IR yacc (1), +its error recovery leaves much to be desired. + +.\" .IR for manual entries +.\" .PP for paragraph breaks + +.SH "SEE ALSO" +com_err (3). + +Ken Raeburn, "A Common Error Description Library for UNIX". diff --git a/kerberosIV/compile_et/compile_et.c b/kerberosIV/compile_et/compile_et.c new file mode 100644 index 00000000000..4bd96762ebc --- /dev/null +++ b/kerberosIV/compile_et/compile_et.c @@ -0,0 +1,289 @@ +/* $id$ */ + +/* + * Copyright 1986, 1987, 1988 + * by MIT Student Information Processing Board. + * + * For copyright info, see "mit-sipb-copyright.h". + */ + +#include +#include +#include +#include +#include +#include "compiler.h" + +#ifndef __STDC__ +#define const +#endif + +#ifndef lint +static const char copyright[] = + "Copyright 1987,1988 by MIT Student Information Processing Board"; + +static const char rcsid_compile_et_c[] = + "$Id: compile_et.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $"; +#endif + +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 unsigned lineno; + +char * xmalloc (size) unsigned int size; { + char * p = malloc (size); + if (!p) { + perror (whoami); + exit (1); + } + return p; +} + +static int check_arg (str_list, arg) char const *const *str_list, *arg; { + while (*str_list) + if (!strcmp(arg, *str_list++)) + return 1; + return 0; +} + +static const char *const debug_args[] = { + "d", + "debug", + 0, +}; + +static const char *const lang_args[] = { + "lang", + "language", + 0, +}; + +static const char *const language_names[] = { + "C", + "K&R C", + "C++", + 0, +}; + +static const char * const c_src_prolog[] = { + "static const char * const text[] = {\n", + 0, +}; + +static const char * const krc_src_prolog[] = { + "#ifdef __STDC__\n", + "#define NOARGS void\n", + "#else\n", + "#define NOARGS\n", + "#define const\n", + "#endif\n\n", + "static const char * const text[] = {\n", + 0, +}; + +static const char *const struct_def[] = { + "struct error_table {\n", + " char const * const * msgs;\n", + " long base;\n", + " int n_msgs;\n", + "};\n", + "struct et_list {\n", + " struct et_list *next;\n", + " const struct error_table * table;\n", + "};\n", + "extern struct et_list *_et_list;\n", + "\n", 0, +}; + +static const char warning[] = + "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n"; + +/* pathnames */ +char c_file[MAXPATHLEN]; /* output file */ +char h_file[MAXPATHLEN]; /* output */ + +static void usage () { + fprintf (stderr, "%s: usage: %s ERROR_TABLE\n", + whoami, whoami); + exit (1); +} + +static void dup_err (type, one, two) char const *type, *one, *two; { + fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n", + whoami, type, one, two); + usage (); +} + +int main (argc, argv) int argc; char **argv; { + char *p, *ename; + int len; + char const * const *cpp; + int got_language = 0; + + /* argument parsing */ + debug = 0; + filename = 0; + whoami = argv[0]; + p = strrchr (whoami, '/'); + if (p) + whoami = p+1; + while (argv++, --argc) { + char *arg = *argv; + if (arg[0] != '-') { + if (filename) + dup_err ("filenames", filename, arg); + filename = arg; + } + else { + arg++; + if (check_arg (debug_args, arg)) + debug++; + else if (check_arg (lang_args, arg)) { + got_language++; + arg = *++argv, argc--; + if (!arg) + usage (); + if (language) + dup_err ("languanges", language_names[(int)language], arg); +#define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v + check_lang ("c", lang_C); + check_lang ("ansi_c", lang_C); + check_lang ("ansi-c", lang_C); + check_lang ("krc", lang_KRC); + check_lang ("kr_c", lang_KRC); + check_lang ("kr-c", lang_KRC); + check_lang ("k&r-c", lang_KRC); + check_lang ("k&r_c", lang_KRC); + check_lang ("c++", lang_CPP); + check_lang ("cplusplus", lang_CPP); + check_lang ("c-plus-plus", lang_CPP); +#undef check_lang + else { + fprintf (stderr, "%s: unknown language name `%s'\n", + whoami, arg); + fprintf (stderr, "\tpick one of: C K&R-C\n"); + exit (1); + } + } + else { + fprintf (stderr, "%s: unknown control argument -`%s'\n", + whoami, arg); + usage (); + } + } + } + if (!filename) + usage (); + if (!got_language) + language = lang_KRC; + else if (language == lang_CPP) { + fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n", + whoami); + exit (1); + } + + p = xmalloc (strlen (filename) + 5); + strcpy (p, filename); + filename = p; + p = strrchr(filename, '/'); + if (p == (char *)NULL) + p = filename; + else + p++; + ename = p; + len = strlen (ename); + p += len - 3; + if (strcmp (p, ".et")) + p += 3; + *p++ = '.'; + /* now p points to where "et" suffix should start */ + /* generate new filenames */ + strcpy (p, "c"); + strcpy (c_file, ename); + *p = 'h'; + strcpy (h_file, ename); + strcpy (p, "et"); + + yyin = fopen(filename, "r"); + if (!yyin) { + perror(filename); + exit(1); + } + + hfile = fopen(h_file, "w"); + if (hfile == (FILE *)NULL) { + perror(h_file); + exit(1); + } + fprintf (hfile, warning, h_file); + + cfile = fopen(c_file, "w"); + if (cfile == (FILE *)NULL) { + perror(c_file); + exit(1); + } + fprintf (cfile, warning, c_file); + + /* prologue */ + if (language == lang_C) + cpp = c_src_prolog; + else if (language == lang_KRC) + cpp = krc_src_prolog; + else + abort (); + while (*cpp) + fputs (*cpp++, cfile); + + /* parse it */ + yyparse(); + fclose(yyin); /* bye bye input file */ + + fputs (" 0\n};\n\n", cfile); + for (cpp = struct_def; *cpp; cpp++) + fputs (*cpp, cfile); + fprintf(cfile, + "static const struct error_table et = { text, %ldL, %d };\n\n", + table_number, current); + fputs("static struct et_list link = { 0, 0 };\n\n", + cfile); + fprintf(cfile, "void initialize_%s_error_table (%s) {\n", + table_name, (language == lang_C) ? "void" : "NOARGS"); + fputs(" if (!link.table) {\n", cfile); + fputs(" link.next = _et_list;\n", cfile); + fputs(" link.table = &et;\n", cfile); + fputs(" _et_list = &link;\n", cfile); + fputs(" }\n", cfile); + fputs("}\n", cfile); + fclose(cfile); + + fprintf (hfile, "extern void initialize_%s_error_table ();\n", + table_name); + fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", + table_name, table_number); + /* compatibility... */ + fprintf (hfile, "\n/* for compatibility with older versions... */\n"); + fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n", + table_name, table_name); + fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name, + table_name); + fclose(hfile); /* bye bye include file */ + + return 0; +} + +int yyerror(s) char *s; { + fputs(s, stderr); + fprintf(stderr, "\nLine number %d; last token was '%s'\n", + lineno, current_token); +} diff --git a/kerberosIV/compile_et/compiler.h b/kerberosIV/compile_et/compiler.h new file mode 100644 index 00000000000..0f9ac1bda04 --- /dev/null +++ b/kerberosIV/compile_et/compiler.h @@ -0,0 +1,22 @@ +/* $Id: compiler.h,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/* + * definitions common to the source files of the error table compiler + */ + +#ifndef __STDC__ +/* loser */ +#undef const +#define const +#endif + +enum lang { + lang_C, /* ANSI C (default) */ + lang_KRC, /* C: ANSI + K&R */ + lang_CPP /* C++ */ +}; + +int debug; /* dump debugging info? */ +char *filename; /* error table source */ +enum lang language; +const char *whoami; diff --git a/kerberosIV/compile_et/error_table.y b/kerberosIV/compile_et/error_table.y new file mode 100644 index 00000000000..11ddd22c169 --- /dev/null +++ b/kerberosIV/compile_et/error_table.y @@ -0,0 +1,260 @@ +%{ +/* $Id: error_table.y,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +char *str_concat(), *ds(), *quote(); +char *current_token = (char *)NULL; +extern char *table_name; +%} +%union { + char *dynstr; +} + +%token ERROR_TABLE ERROR_CODE_ENTRY END +%token STRING QUOTED_STRING +%type 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 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include +#include +#include +#include "error_table.h" + +#ifndef lint +static char const rcsid_error_table_y[] = + "$Id: error_table.y,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $"; +#endif + +#include "et_lex.lex.c" + +extern FILE *hfile, *cfile; + +static long gensym_n = 0; +char * +gensym(x) + char const *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 = (char *)malloc(32 * sizeof(char)); + gensym_n++; + sprintf(symbol, "et%ld", gensym_n); + return(symbol); +} + +char * +ds(string) + char const *string; +{ + char *rv; + rv = (char *)malloc(strlen(string)+1); + strcpy(rv, string); + return(rv); +} + +char * +quote(string) + char const *string; +{ + char *rv; + rv = (char *)malloc(strlen(string)+3); + strcpy(rv, "\""); + strcat(rv, string); + strcat(rv, "\""); + return(rv); +} + +long table_number; +int current = 0; +char **error_codes = (char **)NULL; + +add_ec(name, description) + char const *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 const *name, *val, *description; +{ + const 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 (%ldL)\n", + error_codes[i], 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 + */ + +static const char char_set[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +int char_to_num(c) + char c; +{ + const char *where; + int diff; + + where = strchr (char_set, c); + if (where) { + diff = where - char_set + 1; + assert (diff < (1 << ERRCODE_RANGE)); + return diff; + } + else if (isprint (c)) + fprintf (stderr, + "Illegal character `%c' in error table name\n", + c); + else + fprintf (stderr, + "Illegal character %03o in error table name\n", + c); + exit (1); +} + +set_table_num(string) + char *string; +{ + if (char_to_num (string[0]) > char_to_num ('z')) { + fprintf (stderr, "%s%s%s%s", + "First character of error table name must be ", + "a letter; name ``", + string, "'' rejected\n"); + exit (1); + } + 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; +} + diff --git a/kerberosIV/compile_et/et_lex.lex.l b/kerberosIV/compile_et/et_lex.lex.l new file mode 100644 index 00000000000..cedeff500c3 --- /dev/null +++ b/kerberosIV/compile_et/et_lex.lex.l @@ -0,0 +1,31 @@ +%{ + unsigned lineno = 1; +%} + +PC [^\"] +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 ++lineno; + +\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1); + if (p=strrchr(yylval.dynstr, '"')) *p='\0'; + return QUOTED_STRING; + } + +{AN}* { yylval.dynstr = ds(yytext); return STRING; } + +#.*\n ++lineno; + +. { return (*yytext); } +%% +#ifndef lint +static char rcsid_et_lex_lex_l[] = "$Id: et_lex.lex.l,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $"; +#endif diff --git a/kerberosIV/des/3cbc_enc.c b/kerberosIV/des/3cbc_enc.c new file mode 100644 index 00000000000..e3704562b5f --- /dev/null +++ b/kerberosIV/des/3cbc_enc.c @@ -0,0 +1,52 @@ +/* $Id: 3cbc_enc.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +static void +xp(des_cblock *arg) +{ + unsigned char *a = (unsigned char *) arg; + int i; + for(i=0; i<8; i++) printf("%02X",a[i]);printf("\n"); +} + +int des_3cbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *ks1, struct des_ks_struct *ks2, des_cblock (*iv1), des_cblock (*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)) + memcpy(niv1,output[off],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)) + memcpy(niv2,output[off],sizeof(des_cblock)); + memcpy(*iv1,niv1,sizeof(des_cblock)); + } + else + { + if (length >= sizeof(des_cblock)) + memcpy(niv1,input[off],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)) + memcpy(niv2,output[off],sizeof(des_cblock)); + des_cbc_encrypt(output,output,length,ks1,iv2, encrypt); + } + memcpy(iv1,niv1,sizeof(des_cblock)); + memcpy(iv2,niv2,sizeof(des_cblock)); + xp(iv1); + xp(iv1); + xp(iv2); + xp(output); + return(0); +} diff --git a/kerberosIV/des/3ecb_enc.c b/kerberosIV/des/3ecb_enc.c new file mode 100644 index 00000000000..f3b4fa33571 --- /dev/null +++ b/kerberosIV/des/3ecb_enc.c @@ -0,0 +1,27 @@ +/* $Id: 3ecb_enc.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +int des_3ecb_encrypt(des_cblock (*input), des_cblock (*output), struct des_ks_struct *ks1, struct des_ks_struct *ks2, int encrypt) +{ + register u_int32_t l0,l1; + register unsigned char *in,*out; + u_int32_t 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/kerberosIV/des/ARTISTIC b/kerberosIV/des/ARTISTIC new file mode 100644 index 00000000000..eb6707109df --- /dev/null +++ b/kerberosIV/des/ARTISTIC @@ -0,0 +1,103 @@ + 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/kerberosIV/des/CHANGES b/kerberosIV/des/CHANGES new file mode 100644 index 00000000000..4f441fae2d4 --- /dev/null +++ b/kerberosIV/des/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/kerberosIV/des/COPYING b/kerberosIV/des/COPYING new file mode 100644 index 00000000000..9b1a9329f15 --- /dev/null +++ b/kerberosIV/des/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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/kerberosIV/des/Makefile b/kerberosIV/des/Makefile new file mode 100644 index 00000000000..784220f446f --- /dev/null +++ b/kerberosIV/des/Makefile @@ -0,0 +1,16 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ + +LIB= des +SRCS= 3cbc_enc.c 3ecb_enc.c cbc_cksm.c cbc_enc.c cfb_enc.c \ + ecb_enc.c enc_read.c enc_writ.c key_par.c ofb_enc.c \ + pcbc_enc.c qud_cksm.c random_key.c read_pwd.c rnd_keys.c \ + set_key.c str2key.c +CFLAGS+=-I${.CURDIR} +MAN= des_crypt.3 +MLINKS+=des_crypt.3 des_read_password.3 des_crypt.3 des_string_to_key.3 \ + des_crypt.3 des_random_key.3 des_crypt.3 des_set_key.3 \ + des_crypt.3 des_ecb_encrypt.3 des_crypt.3 des_cbc_encrypt.3 \ + des_crypt.3 des_pcbc_encrypt.3 des_crypt.3 des_cbc_cksum.3 \ + des_crypt.3 des_quad_cksum.3 + +.include diff --git a/kerberosIV/des/README b/kerberosIV/des/README new file mode 100644 index 00000000000..ee1fa0c0a16 --- /dev/null +++ b/kerberosIV/des/README @@ -0,0 +1,55 @@ + 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/kerberosIV/des/VERSION b/kerberosIV/des/VERSION new file mode 100644 index 00000000000..21e3b8dbadb --- /dev/null +++ b/kerberosIV/des/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 + 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 , 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/kerberosIV/des/cbc_cksm.c b/kerberosIV/des/cbc_cksm.c new file mode 100644 index 00000000000..262111b6728 --- /dev/null +++ b/kerberosIV/des/cbc_cksm.c @@ -0,0 +1,46 @@ +/* $Id: cbc_cksm.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +u_int32_t des_cbc_cksum(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec)) +{ + register u_int32_t tout0,tout1,tin0,tin1; + register long l=length; + u_int32_t 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(tin,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/kerberosIV/des/cbc_enc.c b/kerberosIV/des/cbc_enc.c new file mode 100644 index 00000000000..cf82ca6b774 --- /dev/null +++ b/kerberosIV/des/cbc_enc.c @@ -0,0 +1,73 @@ +/* $Id: cbc_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +int des_cbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt) +{ + register u_int32_t tin0,tin1; + register u_int32_t tout0,tout1,xor0,xor1; + register unsigned char *in,*out; + register long l=length; + u_int32_t 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(tin,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(tin,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/kerberosIV/des/cfb_enc.c b/kerberosIV/des/cfb_enc.c new file mode 100644 index 00000000000..c5f3364337b --- /dev/null +++ b/kerberosIV/des/cfb_enc.c @@ -0,0 +1,100 @@ +/* $Id: cfb_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#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(unsigned char *in, unsigned char *out, int numbits, long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt) +{ + register u_int32_t d0,d1,v0,v1,n=(numbits+7)/8; + register u_int32_t mask0,mask1; + register long l=length; + register int num=numbits; + u_int32_t 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< 0) + { + ti[0]=v0; + ti[1]=v1; + des_encrypt(ti,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(ti,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/kerberosIV/des/des_crypt.3 b/kerberosIV/des/des_crypt.3 new file mode 100644 index 00000000000..311690d7aeb --- /dev/null +++ b/kerberosIV/des/des_crypt.3 @@ -0,0 +1,379 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: des_crypt.3,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ +.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 +.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/kerberosIV/des/des_locl.h b/kerberosIV/des/des_locl.h new file mode 100644 index 00000000000..4a7f472096e --- /dev/null +++ b/kerberosIV/des/des_locl.h @@ -0,0 +1,174 @@ +/* $Id: des_locl.h,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ + +#ifndef __des_locl_h +#define __des_locl_h + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "kerberosIV/des.h" + +#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 =((u_int32_t)(*((c)++))) , \ + l|=((u_int32_t)(*((c)++)))<< 8, \ + l|=((u_int32_t)(*((c)++)))<<16, \ + l|=((u_int32_t)(*((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|=((u_int32_t)(*(--(c))))<<24; \ + case 7: l2|=((u_int32_t)(*(--(c))))<<16; \ + case 6: l2|=((u_int32_t)(*(--(c))))<< 8; \ + case 5: l2|=((u_int32_t)(*(--(c)))); \ + case 4: l1|=((u_int32_t)(*(--(c))))<<24; \ + case 3: l1|=((u_int32_t)(*(--(c))))<<16; \ + case 2: l1|=((u_int32_t)(*(--(c))))<< 8; \ + case 1: l1|=((u_int32_t)(*(--(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 =((u_int32_t)(*((c)++)))<<24, \ + l|=((u_int32_t)(*((c)++)))<<16, \ + l|=((u_int32_t)(*((c)++)))<< 8, \ + l|=((u_int32_t)(*((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 + * 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^= \ + *(u_int32_t *)(des_SP+0x0100+((t )&0xfc))+ \ + *(u_int32_t *)(des_SP+0x0300+((t>> 8)&0xfc))+ \ + *(u_int32_t *)(des_SP+0x0500+((t>>16)&0xfc))+ \ + *(u_int32_t *)(des_SP+0x0700+((t>>24)&0xfc))+ \ + *(u_int32_t *)(des_SP+ ((u )&0xfc))+ \ + *(u_int32_t *)(des_SP+0x0200+((u>> 8)&0xfc))+ \ + *(u_int32_t *)(des_SP+0x0400+((u>>16)&0xfc))+ \ + *(u_int32_t *)(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<>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + + +#endif /* __des_locl_h */ diff --git a/kerberosIV/des/ecb_enc.c b/kerberosIV/des/ecb_enc.c new file mode 100644 index 00000000000..87af76b203c --- /dev/null +++ b/kerberosIV/des/ecb_enc.c @@ -0,0 +1,111 @@ +/* $Id: ecb_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" +#include "spr.h" + +int des_ecb_encrypt(des_cblock (*input), des_cblock (*output), struct des_ks_struct *ks, int encrypt) +{ + register u_int32_t l0,l1; + register unsigned char *in,*out; + u_int32_t 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(u_int32_t *input, u_int32_t *output, struct des_ks_struct *ks, int encrypt) +{ + register u_int32_t l,r,t,u; +#ifdef ALT_ECB + register unsigned char *des_SP=(unsigned char *)des_SPtrans; +#endif +#ifdef MSDOS + union fudge { + u_int32_t l; + unsigned short s[2]; + unsigned char c[4]; + } U,T; +#endif + register int i; + register u_int32_t *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=(u_int32_t *)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/kerberosIV/des/enc_read.c b/kerberosIV/des/enc_read.c new file mode 100644 index 00000000000..233e078f973 --- /dev/null +++ b/kerberosIV/des/enc_read.c @@ -0,0 +1,156 @@ +/* $Id: enc_read.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ + +#include "des_locl.h" +#include +#include + +/* 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(int fd, char *buf, int len, struct des_ks_struct *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 */ + memcpy(buf,&(unnet[unnet_start]),unnet_left); + /* eay 26/08/92 I had the next 2 lines + * reversed :-( */ + i=unnet_left; + unnet_start=unnet_left=0; + } + else + { + memcpy(buf,&(unnet[unnet_start]),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) + des_pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet, + num,sched,iv,DES_DECRYPT); + else + des_cbc_encrypt((des_cblock *)net,(des_cblock *)unnet, + num,sched,iv,DES_DECRYPT); + memcpy(buf,unnet,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) + des_pcbc_encrypt((des_cblock *)net, + (des_cblock *)tmpbuf, + num,sched,iv,DES_DECRYPT); + else + des_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 :-( */ + memcpy(buf,tmpbuf,num); + } + else if (num >= 8) + { + if (des_rw_mode & DES_PCBC_MODE) + des_pcbc_encrypt((des_cblock *)net, + (des_cblock *)buf,num,sched,iv, + DES_DECRYPT); + else + des_cbc_encrypt((des_cblock *)net, + (des_cblock *)buf,num,sched,iv, + DES_DECRYPT); + } + else + { + if (des_rw_mode & DES_PCBC_MODE) + des_pcbc_encrypt((des_cblock *)net, + (des_cblock *)buf,8,sched,iv, + DES_DECRYPT); + else + des_cbc_encrypt((des_cblock *)net, + (des_cblock *)buf,8,sched,iv, + DES_DECRYPT); +#ifdef LEFT_JUSTIFIED + memcpy(buf, buf, num); +#else + memcpy(buf, buf+(8-num), num); +#endif + } + } + return(num); +} + diff --git a/kerberosIV/des/enc_writ.c b/kerberosIV/des/enc_writ.c new file mode 100644 index 00000000000..a547710efa1 --- /dev/null +++ b/kerberosIV/des/enc_writ.c @@ -0,0 +1,95 @@ +/* $Id: enc_writ.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ + +#include "des_locl.h" +#include +#include + +int des_enc_write(int fd, char *buf, int len, struct des_ks_struct *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; + srand(time(NULL)); + } + + /* lets recurse if we want to send the data in small chunks */ + if (len > MAXWRITE) + { + j=0; + for (i=0; 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) + { +#ifdef LEFT_JUSTIFIED + p=shortbuf; + memcpy(shortbuf,buf,len); + for (i=len; i<8; i++) + shortbuf[i]=rand(); + rnum=8; +#else + p=shortbuf; + for (i=0; i<8-len; i++) + shortbuf[i]=rand(); + memcpy(shortbuf + 8 - len, buf, len); + rnum=8; +#endif + } + else + { + p=buf; + rnum=((len+7)/8*8); /* round up to nearest eight */ + } + + if (des_rw_mode & DES_PCBC_MODE) + des_pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]), + (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); + else + des_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 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< 0) + { + des_encrypt(ti,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/kerberosIV/des/pcbc_enc.c b/kerberosIV/des/pcbc_enc.c new file mode 100644 index 00000000000..3cc97a60130 --- /dev/null +++ b/kerberosIV/des/pcbc_enc.c @@ -0,0 +1,68 @@ +/* $Id: pcbc_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +int des_pcbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt) +{ + register u_int32_t sin0,sin1,xor0,xor1,tout0,tout1; + u_int32_t 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(tin,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(tin,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/kerberosIV/des/podd.h b/kerberosIV/des/podd.h new file mode 100644 index 00000000000..2e959b86af0 --- /dev/null +++ b/kerberosIV/des/podd.h @@ -0,0 +1,20 @@ +/* $Id: podd.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +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/kerberosIV/des/qud_cksm.c b/kerberosIV/des/qud_cksm.c new file mode 100644 index 00000000000..7ce5c351cb3 --- /dev/null +++ b/kerberosIV/des/qud_cksm.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1993 Eric Young - see README for more details */ +/* 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. + * + * $Id: qud_cksm.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ + */ +#include "des_locl.h" + +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ +#define B0(a) (((u_int32_t)(a))) +#define B1(a) (((u_int32_t)(a))<<8) +#define B2(a) (((u_int32_t)(a))<<16) +#define B3(a) (((u_int32_t)(a))<<24) + +/* used to scramble things a bit */ +/* Got the value MIT uses via brute force :-) 2/10/90 eay */ +#define NOISE ((u_int32_t)83653421) + +u_int32_t des_quad_cksum(des_cblock (*input), des_cblock (*output), long int length, int out_count, des_cblock (*seed)) +{ + u_int32_t 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 0) + { + if (l > 1) + { + t0= (u_int32_t)(*(cp++)); + t0|=(u_int32_t)B1(*(cp++)); + l--; + } + else + t0= (u_int32_t)(*(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 u_int32_t 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/kerberosIV/des/random_key.c b/kerberosIV/des/random_key.c new file mode 100644 index 00000000000..d228741cf12 --- /dev/null +++ b/kerberosIV/des/random_key.c @@ -0,0 +1,34 @@ +/* $Id: random_key.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +/* Copyright (C) 1992 Eric Young - see COPYING for more details */ +#include "des_locl.h" + +void des_random_key(ret) +des_cblock ret; + { + des_key_schedule ks; + static u_int32_t c=0; + static pid_t pid=0; + static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + des_cblock key; + +#ifdef MSDOS + pid=1; +#else + if (!pid) pid=getpid(); +#endif + ((u_int32_t *)key)[0]=(u_int32_t)time(NULL); + ((u_int32_t *)key)[1]=(u_int32_t)((pid)|((c++)<<16)); + + des_set_odd_parity((des_cblock *)data); + des_set_key((des_cblock *)data,ks); + des_cbc_cksum((des_cblock *)key,(des_cblock *)key, + (int32_t)sizeof(key),ks,(des_cblock *)data); + des_set_odd_parity((des_cblock *)key); + des_cbc_cksum((des_cblock *)key,(des_cblock *)key, + (int32_t)sizeof(key),ks,(des_cblock *)data); + + bcopy(key,ret,sizeof(key)); + bzero(key,sizeof(key)); + bzero(ks,sizeof(ks)); + } diff --git a/kerberosIV/des/read_pwd.c b/kerberosIV/des/read_pwd.c new file mode 100644 index 00000000000..fd482ce74f6 --- /dev/null +++ b/kerberosIV/des/read_pwd.c @@ -0,0 +1,285 @@ +/* $Id: read_pwd.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +/* 06-Apr-92 Luke Brennan Support for VMS */ +#include "des_locl.h" +#include +#include +#include + +/* Ick! */ +#if defined(__svr4__) || defined(__sgi) || defined(linux) +#define TERMIO +#endif + +#ifndef VMS +#ifndef MSDOS +#ifdef TERMIO +#include +#define sgttyb termio +#define sg_flags c_lflag +#define TIOCGETP TCGETA +#define TIOCSETP TCSETA +#else /* !TERMIO */ +#include +#endif +#include +#else /* MSDOS */ +#define fgets(a,b,c) noecho_fgets(a,b,c) +#endif +#else /* VMS */ +#include +#include +#include +#include +struct IOSB { + short iosb$w_value; + short iosb$w_count; + long iosb$l_info; + }; +#endif +#ifndef NSIG +#define NSIG 32 +#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); + } + +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); + } + +static void read_till_nl(in) +FILE *in; + { +#define SIZE 4 + char buf[SIZE+1]; + + do { + fgets(buf,SIZE,in); + } while (strchr(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; + + while (!ok) + { + fputs(prompt,stderr); + fflush(stderr); + + buf[0]='\0'; + fgets(buf,size,tty); + if (feof(tty)) goto error; + if ((p=(char *)strchr(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 *)strchr(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 + +#include + +#include +#include +#include + +/* + * Create a sequence of random 64 bit blocks. + * The sequence is indexed with a long long and + * based on an initial des key used as a seed. + */ +static des_key_schedule sequence_seed; +static u_int32_t sequence_index[2]; + +/* + * In case the generator does not get inited use this for backup. + */ +static int initialized; +static des_cblock default_seed = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static void +do_initialize() +{ + des_set_odd_parity(&default_seed); + des_set_random_generator_seed(&default_seed); +} + +#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0) + +#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0) + +#define des_set_sequence_number(ll) \ +do { \ + memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); \ + } while (0) + +#define des_generate_random_block(ret) \ +do { \ + des_ecb_encrypt((des_cblock *) sequence_index, (ret), sequence_seed, DES_ENCRYPT); \ + incr_long_long(sequence_index); \ + } while (0) + +void +des_set_random_generator_seed(des_cblock *seed) +{ + des_key_sched(seed, sequence_seed); + zero_long_long(sequence_index); + initialized = 1; +} + +/* + * Generate a sequence of random des keys + * using the random block sequence, fixup + * parity and skip weak keys. + */ +int +des_new_random_key(des_cblock *key) +{ + if (!initialized) + do_initialize(); + + try_again: + des_generate_random_block(key); + /* random key must have odd parity and not be weak */ + des_set_odd_parity(key); + if (des_is_weak_key(key)) + goto try_again; + return(0); +} + +/* + * des_init_random_number_generator: + * + * This routine takes a secret key possibly shared by a number + * of servers and uses it to generate a random number stream that is + * not shared by any of the other servers. It does this by using the current + * process id, host id, and the current time to the nearest second. The + * resulting stream seed is not useful information for cracking the secret + * key. Moreover, this routine keeps no copy of the secret key. + * + */ +void +des_init_random_number_generator(des_cblock *seed) +{ + struct timeval now; + static long uniq[2]; + des_cblock new_key; + long gethostid(void); + + gettimeofday(&now, (struct timezone *)0); + if (!uniq[0]) + { + struct hostent *hent; + char hostname[100]; + gethostname(hostname, sizeof(hostname)); + hent = gethostbyname(hostname); + if (hent != NULL) + bcopy(hent->h_addr_list[0], &uniq[0], sizeof(uniq[0])); + else + uniq[0] = gethostid(); +#ifdef MSDOS + uniq[1] = 1; +#else + uniq[1] = getpid(); +#endif + } + + /* Pick a unique random key from the shared sequence. */ + des_set_random_generator_seed(seed); + des_set_sequence_number((unsigned char *)uniq); + des_new_random_key(&new_key); + + /* Select a new nonshared sequence, */ + des_set_random_generator_seed(&new_key); + + /* and use the current time to pick a key for the new sequence. */ + des_set_sequence_number((unsigned char *)&now); + des_new_random_key(&new_key); + des_set_random_generator_seed(&new_key); +} diff --git a/kerberosIV/des/set_key.c b/kerberosIV/des/set_key.c new file mode 100644 index 00000000000..e7a0186d013 --- /dev/null +++ b/kerberosIV/des/set_key.c @@ -0,0 +1,179 @@ +/* $Id: set_key.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* 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 + */ +#include "des_locl.h" +#include "podd.h" +#include "sk.h" + +static int check_parity(des_cblock (*key)); + +int des_check_key=0; + +void des_set_odd_parity(des_cblock (*key)) +{ + int i; + + for (i=0; i>(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(des_cblock (*key), struct des_ks_struct *schedule) +{ + register u_int32_t c,d,t,s; + register unsigned char *in; + register u_int32_t *k; + register int i; + + if (des_check_key) + { + if (!check_parity(key)) + return(-1); + + if (des_is_weak_key(key)) + return(-2); + } + + k=(u_int32_t *)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>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(des_cblock *key, des_key_schedule schedule) +{ + return(des_set_key(key, (struct des_ks_struct *)schedule)); +} diff --git a/kerberosIV/des/shlib_version b/kerberosIV/des/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/des/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/des/sk.h b/kerberosIV/des/sk.h new file mode 100644 index 00000000000..31bec909f76 --- /dev/null +++ b/kerberosIV/des/sk.h @@ -0,0 +1,141 @@ +/* $Id: sk.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +static u_int32_t 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/kerberosIV/des/spr.h b/kerberosIV/des/spr.h new file mode 100644 index 00000000000..aea087b9e9a --- /dev/null +++ b/kerberosIV/des/spr.h @@ -0,0 +1,147 @@ +/* $Id: spr.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +static u_int32_t 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/kerberosIV/des/str2key.c b/kerberosIV/des/str2key.c new file mode 100644 index 00000000000..115e26b0fc5 --- /dev/null +++ b/kerberosIV/des/str2key.c @@ -0,0 +1,113 @@ +/* $Id: str2key.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#include "des_locl.h" + +extern int des_check_key; + +int des_string_to_key(char *str, des_cblock (*key)) +{ + des_key_schedule ks; + int i,length; + register unsigned char j; + + memset(key,0,8); + length=strlen(str); +#ifdef OLD_STR_TO_KEY + for (i=0; i>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); + memset(ks,0,sizeof(ks)); + des_set_odd_parity((des_cblock *)key); + return(0); +} + +int des_string_to_2keys(char *str, des_cblock (*key1), des_cblock (*key2)) +{ + des_key_schedule ks; + int i,length; + register unsigned char j; + + memset(key1,0,8); + memset(key2,0,8); + length=strlen(str); +#ifdef OLD_STR_TO_KEY + if (length <= 8) + { + for (i=0; i>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) memcpy(key2,key1,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; + memset(ks,0,sizeof(ks)); + des_set_odd_parity(key1); + des_set_odd_parity(key2); + return(0); +} diff --git a/kerberosIV/ext_srvtab/Makefile b/kerberosIV/ext_srvtab/Makefile new file mode 100644 index 00000000000..3b92c5fda00 --- /dev/null +++ b/kerberosIV/ext_srvtab/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ + +PROG= ext_srvtab +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= ext_srvtab.8 + +.include diff --git a/kerberosIV/ext_srvtab/ext_srvtab.8 b/kerberosIV/ext_srvtab/ext_srvtab.8 new file mode 100644 index 00000000000..1491e5e308b --- /dev/null +++ b/kerberosIV/ext_srvtab/ext_srvtab.8 @@ -0,0 +1,62 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: ext_srvtab.8,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ +.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/kerberosIV/ext_srvtab/ext_srvtab.c b/kerberosIV/ext_srvtab/ext_srvtab.c new file mode 100644 index 00000000000..13a84125941 --- /dev/null +++ b/kerberosIV/ext_srvtab/ext_srvtab.c @@ -0,0 +1,158 @@ +/* $Id: ext_srvtab.c,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include + +static des_cblock master_key; +static des_cblock session_key; +static des_key_schedule master_key_schedule; +char progname[] = "ext_srvtab"; +static char realm[REALM_SZ]; + +static void +usage(void) +{ + fprintf(stderr, + "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname); + exit(1); +} + +static void +StampOutSecrets(void) +{ + bzero(master_key, sizeof master_key); + bzero(session_key, sizeof session_key); + bzero(master_key_schedule, sizeof master_key_schedule); +} + +static void +Die(void) +{ + StampOutSecrets(); + exit(1); +} + +static void +FWrite(char *p, int size, int n, FILE *f) +{ + if (fwrite(p, size, n, f) != n) { + printf("Error writing output file. Terminating.\n"); + Die(); + } +} + +int +main(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((char*)&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((char*)session_key, sizeof session_key, 1, fout); + } + fclose(fout); + } + + StampOutSecrets(); + + exit(fopen_errs); /* 0 errors if successful */ + +} diff --git a/kerberosIV/include/Makefile b/kerberosIV/include/Makefile new file mode 100644 index 00000000000..cf1fe5bc188 --- /dev/null +++ b/kerberosIV/include/Makefile @@ -0,0 +1,5 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ + +SUBDIR= kerberosIV ss + +.include diff --git a/kerberosIV/include/adm_locl.h b/kerberosIV/include/adm_locl.h new file mode 100644 index 00000000000..6a1495c69b1 --- /dev/null +++ b/kerberosIV/include/adm_locl.h @@ -0,0 +1,54 @@ +/* $Id: adm_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#ifndef __adm_locl_h +#define __adm_locl_h + +#define TRUE 1 +#define FALSE 0 + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include "kdc.h" + +/* Utils */ +long maketime __P((struct tm *, int)); + +#endif /* __adm_locl_h */ diff --git a/kerberosIV/include/kadm_locl.h b/kerberosIV/include/kadm_locl.h new file mode 100644 index 00000000000..7653d9ec744 --- /dev/null +++ b/kerberosIV/include/kadm_locl.h @@ -0,0 +1,86 @@ +/* $Id: kadm_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include "kerberosIV/site.h" + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include "kerberosIV/com_err.h" +#include + +#include +#include +#include "krb_err.h" +#include +#include +#include "kadm_err.h" +#include "kerberosIV/acl.h" + +#include "kadm_server.h" + +/* GLOBALS */ +extern char *acldir; +extern Kadm_Server server_parm; + +/* Utils */ +int kadm_change __P((char *, char *, char *, des_cblock)); +int kadm_add_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *)); +int kadm_mod_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *, Kadm_vals *)); +int kadm_get_entry __P((char *, char *, char *, Kadm_vals *, u_char *, Kadm_vals *)); +int kadm_ser_cpw __P((u_char *, int, AUTH_DAT *, u_char **, int *)); +int kadm_ser_add __P((u_char *, int, AUTH_DAT *, u_char **, int *)); +int kadm_ser_mod __P((u_char *, int, AUTH_DAT *, u_char **, int *)); +int kadm_ser_get __P((u_char *, int, AUTH_DAT *, u_char **, int *)); +int kadm_ser_init __P((int inter, char realm[])); +int kadm_ser_in __P((u_char **, int *)); + +long maketime __P((struct tm *, int)); + +void change_password __P((int argc, char *argv[])); +void change_admin_password __P((int argc, char *argv[])); +void add_new_key __P((int argc, char *argv[])); +void get_entry __P((int argc, char *argv[])); +void mod_entry __P((int argc, char *argv[])); +void help __P((int argc, char *argv[])); +void clean_up __P((void)); +void quit __P((void)); diff --git a/kerberosIV/include/kadm_server.h b/kerberosIV/include/kadm_server.h new file mode 100644 index 00000000000..e742db51f79 --- /dev/null +++ b/kerberosIV/include/kadm_server.h @@ -0,0 +1,57 @@ +/* $Id: kadm_server.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * 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. + * + */ + +/* + * Definitions for Kerberos administration server & client + */ + +#ifndef KADM_SERVER_DEFS +#define KADM_SERVER_DEFS + +/* + * kadm_server.h + * Header file for the fourth attempt at an admin server + * Doug Church, December 28, 1989, MIT Project Athena + * ps. Yes that means this code belongs to athena etc... + * as part of our ongoing attempt to copyright all greek names + */ + +#include +#include +#include + +typedef struct { + struct sockaddr_in admin_addr; + struct sockaddr_in recv_addr; + int recv_addr_len; + int admin_fd; /* our link to clients */ + char sname[ANAME_SZ]; + char sinst[INST_SZ]; + char krbrlm[REALM_SZ]; + des_cblock master_key; + des_cblock session_key; + des_key_schedule master_key_schedule; + long master_key_version; +} Kadm_Server; + +#endif /* KADM_SERVER_DEFS */ diff --git a/kerberosIV/include/kdc.h b/kerberosIV/include/kdc.h new file mode 100644 index 00000000000..e2f625d5cb6 --- /dev/null +++ b/kerberosIV/include/kdc.h @@ -0,0 +1,32 @@ +/* $Id: kdc.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Include file for the Kerberos Key Distribution Center. + */ + +#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 diff --git a/kerberosIV/include/kerberosIV/acl.h b/kerberosIV/include/kerberosIV/acl.h new file mode 100644 index 00000000000..0a3ce5c5fea --- /dev/null +++ b/kerberosIV/include/kerberosIV/acl.h @@ -0,0 +1,15 @@ +/* $Id: acl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +#ifndef __ACL_H +#define __ACL_H + +#include + +void acl_canonicalize_principal __P((char *principal, char *canon)); +int acl_initialize __P((char *acl_file, int perm)); +int acl_exact_match __P((char *acl, char *principal)); +int acl_check __P((char *acl, char *principal)); +int acl_add __P((char *acl, char *principal)); +int acl_delete __P((char *acl, char *principal)); + +#endif /* __ACL_H */ diff --git a/kerberosIV/include/kerberosIV/com_err.h b/kerberosIV/include/kerberosIV/com_err.h new file mode 100644 index 00000000000..0d7fb9a06b9 --- /dev/null +++ b/kerberosIV/include/kerberosIV/com_err.h @@ -0,0 +1,27 @@ +/* $Id: com_err.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Header file for common error description library. + * + * Copyright 1988, Student Information Processing Board of the + * Massachusetts Institute of Technology. + * + * For copyright and distribution info, see the documentation supplied + * with this package. + */ + +#ifndef __COM_ERR_H +#define __COM_ERR_H + +#include + +/* ANSI C -- use prototypes etc */ +void com_err __P((const char *, long, const char *, ...)); +char const *error_message __P((long)); +void (*com_err_hook) __P((const char *, long, const char *, va_list)); +void (*set_com_err_hook __P((void (*) (const char *, long, const char *, va_list)))) + __P((const char *, long, const char *, va_list)); +void (*reset_com_err_hook __P((void))) + __P((const char *, long, const char *, va_list)); + +#endif /* ! defined(__COM_ERR_H) */ diff --git a/kerberosIV/include/kerberosIV/des.h b/kerberosIV/include/kerberosIV/des.h new file mode 100644 index 00000000000..dd8c9ac5390 --- /dev/null +++ b/kerberosIV/include/kerberosIV/des.h @@ -0,0 +1,86 @@ +/* $Id: des.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/* Copyright (C) 1993 Eric Young - see README for more details */ +#ifndef DES_DEFS +#define DES_DEFS + +#include +#include + +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 */ + u_int32_t 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 + +#if !defined(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 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; +#endif + +extern int des_check_key; /* defaults to false */ +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ + +int des_3ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks1,des_key_schedule ks2,int encrypt)); +int des_3cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule sk1,des_key_schedule sk2,des_cblock *ivec1,des_cblock *ivec2,int encrypt)); +u_int32_t des_cbc_cksum __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec)); +int des_cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); +int des_cfb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); +int des_ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks,int encrypt)); +int des_encrypt __P((u_int32_t *input,u_int32_t *output,des_key_schedule ks, int encrypt)); +int des_enc_read __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv)); +int des_enc_write __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv)); +int des_ofb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec)); +int des_pcbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); + +void des_set_odd_parity __P((des_cblock *key)); +int des_is_weak_key __P((des_cblock *key)); +int des_set_key __P((des_cblock *key,des_key_schedule schedule)); +int des_key_sched __P((des_cblock *key,des_key_schedule schedule)); + +int des_string_to_key __P((char *str,des_cblock *key)); +int des_string_to_2keys __P((char *str,des_cblock *key1,des_cblock *key2)); + +void des_set_random_generator_seed __P((des_cblock *seed)); +int des_new_random_key __P((des_cblock *key)); +void des_init_random_number_generator __P((des_cblock *seed)); +void des_random_key __P((des_cblock ret)); +int des_read_password __P((des_cblock *key,char *prompt,int verify)); +int des_read_2passwords __P((des_cblock *key1,des_cblock *key2,char *prompt,int verify)); +int des_read_pw_string __P((char *buf,int length,char *prompt,int verify)); + +u_int32_t des_quad_cksum __P((des_cblock *input,des_cblock *output,long length,int out_count,des_cblock *seed)); + +/* MIT Link and source compatibility */ +void des_fixup_key_parity __P((des_cblock *key)); +#define des_fixup_key_parity des_set_odd_parity + +#endif /* DES_DEFS */ diff --git a/kerberosIV/include/kerberosIV/kadm.h b/kerberosIV/include/kerberosIV/kadm.h new file mode 100644 index 00000000000..a649b0ff091 --- /dev/null +++ b/kerberosIV/include/kerberosIV/kadm.h @@ -0,0 +1,138 @@ +/* $Id: kadm.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Definitions for Kerberos administration server & client + */ + +#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 + */ + +/* 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_int8_t fields[FLDSZ]; /* The active fields in this struct */ + char name[ANAME_SZ]; + char instance[INST_SZ]; + u_int32_t key_low; + u_int32_t key_high; + u_int32_t exp_date; + u_int16_t attributes; + u_int8_t 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 + +void prin_vals __P((Kadm_vals *)); +int stv_long __P((u_char *, u_int32_t *, int, int)); + +int stream_to_vals __P((u_char *, Kadm_vals *, int)); +int vals_to_stream __P((Kadm_vals *, u_char **)); + +int kadm_init_link __P((char *, char *, char *)); +int kadm_change_pw __P((unsigned char *)); +int kadm_mod __P((Kadm_vals *, Kadm_vals *)); +int kadm_get __P((Kadm_vals *, u_char *)); +int kadm_add __P((Kadm_vals *)); +void kadm_vals_to_prin __P((u_char *, Principal *, Kadm_vals *)); +void kadm_prin_to_vals __P((u_char *, Kadm_vals *, Principal *)); + +#endif /* KADM_DEFS */ diff --git a/kerberosIV/include/kerberosIV/kafs.h b/kerberosIV/include/kerberosIV/kafs.h new file mode 100644 index 00000000000..1a1bc1a440c --- /dev/null +++ b/kerberosIV/include/kerberosIV/kafs.h @@ -0,0 +1,47 @@ +/* $Id: kafs.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +#ifndef __KAFS_H +#define __KAFS_H + +#define AFSCALL_PIOCTL 20 +#define AFSCALL_SETPAG 21 + +#ifndef _VICEIOCTL +#if defined(__STDC__) || defined(sgi) +#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl)) +#else +#define _VICEIOCTL(id) ((unsigned int ) _IOW(V, id, struct ViceIoctl)) +#endif +#endif /* _VICEIOCTL */ + +#define VIOCSETTOK _VICEIOCTL(3) +#define VIOCUNLOG _VICEIOCTL(9) + +struct ViceIoctl { + caddr_t in, out; + short in_size; + short out_size; +}; + +struct ClearToken { + int32_t AuthHandle; + char HandShakeKey[8]; + int32_t ViceId; + int32_t BeginTimestamp; + int32_t EndTimestamp; +}; + +/* Use k_hasafs() to probe if the machine supports AFS syscalls. + The other functions will generate a SIGSYS if AFS is not supported */ + +int k_hasafs __P((void)); + +int k_afsklog __P((char *realm)); +int k_pioctl __P((char *a_path, + int o_opcode, + struct ViceIoctl *a_paramsP, + int a_followSymlinks)); +int k_unlog __P((void)); +int k_setpag __P((void)); + +#endif /* __KAFS_H */ diff --git a/kerberosIV/include/kerberosIV/kparse.h b/kerberosIV/include/kerberosIV/kparse.h new file mode 100644 index 00000000000..ae72c84e111 --- /dev/null +++ b/kerberosIV/include/kerberosIV/kparse.h @@ -0,0 +1,109 @@ +/* $Id: kparse.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Include file for kparse routines. + */ + +#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 + */ + +#include + +int fGetParameterSet __P((FILE *fp, parmtable *parm, int parmcount)); +int ParmCompare __P((parmtable *parm, int parmcount, char *keyword, char *value)); +void FreeParameterSet __P((parmtable *parm, int parmcount)); +int fGetKeywordValue __P((FILE *fp, char *keyword, int klen, char *value, int vlen)); +int fGetToken __P((FILE *fp, char *dest, int maxlen)); +int fGetLiteral __P((FILE *fp)); +int fUngetChar __P((int ch, FILE *fp)); +int fGetChar __P((FILE *fp)); +char * strsave __P((char *p)); +char * strutol __P((char *start)); + +#endif /* KPARSE_DEFS */ diff --git a/kerberosIV/include/kerberosIV/krb.h b/kerberosIV/include/kerberosIV/krb.h new file mode 100644 index 00000000000..dc8c0435e32 --- /dev/null +++ b/kerberosIV/include/kerberosIV/krb.h @@ -0,0 +1,432 @@ +/* $Id: krb.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Include file for the Kerberos library. + */ + +/* Only one time, please */ +#ifndef KRB_DEFS +#define KRB_DEFS + +#include +#include + +/* Include site.h file to define paths */ +#include + +/* Need some defs from des.h */ +#include + +/* Global library variables. */ +extern int krbONE; +#define HOST_BYTE_ORDER (* (char *) &krbONE) +extern int private_msg_ver; /* in rd_priv.c */ +extern int req_act_vno; /* this is defined in the kerberos server code */ + + +/* Text describing error codes */ +#define MAX_KRB_ERRORS 256 +extern const char *krb_err_txt[MAX_KRB_ERRORS]; + +/* General definitions */ +#define KSUCCESS 0 +#define KFAILURE 255 + +/* + * 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. + */ + +/* 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 */ +/* default lifetime for krb_mk_req & co., 10 hrs */ +#define DEFAULT_TKT_LIFE 120 +#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 */ + u_int32_t 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 + +/* Parameters for rd_ap_req */ +/* Maximum alloable clock skew in seconds */ +#define CLOCK_SKEW 5*60 + +/* 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 */ + u_int32_t checksum; /* Data checksum (opt) */ + des_cblock session; /* Session Key */ + int life; /* Life of ticket */ + u_int32_t time_sec; /* Time ticket issued */ + u_int32_t 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 */ + des_cblock session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT_ST ticket_st; /* The ticket itself */ + int32_t 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 */ + u_int32_t app_length; /* length of appl data */ + u_int32_t hash; /* hash to lookup replay */ + int swap; /* swap bytes? */ + int32_t 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 */ +#define TKT_FILE tkt_string() +#define TKT_ROOT "/tmp/tkt" + +/* 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_int32_t 0-->3, 1-->2, 2-->1, 3-->0 + * u_int16_t 0-->1, 1-->0 + */ + +#define swap_u_16(x) {\ + u_int32_t _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) {\ + u_int32_t _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) {\ + u_int32_t _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) {\ + u_int32_t _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) {\ + u_int32_t _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) {\ + u_int16_t _krb_swap_sh_tmp; \ + swab((char *) &x, ( &_krb_swap_sh_tmp) ,2); \ + x = (u_int16_t) _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 */ + +/* 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 */ + +struct tm; +struct tm *k_localtime __P((u_int32_t *)); + +/* --- Random prototypes */ +#include /* to get u_char */ + +/* Host address comparison */ +int krb_equiv __P((u_int32_t, u_int32_t)); + +/* Password conversion */ +void mit_string_to_key __P((char *str, char *cell, des_cblock *key)); +void afs_string_to_key __P((char *str, char *cell, des_cblock *key)); + +/* Lifetime conversion */ +u_int32_t krb_life_to_time __P((u_int32_t start, int life)); +int krb_time_to_life __P((u_int32_t start, u_int32_t end)); +char *krb_life_to_atime __P((int life)); +int krb_atime_to_life __P((char *atime)); + +/* Ticket manipulation */ +int tf_get_cred __P((CREDENTIALS *)); +int tf_get_pinst __P((char *)); +int tf_get_pname __P((char *)); +int tf_init __P((char *, int)); +int tf_save_cred __P((char *, char *, char *, unsigned char *, int , int , KTEXT ticket, u_int32_t)); +void tf_close __P((void)); + +/* Private communication */ +struct sockaddr_in; +int32_t krb_mk_priv __P((u_char *, u_char *, u_int32_t , struct des_ks_struct *, des_cblock *, struct sockaddr_in *, struct sockaddr_in *)); +int32_t krb_rd_priv __P((u_char *, u_int32_t, struct des_ks_struct *, des_cblock *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *)); + +/* Misc */ +KTEXT create_auth_reply __P((char *, char *, char *, int32_t, int, u_int32_t, int, KTEXT)); + +char *krb_get_phost __P((char *)); +char *krb_realmofhost __P((char *)); +char *tkt_string __P((void)); + +int create_ciph __P((KTEXT, unsigned char *, char *, char *, char *, u_int32_t, int, KTEXT, u_int32_t, des_cblock *)); +int decomp_ticket __P((KTEXT, unsigned char *, char *, char *, char *, u_int32_t *, unsigned char *, int *, u_int32_t *, char *, char *, des_cblock *, struct des_ks_struct *)); +int dest_tkt __P((void)); +int get_ad_tkt __P((char *, char *, char *, int)); +int get_pw_tkt __P((char *, char *, char *, char *)); +int get_request __P((KTEXT, int, char **, char **)); +int get_request __P((KTEXT, int, char **, char **)); +int in_tkt __P((char *, char *)); +int k_isinst __P((char *)); +int k_isname __P((char *)); +int k_isrealm __P((char *)); +int kname_parse __P((char *, char *, char *, char *)); +int krb_create_ticket __P((KTEXT, unsigned char, char *, char *, char *, int32_t, char *, int16_t, int32_t, char *, char *, des_cblock *)); +int krb_get_admhst __P((char *, char *, int)); +int krb_get_admhst __P((char *, char *, int)); +int krb_get_cred __P((char *, char *, char *, CREDENTIALS *)); +int krb_get_in_tkt __P((char *, char *, char *, char *, char *, int , int (*key_proc) (/* ??? */), int (*decrypt_proc) (/* ??? */), char *)); +int krb_get_krbhst __P((char *, char *, int)); +int krb_get_krbhst __P((char *, char *, int)); +int krb_get_krbhst __P((char *, char *, int)); +int krb_get_lrealm __P((char *, int)); +int krb_get_pw_in_tkt __P((char *, char *, char *, char *, char *, int, char *)); +int krb_get_svc_in_tkt __P((char *, char *, char *, char *, char *, int, char *)); +int krb_get_tf_fullname __P((char *, char *, char *, char *)); +int krb_get_tf_realm __P((char *, char *)); +int krb_kntoln __P((AUTH_DAT *, char *)); +int krb_mk_req __P((KTEXT , char *, char *, char *, int32_t)); +int krb_net_read __P((int , char *, int)); +int krb_net_write __P((int , char *, int)); +int krb_rd_err __P((u_char *, u_int32_t, int32_t *, MSG_DAT *)); +int krb_rd_req __P((KTEXT , char *, char *, int32_t, AUTH_DAT *, char *)); +int krb_recvauth __P((int32_t, int, KTEXT, char *, char *, struct sockaddr_in *, struct sockaddr_in *, AUTH_DAT *, char *, struct des_ks_struct *, char *)); +int krb_sendauth __P((int32_t, int, KTEXT, char *, char *, char *, u_int32_t, MSG_DAT *, CREDENTIALS *, struct des_ks_struct *, struct sockaddr_in *, struct sockaddr_in *, char *)); +int krb_set_key __P((char *, int)); +int krb_set_lifetime __P((int)); +int kuserok __P((AUTH_DAT *, char *)); +int read_service_key __P((char *, char *, char *, int , char *, char *)); +int save_credentials __P((char *, char *, char *, unsigned char *, int , int , KTEXT , int32_t)); +int send_to_kdc __P((KTEXT , KTEXT , char *)); + +int32_t krb_mk_err __P((u_char *, int32_t, char *)); +int32_t krb_mk_safe __P((u_char *, u_char *, u_int32_t, des_cblock *, struct sockaddr_in *, struct sockaddr_in *)); +int32_t krb_rd_safe __P((u_char *, u_int32_t, des_cblock *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *)); + +void ad_print __P((AUTH_DAT *)); +void cr_err_reply __P((KTEXT, char *, char *, char *, u_int32_t, u_int32_t, char *)); +void extract_ticket __P((KTEXT, int, char *, int *, int *, char *, KTEXT)); +void krb_set_tkt_string __P((char *)); + +void kset_logfile __P((char *)); +void set_logfile __P((char *)); + +void log (); +char *klog (); + +int getst __P((int, char *, int)); + + +#endif /* KRB_DEFS */ diff --git a/kerberosIV/include/kerberosIV/krb_db.h b/kerberosIV/include/kerberosIV/krb_db.h new file mode 100644 index 00000000000..a463e992737 --- /dev/null +++ b/kerberosIV/include/kerberosIV/krb_db.h @@ -0,0 +1,127 @@ +/* $Id: krb_db.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* spm Project Athena 8/85 + * + * This file defines data structures for the kerberos + * authentication/authorization database. + * + * They MUST correspond to those defined in *.rel + */ + +#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 "" + +/* 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]; + + u_int32_t key_low; + u_int32_t key_high; + u_int32_t exp_date; + char exp_date_txt[DATE_SZ]; + u_int32_t mod_date; + char mod_date_txt[DATE_SZ]; + u_int16_t attributes; + u_int8_t max_life; + u_int8_t kdc_key_ver; + u_int8_t 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 { + int32_t cpu; + int32_t elapsed; + int32_t dio; + int32_t pfault; + int32_t t_stamp; + int32_t n_retrieve; + int32_t n_replace; + int32_t n_append; + int32_t n_get_stat; + int32_t n_put_stat; +} + DB_stat; + +/* Dba defines the structure of a database administrator */ + +typedef struct { + char name[ANAME_SZ]; + char instance[INST_SZ]; + u_int16_t attributes; + u_int32_t exp_date; + char exp_date_txt[DATE_SZ]; + char *old; /* + * cast to (Dba *); not in db, ptr to + * old vals + */ +} + Dba; + +int kerb_get_principal __P((char *, char *, Principal *, unsigned int, int *)); +int kerb_put_principal __P((Principal *, unsigned int)); +void kerb_db_get_stat __P((DB_stat *)); +void kerb_db_put_stat __P((DB_stat *)); +int kerb_get_dba __P((char *, char *, Dba *, unsigned int, int *)); +int kerb_db_get_dba __P(()); +int kerb_init __P((void)); +void kerb_fini __P((void)); +time_t kerb_get_db_age __P((void)); + +void kdb_encrypt_key __P((des_cblock *, des_cblock *, des_cblock *, des_key_schedule, int)); +int kerb_db_set_name __P((char *)); + +long kdb_get_master_key __P((int, des_cblock *, des_key_schedule)); + +#include +long kdb_verify_master_key __P((des_cblock *, des_key_schedule, FILE *)); + +int kerb_db_create __P((char *db_name)); +int kerb_db_put_principal __P((Principal *, unsigned int)); +int kerb_db_iterate __P((int (*)(char *, Principal *), char *)); +int kerb_db_rename __P((char *, char *)); +int kerb_db_set_lockmode __P((int)); + +#endif /* KRB_DB_DEFS */ diff --git a/kerberosIV/include/kerberosIV/site.h b/kerberosIV/include/kerberosIV/site.h new file mode 100644 index 00000000000..d3191ed8d63 --- /dev/null +++ b/kerberosIV/include/kerberosIV/site.h @@ -0,0 +1,46 @@ +/* $Id: site.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ */ + +/* + * Site-specific definitions. + */ + +#ifndef SITE_H +#define SITE_H + +/* + * Location of common files. + */ +#define KRB_CONF "/etc/kerberosIV/krb.conf" +#define KRB_RLM_TRANS "/etc/kerberosIV/krb.realms" +#define KRB_EQUIV "/etc/kerberosIV/krb.equiv" +#define KRB_ACL "/etc/kerberosIV/kerberos.acl" +#define MKEYFILE "/etc/kerberosIV/master_key" +#define KEYFILE "/etc/kerberosIV/srvtab" +#define DBM_FILE "/etc/kerberosIV/principal" + +#define K_LOGFIL "/var/log/kpropd.log" +#define KS_LOGFIL "/var/log/kerberos_slave.log" +#define KRBLOG "/var/log/kerberos.log" /* master server */ +#define KRBSLAVELOG "/var/log/kerberos_slave.log" /* master (?) server */ + +#define KRB_MASTER "kerberos" +#define KRB_HOST "kowande.bu.oz.au" +#define KRB_REALM "KOWANDE.BU.OZ.AU" + +/* from: kadm_server.h */ +/* the default syslog file */ +#define KADM_SYSLOG "/var/log/admin_server.log" + +#define DEFAULT_ACL_DIR "/etc/kerberosIV/" +/* These get appended to DEFAULT_ACL_DIR */ +#define ADD_ACL_FILE "admin_acl.add" +#define GET_ACL_FILE "admin_acl.get" +#define MOD_ACL_FILE "admin_acl.mod" + +/* + * Set ORGANIZATION to be the desired organization string printed + * by the 'kinit' program. It may have spaces. + */ +#define ORGANIZATION "The OpenBSD Project" + +#endif diff --git a/kerberosIV/include/klog.h b/kerberosIV/include/klog.h new file mode 100644 index 00000000000..e8747f17e7c --- /dev/null +++ b/kerberosIV/include/klog.h @@ -0,0 +1,37 @@ +/* $Id: klog.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +/*- + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * This file defines the types of log messages logged by klog. Each + * type of message may be selectively turned on or off. + */ + +#ifndef KLOG_DEFS +#define KLOG_DEFS + +#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/kerberosIV/include/kprop.h b/kerberosIV/include/kprop.h new file mode 100644 index 00000000000..ab480c64481 --- /dev/null +++ b/kerberosIV/include/kprop.h @@ -0,0 +1,18 @@ +/* $Id: kprop.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +/*- + * Copyright 1987 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file . + */ + +#define KPROP_SERVICE_NAME "rcmd" +#define KPROP_SRVTAB "/etc/srvtab" +#define TGT_SERVICE_NAME "krbtgt" +#define KPROP_PROT_VERSION_LEN 8 +#define KPROP_PROT_VERSION "kprop01" +#define KPROP_TRANSFER_PRIVATE 1 +#define KPROP_TRANSFER_SAFE 2 +#define KPROP_TRANSFER_CLEAR 3 +#define KPROP_BUFSIZ 32768 diff --git a/kerberosIV/include/kuser_locl.h b/kerberosIV/include/kuser_locl.h new file mode 100644 index 00000000000..f52b3061b28 --- /dev/null +++ b/kerberosIV/include/kuser_locl.h @@ -0,0 +1,19 @@ +/* $Id: kuser_locl.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +#include "kerberosIV/site.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include diff --git a/kerberosIV/include/prot.h b/kerberosIV/include/prot.h new file mode 100644 index 00000000000..da9f106a588 --- /dev/null +++ b/kerberosIV/include/prot.h @@ -0,0 +1,89 @@ +/* $Id: prot.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +/*- + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Include file with authentication protocol information. + */ + +#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(); + +/* 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/kerberosIV/include/slav_locl.h b/kerberosIV/include/slav_locl.h new file mode 100644 index 00000000000..36b6a3f9761 --- /dev/null +++ b/kerberosIV/include/slav_locl.h @@ -0,0 +1,34 @@ +/* $Id: slav_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */ + +#ifndef __slav_locl_h +#define __slav_locl_h + +#include "kerberosIV/site.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include "klog.h" +#include "prot.h" +#include "kdc.h" + +#endif /* __slav_locl_h */ diff --git a/kerberosIV/include/ss/Makefile b/kerberosIV/include/ss/Makefile new file mode 100644 index 00000000000..85986e88e8c --- /dev/null +++ b/kerberosIV/include/ss/Makefile @@ -0,0 +1,18 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ + +FILES= ss.h +NOOBJ= noobj + +all include clean cleandir depend lint tags: + +realinstall: + @echo installing ${FILES} + @-for i in ${FILES}; do \ + cmp -s $$i ${DESTDIR}/usr/include/ss/$$i || \ + install -c -m 444 $$i ${DESTDIR}/usr/include/ss/$$i; \ + done + +beforeinstall: + install -d -o ${BINOWN} -g ${BINGRP} -m 755 ${DESTDIR}/usr/include/ss + +.include diff --git a/kerberosIV/include/ss/ss.h b/kerberosIV/include/ss/ss.h new file mode 100644 index 00000000000..f387fd4578b --- /dev/null +++ b/kerberosIV/include/ss/ss.h @@ -0,0 +1,65 @@ +/* $Id: ss.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#ifndef _SS_H +#define _SS_H + +#include + +#ifndef NO_SS_ERR_H +#include +#endif + +typedef const struct _ss_request_entry { + const char * const *command_names; /* whatever */ + void (* const function) __P((int, const char * const *, int, void *)); + const char * const info_string; /* NULL */ + int flags; /* 0 */ +} ss_request_entry; + +typedef const struct _ss_request_table { + int version; + ss_request_entry *requests; +} ss_request_table; + +#define SS_RQT_TBL_V2 2 + +typedef struct _ss_rp_options { /* DEFAULT VALUES */ + int version; /* SS_RP_V1 */ + void (*unknown) __P((int, const char * const *, int, void *)); /* call for unknown command */ + int allow_suspend; + int catch_int; +} ss_rp_options; + +#define SS_RP_V1 1 + +#define SS_OPT_DONT_LIST 0x0001 +#define SS_OPT_DONT_SUMMARIZE 0x0002 + +void ss_help __P((int, const char * const *, int, void *)); +char *ss_current_request(); +char *ss_name(); +void ss_error __P((int, long, char const *, ...)); +void ss_perror __P((int, long, char const *)); +int ss_create_invocation __P((char *, char *, char *, ss_request_table *, int *)); +int ss_listen(int); +void ss_abort_subsystem(); + +extern ss_request_table ss_std_requests; +#endif /* _SS_H */ diff --git a/kerberosIV/kadm/Makefile b/kerberosIV/kadm/Makefile new file mode 100644 index 00000000000..63aa3c33a9d --- /dev/null +++ b/kerberosIV/kadm/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ + +LIB= kadm +SRCS= kadm_err.c kadm_cli_wrap.c kadm_stream.c kadm_supp.c +CFLAGS+=-I. -I${.CURDIR} +.if exists(${.CURDIR}/../krb/obj) +CFLAGS+=-I${.CURDIR}/../krb/obj +.else +CFLAGS+=-I${.CURDIR}/../krb +.endif +LDADD+= ${COM_ERR} +CLEANFILES+= kadm_err.c kadm_err.h + +kadm_err.c kadm_err.h: kadm_err.et + test -e kadm_err.et || ln -s ${.CURDIR}/kadm_err.et . + ${COMPILE_ET} kadm_err.et + -test -h kadm_err.et && rm kadm_err.et + +beforeinstall: + -cd ${.OBJDIR}; cmp -s kadm_err.h ${DESTDIR}/usr/include/kerberosIV/kadm_err.h || \ + install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm_err.h ${DESTDIR}/usr/include/kerberosIV + +.include diff --git a/kerberosIV/kadm/kadm_cli_wrap.c b/kerberosIV/kadm/kadm_cli_wrap.c new file mode 100644 index 00000000000..bdba1a6b109 --- /dev/null +++ b/kerberosIV/kadm/kadm_cli_wrap.c @@ -0,0 +1,509 @@ +/* $Id: kadm_cli_wrap.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +/*- + * 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. + * + */ + +/* + * Kerberos administration server client-side routines + */ + +/* + * kadm_cli_wrap.c the client side wrapping of the calls to the admin server + */ + +#include "kadm_local.h" + +#ifndef NULL +#define NULL 0 +#endif + +static Kadm_Client client_parm; + +/* Macros for use in returning data... used in kadm_cli_send */ +#define RET_N_FREE(r) {clear_secrets(); free((char *)act_st); free((char *)priv_pak); return r;} + +/* Keys for use in the transactions */ +static des_cblock sess_key; /* to be filled in by kadm_cli_keyd */ +static des_key_schedule sess_sched; + +static void +clear_secrets() +{ + bzero((char *)sess_key, sizeof(sess_key)); + bzero((char *)sess_sched, sizeof(sess_sched)); + return; +} + +static void (*opipe)(); + +static void +kadm_cli_disconn() +{ + (void) close(client_parm.admin_fd); + (void) signal(SIGPIPE, opipe); + return; +} + +/* + * kadm_init_link + * receives : name, inst, realm + * + * initializes client parm, the Kadm_Client structure which holds the + * data about the connection between the server and client, the services + * used, the locations and other fun things + */ +int +kadm_init_link(n, i, r) + char *n; + char *i; + char *r; +{ + struct servent *sep; /* service we will talk to */ + struct hostent *hop; /* host we will talk to */ + char adm_hostname[MAXHOSTNAMELEN]; + + (void) init_kadm_err_tbl(); + (void) init_krb_err_tbl(); + (void) strcpy(client_parm.sname, n); + (void) strcpy(client_parm.sinst, i); + (void) strcpy(client_parm.krbrlm, r); + client_parm.admin_fd = -1; + + /* set up the admin_addr - fetch name of admin host */ + if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS) + return KADM_NO_HOST; + if ((hop = gethostbyname(adm_hostname)) == NULL) + return KADM_UNK_HOST; /* couldnt find the admin servers + * address */ + if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL) + return KADM_NO_SERV; /* couldnt find the admin service */ + bzero((char *) &client_parm.admin_addr, + sizeof(client_parm.admin_addr)); + client_parm.admin_addr.sin_family = hop->h_addrtype; + bcopy((char *) hop->h_addr, (char *) &client_parm.admin_addr.sin_addr, + hop->h_length); + client_parm.admin_addr.sin_port = sep->s_port; + + return KADM_SUCCESS; +} /* procedure kadm_init_link */ + +static int +kadm_cli_conn() +{ /* this connects and sets my_addr */ + int on = 1; + + if ((client_parm.admin_fd = + socket(client_parm.admin_addr.sin_family, SOCK_STREAM,0)) < 0) + return KADM_NO_SOCK; /* couldnt create the socket */ + if (connect(client_parm.admin_fd, + (struct sockaddr *) & client_parm.admin_addr, + sizeof(client_parm.admin_addr))) { + (void) close(client_parm.admin_fd); + client_parm.admin_fd = -1; + return KADM_NO_CONN; /* couldnt get the connect */ + } + opipe = signal(SIGPIPE, SIG_IGN); + client_parm.my_addr_len = sizeof(client_parm.my_addr); + if (getsockname(client_parm.admin_fd, + (struct sockaddr *) & client_parm.my_addr, + &client_parm.my_addr_len) < 0) { + (void) close(client_parm.admin_fd); + client_parm.admin_fd = -1; + (void) signal(SIGPIPE, opipe); + return KADM_NO_HERE; /* couldnt find out who we are */ + } + if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, &on, + sizeof(on)) < 0) { + (void) close(client_parm.admin_fd); + client_parm.admin_fd = -1; + (void) signal(SIGPIPE, opipe); + return KADM_NO_CONN; /* XXX */ + } + return KADM_SUCCESS; +} + +/* takes in the sess_key and key_schedule and sets them appropriately */ +static int +kadm_cli_keyd(s_k, s_s) + des_cblock *s_k; /* session key */ + struct des_ks_struct *s_s; /* session key schedule */ +{ + CREDENTIALS cred; /* to get key data */ + int stat; + + /* want .sname and .sinst here.... */ + if ((stat = krb_get_cred(client_parm.sname, client_parm.sinst, + client_parm.krbrlm, &cred))) + return stat + krb_err_base; + bcopy((char *) cred.session, (char *) s_k, sizeof(des_cblock)); + bzero((char *) cred.session, sizeof(des_cblock)); +#ifdef NOENCRYPTION + bzero(s_s, sizeof(des_key_schedule)); +#else + if ((stat = des_key_sched(s_k,s_s))) + return(stat+krb_err_base); +#endif + return KADM_SUCCESS; +} /* This code "works" */ + +static int +kadm_cli_out(dat, dat_len, ret_dat, ret_siz) + u_char *dat; + int dat_len; + u_char **ret_dat; + int *ret_siz; +{ + u_short dlen; + int retval; + + dlen = (u_short) dat_len; + + if (dat_len != (int)dlen) + return (KADM_NO_ROOM); + + dlen = htons(dlen); + if (krb_net_write(client_parm.admin_fd, (char *) &dlen, + sizeof(u_short)) < 0) + return (errno); /* XXX */ + + if (krb_net_write(client_parm.admin_fd, (char *) dat, dat_len) < 0) + return (errno); /* XXX */ + + if ((retval = krb_net_read(client_parm.admin_fd, (char *) &dlen, + sizeof(u_short)) != sizeof(u_short))) { + if (retval < 0) + return(errno); /* XXX */ + else + return(EPIPE); /* short read ! */ + } + + dlen = ntohs(dlen); + *ret_dat = (u_char *)malloc((unsigned)dlen); + if (!*ret_dat) + return(KADM_NOMEM); + + if ((retval = krb_net_read(client_parm.admin_fd, (char *) *ret_dat, + (int) dlen) != dlen)) { + if (retval < 0) + return(errno); /* XXX */ + else + return(EPIPE); /* short read ! */ + } + *ret_siz = (int) dlen; + return KADM_SUCCESS; +} + +/* + * kadm_cli_send + * recieves : opcode, packet, packet length, serv_name, serv_inst + * returns : return code from the packet build, the server, or + * something else + * + * It assembles a packet as follows: + * 8 bytes : VERSION STRING + * 4 bytes : LENGTH OF MESSAGE DATA and OPCODE + * : KTEXT + * : OPCODE \ + * : DATA > Encrypted (with make priv) + * : ...... / + * + * If it builds the packet and it is small enough, then it attempts to open the + * connection to the admin server. If the connection is succesfully open + * then it sends the data and waits for a reply. + */ +static int +kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz) + u_char *st_dat; /* the actual data */ + int st_siz; /* length of said data */ + u_char **ret_dat; /* to give return info */ + int *ret_siz; /* length of returned info */ +{ + int act_len, retdat; /* current offset into packet, return + * data */ + KTEXT_ST authent; /* the authenticator we will build */ + u_char *act_st; /* the pointer to the complete packet */ + u_char *priv_pak; /* private version of the packet */ + int priv_len; /* length of private packet */ + u_int32_t cksum; /* checksum of the packet */ + MSG_DAT mdat; + u_char *return_dat; + + act_st = (u_char *) malloc(KADM_VERSIZE); /* verstr stored first */ + (void) strncpy((char *)act_st, KADM_VERSTR, KADM_VERSIZE); + act_len = KADM_VERSIZE; + + if ((retdat = kadm_cli_keyd(&sess_key, sess_sched)) != KADM_SUCCESS) { + free((char *)act_st); + return retdat; /* couldnt get key working */ + } + priv_pak = (u_char *) malloc((unsigned)(st_siz + 200)); + /* 200 bytes for extra info case */ + if ((priv_len = krb_mk_priv(st_dat, priv_pak, (u_int32_t)st_siz, + sess_sched, &sess_key, &client_parm.my_addr, + &client_parm.admin_addr)) < 0) + RET_N_FREE(KADM_NO_ENCRYPT); /* whoops... we got a lose + * here */ + /* here is the length of priv data. receiver calcs + size of authenticator by subtracting vno size, priv size, and + sizeof(u_int32_t) (for the size indication) from total size */ + + act_len += vts_long((u_int32_t) priv_len, &act_st, act_len); +#ifdef NOENCRYPTION + cksum = 0; +#else + cksum = des_quad_cksum((des_cblock *)priv_pak, (des_cblock *)0, (long)priv_len, 0, + &sess_key); +#endif + if ((retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst, + client_parm.krbrlm, (long)cksum))) { + /* authenticator? */ + RET_N_FREE(retdat + krb_err_base); + } + + act_st = (u_char *) realloc((char *) act_st, + (unsigned) (act_len + authent.length + + priv_len)); + if (!act_st) { + clear_secrets(); + free((char *)priv_pak); + return(KADM_NOMEM); + } + bcopy((char *) authent.dat, (char *) act_st + act_len, authent.length); + bcopy((char *) priv_pak, (char *) act_st + act_len + authent.length, + priv_len); + free((char *)priv_pak); + if ((retdat = kadm_cli_out(act_st, + act_len + authent.length + priv_len, + ret_dat, ret_siz)) != KADM_SUCCESS) + RET_N_FREE(retdat); + free((char *)act_st); +#define RET_N_FREE2(r) {free((char *)*ret_dat); clear_secrets(); return(r);} + + /* first see if it's a YOULOUSE */ + if ((*ret_siz >= KADM_VERSIZE) && + !strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) { + u_int32_t errcode; + /* it's a youlose packet */ + if (*ret_siz < KADM_VERSIZE + sizeof(u_int32_t)) + RET_N_FREE2(KADM_BAD_VER); + bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode, + sizeof(u_int32_t)); + retdat = (int) ntohl(errcode); + RET_N_FREE2(retdat); + } + /* need to decode the ret_dat */ + if ((retdat = krb_rd_priv(*ret_dat, (u_int32_t)*ret_siz, sess_sched, + &sess_key, &client_parm.admin_addr, + &client_parm.my_addr, &mdat))) + RET_N_FREE2(retdat+krb_err_base); + if (mdat.app_length < KADM_VERSIZE + 4) + /* too short! */ + RET_N_FREE2(KADM_BAD_VER); + if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE)) + /* bad version */ + RET_N_FREE2(KADM_BAD_VER); + bcopy((char *)mdat.app_data+KADM_VERSIZE, + (char *)&retdat, sizeof(u_int32_t)); + retdat = ntohl((u_int32_t)retdat); + if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length - + KADM_VERSIZE - sizeof(u_int32_t))))) + RET_N_FREE2(KADM_NOMEM); + bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_int32_t), + (char *)return_dat, + (int)mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t)); + free((char *)*ret_dat); + clear_secrets(); + *ret_dat = return_dat; + *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t); + return retdat; +} + +/* + * kadm_change_pw + * recieves : key + * + * Replaces the password (i.e. des key) of the caller with that specified in + * key. Returns no actual data from the master server, since this is called + * by a user + */ +int +kadm_change_pw(newkey) + unsigned char *newkey; /* The DES form of the users key */ +{ + int stsize, retc; /* stream size and return code */ + u_char *send_st; /* send stream */ + u_char *ret_st; + int ret_sz; + u_int32_t keytmp; + + if ((retc = kadm_cli_conn()) != KADM_SUCCESS) + return(retc); + /* possible problem with vts_long on a non-multiple of four boundary */ + + stsize = 0; /* start of our output packet */ + send_st = (u_char *) malloc(1);/* to make it reallocable */ + send_st[stsize++] = (u_char) CHANGE_PW; + + /* change key to stream */ + + bcopy((char *) (((long *) newkey) + 1), (char *) &keytmp, 4); + keytmp = htonl(keytmp); + stsize += vts_long(keytmp, &send_st, stsize); + + bcopy((char *) newkey, (char *) &keytmp, 4); + keytmp = htonl(keytmp); + stsize += vts_long(keytmp, &send_st, stsize); + + retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz); + free((char *)send_st); + if (retc == KADM_SUCCESS) { + free((char *)ret_st); + } + kadm_cli_disconn(); + return(retc); +} + +/* + * kadm_add + * receives : vals + * returns : vals + * + * Adds and entry containing values to the database returns the values of the + * entry, so if you leave certain fields blank you will be able to determine + * the default values they are set to + */ +int +kadm_add(vals) + Kadm_vals *vals; +{ + u_char *st, *st2; /* st will hold the stream of values */ + int st_len; /* st2 the final stream with opcode */ + int retc; /* return code from call */ + u_char *ret_st; + int ret_sz; + + if ((retc = kadm_cli_conn()) != KADM_SUCCESS) + return(retc); + st_len = vals_to_stream(vals, &st); + st2 = (u_char *) malloc((unsigned)(1 + st_len)); + *st2 = (u_char) ADD_ENT; /* here's the opcode */ + bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */ + retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); + free((char *)st); + free((char *)st2); + if (retc == KADM_SUCCESS) { + /* ret_st has vals */ + if (stream_to_vals(ret_st, vals, ret_sz) < 0) + retc = KADM_LENGTH_ERROR; + free((char *)ret_st); + } + kadm_cli_disconn(); + return(retc); +} + +/* + * kadm_mod + * receives : KTEXT, {values, values} + * returns : CKSUM, RETCODE, {values} + * acl : su, sms (as register or dealloc) + * + * Modifies all entries corresponding to the first values so they match the + * second values. returns the values for the changed entries in vals2 + */ +int +kadm_mod(vals1, vals2) + Kadm_vals *vals1; + Kadm_vals *vals2; +{ + u_char *st, *st2; /* st will hold the stream of values */ + int st_len, nlen; /* st2 the final stream with opcode */ + u_char *ret_st; + int ret_sz; + + /* nlen is the length of second vals */ + int retc; /* return code from call */ + + if ((retc = kadm_cli_conn()) != KADM_SUCCESS) + return(retc); + + st_len = vals_to_stream(vals1, &st); + st2 = (u_char *) malloc((unsigned)(1 + st_len)); + *st2 = (u_char) MOD_ENT; /* here's the opcode */ + bcopy((char *) st, (char *) st2 + 1, st_len++); /* append st on */ + free((char *)st); + nlen = vals_to_stream(vals2, &st); + st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen)); + bcopy((char *) st, (char *) st2 + st_len, nlen); /* append st on */ + retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz); + free((char *)st); + free((char *)st2); + if (retc == KADM_SUCCESS) { + /* ret_st has vals */ + if (stream_to_vals(ret_st, vals2, ret_sz) < 0) + retc = KADM_LENGTH_ERROR; + free((char *)ret_st); + } + kadm_cli_disconn(); + return(retc); +} + +/* + * kadm_get + * receives : KTEXT, {values, flags} + * returns : CKSUM, RETCODE, {count, values, values, values} + * acl : su + * + * gets the fields requested by flags from all entries matching values returns + * this data for each matching recipient, after a count of how many such + * matches there were + */ +int +kadm_get(vals, fl) + Kadm_vals *vals; + u_char *fl; +{ + int loop; /* for copying the fields data */ + u_char *st, *st2; /* st will hold the stream of values */ + int st_len; /* st2 the final stream with opcode */ + int retc; /* return code from call */ + u_char *ret_st; + int ret_sz; + + if ((retc = kadm_cli_conn()) != KADM_SUCCESS) + return(retc); + st_len = vals_to_stream(vals, &st); + st2 = (u_char *) malloc((unsigned)(1 + st_len + FLDSZ)); + *st2 = (u_char) GET_ENT; /* here's the opcode */ + bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */ + for (loop = FLDSZ - 1; loop >= 0; loop--) + *(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */ + retc = kadm_cli_send(st2, st_len + 1 + FLDSZ, &ret_st, &ret_sz); + free((char *)st); + free((char *)st2); + if (retc == KADM_SUCCESS) { + /* ret_st has vals */ + if (stream_to_vals(ret_st, vals, ret_sz) < 0) + retc = KADM_LENGTH_ERROR; + free((char *)ret_st); + } + kadm_cli_disconn(); + return(retc); +} diff --git a/kerberosIV/kadm/kadm_err.et b/kerberosIV/kadm/kadm_err.et new file mode 100644 index 00000000000..495c365e0dc --- /dev/null +++ b/kerberosIV/kadm/kadm_err.et @@ -0,0 +1,52 @@ +# $Id: kadm_err.et,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ + +# Copyright 1988 by the Massachusetts Institute of Technology. +# +# For copying and distribution information, please see the file +# . +# +# Kerberos administration server error table +# + et kadm + +# KADM_SUCCESS, as all success codes should be, is zero + +ec KADM_RCSID, "$Header: /home/cvs/src/kerberosIV/kadm/Attic/kadm_err.et,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $" +# /* Building and unbuilding the packet errors */ +ec KADM_NO_REALM, "Cannot fetch local realm" +ec KADM_NO_CRED, "Unable to fetch credentials" +ec KADM_BAD_KEY, "Bad key supplied" +ec KADM_NO_ENCRYPT, "Can't encrypt data" +ec KADM_NO_AUTH, "Cannot encode/decode authentication info" +ec KADM_WRONG_REALM, "Principal attemping change is in wrong realm" +ec KADM_NO_ROOM, "Packet is too large" +ec KADM_BAD_VER, "Version number is incorrect" +ec KADM_BAD_CHK, "Checksum does not match" +ec KADM_NO_READ, "Unsealing private data failed" +ec KADM_NO_OPCODE, "Unsupported operation" +ec KADM_NO_HOST, "Could not find administrating host" +ec KADM_UNK_HOST, "Administrating host name is unknown" +ec KADM_NO_SERV, "Could not find service name in services database" +ec KADM_NO_SOCK, "Could not create socket" +ec KADM_NO_CONN, "Could not connect to server" +ec KADM_NO_HERE, "Could not fetch local socket address" +ec KADM_NO_MAST, "Could not fetch master key" +ec KADM_NO_VERI, "Could not verify master key" + +# /* From the server side routines */ +ec KADM_INUSE, "Entry already exists in database" +ec KADM_UK_SERROR, "Database store error" +ec KADM_UK_RERROR, "Database read error" +ec KADM_UNAUTH, "Insufficient access to perform requested operation" +# KADM_DATA isn't really an error, but... +ec KADM_DATA, "Data is available for return to client" +ec KADM_NOENTRY, "No such entry in the database" + +ec KADM_NOMEM, "Memory exhausted" +ec KADM_NO_HOSTNAME, "Could not fetch system hostname" +ec KADM_NO_BIND, "Could not bind port" +ec KADM_LENGTH_ERROR, "Length mismatch problem" +ec KADM_ILL_WILDCARD, "Illegal use of wildcard" + +ec KADM_DB_INUSE, "Database is locked or in use--try again later" +end diff --git a/kerberosIV/kadm/kadm_local.h b/kerberosIV/kadm/kadm_local.h new file mode 100644 index 00000000000..8133671b64e --- /dev/null +++ b/kerberosIV/kadm/kadm_local.h @@ -0,0 +1,31 @@ +/* $Id: kadm_local.h,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include "krb_err.h" +#include +#include +#include "kadm_err.h" + +int vts_long __P((u_int32_t, u_char **, int)); +int vals_to_stream __P((Kadm_vals *, u_char **)); +int stream_to_vals __P((u_char *, Kadm_vals *, int)); + +int kadm_init_link __P((char n[], char i[], char r[])); +int kadm_change_pw __P((des_cblock)); +int kadm_add __P((Kadm_vals *)); +int kadm_mod __P((Kadm_vals *, Kadm_vals *)); +int kadm_get __P((Kadm_vals *, u_char fl[4])); diff --git a/kerberosIV/kadm/kadm_stream.c b/kerberosIV/kadm/kadm_stream.c new file mode 100644 index 00000000000..cdf291bbe93 --- /dev/null +++ b/kerberosIV/kadm/kadm_stream.c @@ -0,0 +1,294 @@ +/* $Id: kadm_stream.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Stream conversion functions for Kerberos administration server + */ + +/* + kadm_stream.c + this holds the stream support routines for the kerberos administration server + + vals_to_stream: converts a vals struct to a stream for transmission + internals build_field_header, vts_[string, char, long, short] + stream_to_vals: converts a stream to a vals struct + internals check_field_header, stv_[string, char, long, short] + error: prints out a kadm error message, returns + fatal: prints out a kadm fatal error message, exits +*/ + +#include "kadm_local.h" + +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +static int +build_field_header(cont, st) + u_char *cont; /* container for fields data */ + u_char **st; /* stream */ +{ + *st = (u_char *) malloc (4); + bcopy((char *) cont, (char *) *st, 4); + return 4; /* return pointer to current stream location */ +} + +static int +check_field_header(st, cont, maxlen) + u_char *st; /* stream */ + u_char *cont; /* container for fields data */ + int maxlen; +{ + if (4 > maxlen) + return(-1); + bcopy((char *) st, (char *) cont, 4); + return 4; /* return pointer to current stream location */ +} + +static int +vts_string(dat, st, loc) + char *dat; /* a string to put on the stream */ + u_char **st; /* base pointer to the stream */ + int loc; /* offset into the stream for current data */ +{ + *st = (u_char *) realloc ((char *)*st, (unsigned) (loc + strlen(dat) + 1)); + bcopy(dat, (char *)(*st + loc), strlen(dat)+1); + return strlen(dat)+1; +} + + +static int +vts_short(dat, st, loc) + u_int16_t dat; /* the attributes field */ + u_char **st; /* a base pointer to the stream */ + int loc; /* offset into the stream for current data */ +{ + u_int16_t temp; /* to hold the net order short */ + + temp = htons(dat); /* convert to network order */ + *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int16_t))); + bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int16_t)); + return sizeof(u_int16_t); +} + +static int +vts_char(dat, st, loc) + u_char dat; /* the attributes field */ + u_char **st; /* a base pointer to the stream */ + int loc; /* offset into the stream for current data */ +{ + *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_char))); + (*st)[loc] = (u_char) dat; + return 1; +} + +int +vts_long(dat, st, loc) + u_int32_t dat; /* the attributes field */ + u_char **st; /* a base pointer to the stream */ + int loc; /* offset into the stream for current data */ +{ + u_int32_t temp; /* to hold the net order short */ + + temp = htonl(dat); /* convert to network order */ + *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int32_t))); + bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int32_t)); + return sizeof(u_int32_t); +} + +static int +stv_string(st, dat, loc, stlen, maxlen) + register u_char *st; /* base pointer to the stream */ + char *dat; /* a string to read from the stream */ + register int loc; /* offset into the stream for current data */ + int stlen; /* max length of string to copy in */ + int maxlen; /* max length of input stream */ +{ + int maxcount; /* max count of chars to copy */ + + maxcount = min(maxlen - loc, stlen); + + (void) strncpy(dat, (char *)st + loc, maxcount); + + if (dat[maxcount-1]) /* not null-term --> not enuf room */ + return(-1); + return strlen(dat)+1; +} + +static int +stv_short(st, dat, loc, maxlen) + u_char *st; /* a base pointer to the stream */ + u_int16_t *dat; /* the attributes field */ + int loc; /* offset into the stream for current data */ + int maxlen; +{ + u_int16_t temp; /* to hold the net order short */ + + if (loc + sizeof(temp) > maxlen) + return(-1); + /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));*/ + bcopy(st + loc, (char *) &temp, sizeof(temp)); + *dat = ntohs(temp); /* convert to network order */ + return sizeof(temp); +} + +int +stv_long(st, dat, loc, maxlen) + u_char *st; /* a base pointer to the stream */ + u_int32_t *dat; /* the attributes field */ + int loc; /* offset into the stream for current data */ + int maxlen; /* maximum length of st */ +{ + u_int32_t temp; /* to hold the net order short */ + + if (loc + sizeof(temp) > maxlen) + return(-1); + /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));*/ + bcopy(st + loc, (char *) &temp, sizeof(temp)); + *dat = ntohl(temp); /* convert to network order */ + return sizeof(temp); +} + +static int +stv_char(st, dat, loc, maxlen) + u_char *st; /* a base pointer to the stream */ + u_char *dat; /* the attributes field */ + int loc; /* offset into the stream for current data */ + int maxlen; +{ + if (loc + 1 > maxlen) + return(-1); + *dat = *(st + loc); + return 1; +} + +/* +vals_to_stream + recieves : kadm_vals *, u_char * + returns : a realloced and filled in u_char * + +this function creates a byte-stream representation of the kadm_vals structure +*/ +int +vals_to_stream(dt_in, dt_out) + Kadm_vals *dt_in; + u_char **dt_out; +{ + int vsloop, stsize; /* loop counter, stream size */ + + stsize = build_field_header(dt_in->fields, dt_out); + for (vsloop=31; vsloop>=0; vsloop--) + if (IS_FIELD(vsloop,dt_in->fields)) { + switch (vsloop) { + case KADM_NAME: + stsize+=vts_string(dt_in->name, dt_out, stsize); + break; + case KADM_INST: + stsize+=vts_string(dt_in->instance, dt_out, stsize); + break; + case KADM_EXPDATE: + stsize+=vts_long(dt_in->exp_date, dt_out, stsize); + break; + case KADM_ATTR: + stsize+=vts_short(dt_in->attributes, dt_out, stsize); + break; + case KADM_MAXLIFE: + stsize+=vts_char(dt_in->max_life, dt_out, stsize); + break; + case KADM_DESKEY: + stsize+=vts_long(dt_in->key_high, dt_out, stsize); + stsize+=vts_long(dt_in->key_low, dt_out, stsize); + break; + default: + break; + } +} + return(stsize); +} + +/* +stream_to_vals + recieves : u_char *, kadm_vals * + returns : a kadm_vals filled in according to u_char * + +this decodes a byte stream represntation of a vals struct into kadm_vals +*/ +int +stream_to_vals(dt_in, dt_out, maxlen) + u_char *dt_in; + Kadm_vals *dt_out; + int maxlen; /* max length to use */ +{ + register int vsloop, stsize; /* loop counter, stream size */ + register int status; + + bzero((char *) dt_out, sizeof(*dt_out)); + + stsize = check_field_header(dt_in, dt_out->fields, maxlen); + if (stsize < 0) + return(-1); + for (vsloop=31; vsloop>=0; vsloop--) + if (IS_FIELD(vsloop,dt_out->fields)) + switch (vsloop) { + case KADM_NAME: + if ((status = stv_string(dt_in, dt_out->name, stsize, + sizeof(dt_out->name), maxlen)) < 0) + return(-1); + stsize += status; + break; + case KADM_INST: + if ((status = stv_string(dt_in, dt_out->instance, stsize, + sizeof(dt_out->instance), maxlen)) < 0) + return(-1); + stsize += status; + break; + case KADM_EXPDATE: + if ((status = stv_long(dt_in, &dt_out->exp_date, stsize, + maxlen)) < 0) + return(-1); + stsize += status; + break; + case KADM_ATTR: + if ((status = stv_short(dt_in, &dt_out->attributes, stsize, + maxlen)) < 0) + return(-1); + stsize += status; + break; + case KADM_MAXLIFE: + if ((status = stv_char(dt_in, &dt_out->max_life, stsize, + maxlen)) < 0) + return(-1); + stsize += status; + break; + case KADM_DESKEY: + if ((status = stv_long(dt_in, &dt_out->key_high, stsize, + maxlen)) < 0) + return(-1); + stsize += status; + if ((status = stv_long(dt_in, &dt_out->key_low, stsize, + maxlen)) < 0) + return(-1); + stsize += status; + break; + default: + break; + } + return stsize; +} diff --git a/kerberosIV/kadm/kadm_supp.c b/kerberosIV/kadm/kadm_supp.c new file mode 100644 index 00000000000..e195c512a62 --- /dev/null +++ b/kerberosIV/kadm/kadm_supp.c @@ -0,0 +1,126 @@ +/* $Id: kadm_supp.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Support functions for Kerberos administration server & clients + */ + +/* + kadm_supp.c + this holds the support routines for the kerberos administration server + + error: prints out a kadm error message, returns + fatal: prints out a kadm fatal error message, exits + prin_vals: prints out data associated with a Principal in the vals + structure +*/ + +#include "kadm_local.h" + +/* +prin_vals: + recieves : a vals structure +*/ +void +prin_vals(vals) + Kadm_vals *vals; +{ + printf("Info in Database for %s.%s:\n", vals->name, vals->instance); + printf(" Max Life: %d (%s) Exp Date: %s\n", + vals->max_life, + krb_life_to_atime(vals->max_life), + asctime(k_localtime(&vals->exp_date))); + printf(" Attribs: %.2x key: %lu %lu\n", + vals->attributes, + (long)vals->key_low, (long)vals->key_high); +} + +#ifdef notdef +nierror(s) +int s; +{ + printf("Kerberos admin server loses..... %s\n",error_message(s)); + return(s); +} +#endif + +/* kadm_prin_to_vals takes a fields arguments, a Kadm_vals and a Principal, + it copies the fields in Principal specified by fields into Kadm_vals, + i.e from old to new */ + +void +kadm_prin_to_vals(fields, new, old) + u_char *fields; + Kadm_vals *new; + Principal *old; +{ + bzero((char *)new, sizeof(*new)); + if (IS_FIELD(KADM_NAME,fields)) { + (void) strncpy(new->name, old->name, ANAME_SZ); + SET_FIELD(KADM_NAME, new->fields); + } + if (IS_FIELD(KADM_INST,fields)) { + (void) strncpy(new->instance, old->instance, INST_SZ); + SET_FIELD(KADM_INST, new->fields); + } + if (IS_FIELD(KADM_EXPDATE,fields)) { + new->exp_date = old->exp_date; + SET_FIELD(KADM_EXPDATE, new->fields); + } + if (IS_FIELD(KADM_ATTR,fields)) { + new->attributes = old->attributes; + SET_FIELD(KADM_ATTR, new->fields); + } + if (IS_FIELD(KADM_MAXLIFE,fields)) { + new->max_life = old->max_life; + SET_FIELD(KADM_MAXLIFE, new->fields); + } + if (IS_FIELD(KADM_DESKEY,fields)) { + new->key_low = old->key_low; + new->key_high = old->key_high; + SET_FIELD(KADM_DESKEY, new->fields); + } +} + +void +kadm_vals_to_prin(fields, new, old) + u_char *fields; + Principal *new; + Kadm_vals *old; +{ + + bzero((char *)new, sizeof(*new)); + if (IS_FIELD(KADM_NAME,fields)) + (void) strncpy(new->name, old->name, ANAME_SZ); + if (IS_FIELD(KADM_INST,fields)) + (void) strncpy(new->instance, old->instance, INST_SZ); + if (IS_FIELD(KADM_EXPDATE,fields)) + new->exp_date = old->exp_date; + if (IS_FIELD(KADM_ATTR,fields)) + new->attributes = old->attributes; + if (IS_FIELD(KADM_MAXLIFE,fields)) + new->max_life = old->max_life; + if (IS_FIELD(KADM_DESKEY,fields)) { + new->key_low = old->key_low; + new->key_high = old->key_high; + } +} diff --git a/kerberosIV/kadm/shlib_version b/kerberosIV/kadm/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/kadm/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/kadmin/Makefile b/kerberosIV/kadmin/Makefile new file mode 100644 index 00000000000..e24b6a28507 --- /dev/null +++ b/kerberosIV/kadmin/Makefile @@ -0,0 +1,31 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ + +PROG= kadmin +SRCS= kadmin.c kadmin_cmds.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +.if exists(${.CURDIR}/../kadm/obj) +CFLAGS+=-I${.CURDIR}/../kadm/obj +.else +CFLAGS+=-I${.CURDIR}/../kadm +.endif +.if exists(${.CURDIR}/../krb/obj) +CFLAGS+=-I${.CURDIR}/../krb/obj +.else +CFLAGS+=-I${.CURDIR}/../krb +.endif +.if exists(${.CURDIR}/../ss/obj) +CFLAGS+=-I${.CURDIR}/../ss/obj +.else +CFLAGS+=-I${.CURDIR}/../ss +.endif +LDADD+= -lkadm -lkrb -ldes -lss -lcom_err +DPADD+= ${LIBKADM} ${LIBKRB} ${LIBDES} ${LIBSS} ${LIBCOM_ERR} +CLEANFILES+= kadmin_cmds.c +MAN= kadmin.8 + +kadmin_cmds.c: kadmin_cmds.ct + test -e kadmin_cmds.ct || ln -s ${.CURDIR}/kadmin_cmds.ct . + ${MK_CMDS} kadmin_cmds.ct + -test -h kadmin_cmds.ct && rm kadmin_cmds.ct + +.include diff --git a/kerberosIV/kadmin/kadmin.8 b/kerberosIV/kadmin/kadmin.8 new file mode 100644 index 00000000000..8b22c75e9fd --- /dev/null +++ b/kerberosIV/kadmin/kadmin.8 @@ -0,0 +1,157 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kadmin.8,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ +.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/kerberosIV/kadmin/kadmin.c b/kerberosIV/kadmin/kadmin.c new file mode 100644 index 00000000000..e5581f5f71e --- /dev/null +++ b/kerberosIV/kadmin/kadmin.c @@ -0,0 +1,765 @@ +/* $Id: kadmin.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/* + * 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. + */ + +/* + * Kerberos database administrator's tool. + * + * The default behavior of kadmin is if the -m option is given + * on the commandline, multiple requests are allowed to be given + * with one entry of the admin password (until the tickets expire). + * If you do not want this to be an available option, compile with + * NO_MULTIPLE defined. + */ + +#include +#include + +#define BAD_PW 1 +#define GOOD_PW 0 +#define FUDGE_VALUE 15 /* for ticket expiration time */ +#define PE_NO 0 +#define PE_YES 1 +#define PE_UNSURE 2 + +/* for get_password, whether it should do the swapping...necessary for + using vals structure, unnecessary for change_pw requests */ +#define DONTSWAP 0 +#define SWAP 1 + +extern ss_request_table admin_cmds; + +static char myname[ANAME_SZ]; +static char default_realm[REALM_SZ]; /* default kerberos realm */ +static char krbrlm[REALM_SZ]; /* current realm being administered */ +static int multiple = 0; /* Allow multiple requests per ticket */ + +#ifdef NOENCRYPTION +#define read_long_pw_string placebo_read_pw_string +#else +#define read_long_pw_string des_read_pw_string +#endif + +static void +get_maxlife(Kadm_vals *vals) +{ + char buff[BUFSIZ]; + time_t life; + int l; + + do { + printf("Maximum ticket lifetime? (%d) [%s] ", + vals->max_life, krb_life_to_atime(vals->max_life)); + fflush(stdout); + if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') { + clearerr(stdin); + return; + } + life = krb_atime_to_life(buff); + } while (life <= 0); + + l = strlen(buff); + if (buff[l-2] == 'm') + life = krb_time_to_life(0L, life*60); + if (buff[l-2] == 'h') + life = krb_time_to_life(0L, life*60*60); + + vals->max_life = life; + SET_FIELD(KADM_MAXLIFE,vals->fields); +} + +static void +get_attr(Kadm_vals *vals) +{ + char buff[BUFSIZ], *out; + int attr; + + do { + printf("Attributes? [0x%.2x] ", vals->attributes); + fflush(stdout); + if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') { + clearerr(stdin); + return; + } + attr = strtol(buff, &out, 0); + if (attr == 0 && out == buff) + attr = -1; + } while (attr < 0 || attr > 0xffff); + + vals->attributes = attr; + SET_FIELD(KADM_ATTR,vals->fields); +} + +static void +get_expdate(Kadm_vals *vals) +{ + char buff[BUFSIZ]; + time_t when; + struct tm edate; + + bzero(&edate, sizeof(edate)); + do { + printf("Expiration date (enter yyyy-mm-dd) ? [%.24s] ", + asctime(k_localtime(&vals->exp_date))); + fflush(stdout); + if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') { + clearerr(stdin); + return; + } + if (sscanf(buff, "%d-%d-%d", + &edate.tm_year, &edate.tm_mon, &edate.tm_mday) == 3) { + 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 */ + when = maketime(&edate, 1); + } + } while (when <= 0); + + vals->exp_date = when; + SET_FIELD(KADM_EXPDATE,vals->fields); +} + +static int +princ_exists(char *name, char *instance, char *realm) +{ + int status; + + status = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm, 1, ""); + + if ((status == KSUCCESS) || (status == INTK_BADPW)) + return(PE_YES); + else if (status == KDC_PR_UNKNOWN) + return(PE_NO); + else + return(PE_UNSURE); +} + +static int +get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap) +{ + char new_passwd[MAX_KPW_LEN]; /* new password */ + des_cblock newkey; + + if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1)) + return(BAD_PW); + if (strlen(new_passwd) == 0) { + printf("Using random password.\n"); +#ifdef NOENCRYPTION + bzero((char *) newkey, sizeof(newkey)); +#else + des_new_random_key(&newkey); +#endif + } else { +#ifdef NOENCRYPTION + bzero((char *) newkey, sizeof(newkey)); +#else + des_string_to_key(new_passwd, &newkey); +#endif + bzero(new_passwd, sizeof(new_passwd)); + } + + bcopy((char *) newkey,(char *)low,4); + bcopy((char *)(((int32_t *) newkey) + 1), (char *)high,4); + + bzero((char *) newkey, sizeof(newkey)); + +#ifdef NOENCRYPTION + *low = 1; +#endif + + if (byteswap != DONTSWAP) { + *low = htonl(*low); + *high = htonl(*high); + } + return(GOOD_PW); +} + +static int +get_admin_password(void) +{ + int status; + char admin_passwd[MAX_KPW_LEN]; /* Admin's password */ + int ticket_life = 1; /* minimum ticket lifetime */ + CREDENTIALS c; + + if (multiple) { + /* If admin tickets exist and are valid, just exit. */ + bzero(&c, sizeof(c)); + if (krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c) == KSUCCESS) + /* + * If time is less than lifetime - FUDGE_VALUE after issue date, + * tickets will probably last long enough for the next + * transaction. + */ + if (time(0) < (c.issue_date + (5 * 60 * c.lifetime) - FUDGE_VALUE)) + return(KADM_SUCCESS); + ticket_life = DEFAULT_TKT_LIFE; + } + + if (princ_exists(myname, "admin", krbrlm) != PE_NO) { + if (read_long_pw_string(admin_passwd, sizeof(admin_passwd)-1, + "Admin password:", 0)) { + fprintf(stderr, "Error reading admin password.\n"); + goto bad; + } + status = krb_get_pw_in_tkt(myname, "admin", krbrlm, PWSERV_NAME, + KADM_SINST, ticket_life, admin_passwd); + bzero(admin_passwd, sizeof(admin_passwd)); + + /* Initialize non shared random sequence from session key. */ + bzero(&c, sizeof(c)); + krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c); + des_init_random_number_generator(&c.session); + } + else + status = KDC_PR_UNKNOWN; + + switch(status) { + case GT_PW_OK: + return(GOOD_PW); + case KDC_PR_UNKNOWN: + printf("Principal %s.admin@%s does not exist.\n", myname, krbrlm); + goto bad; + case GT_PW_BADPW: + printf("Incorrect admin password.\n"); + goto bad; + default: + com_err("kadmin", status+krb_err_base, + "while getting password tickets"); + goto bad; + } + + bad: + bzero(admin_passwd, sizeof(admin_passwd)); + (void) dest_tkt(); + return(BAD_PW); +} + +static void +usage(void) +{ + fprintf(stderr, "Usage: kadmin [-u admin_name] [-r default_realm]"); + fprintf(stderr, " [-m]"); + fprintf(stderr, "\n"); + fprintf(stderr, " -m allows multiple admin requests to be "); + fprintf(stderr, "serviced with one entry of admin\n"); + fprintf(stderr, " password.\n"); + exit(1); +} + +/* GLOBAL */ +void +clean_up(void) +{ + (void) dest_tkt(); + return; +} + +/* GLOBAL */ +void +quit(void) +{ + printf("Cleaning up and exiting.\n"); + clean_up(); + exit(0); +} + +static int inited = 0; + +static void +do_init(int argc, char **argv) +{ + struct passwd *pw; + int c; +#define OPTION_STRING "u:r:m" + + bzero(myname, sizeof(myname)); + + if (!inited) { + /* + * This is only as a default/initial realm; we don't care + * about failure. + */ + if (krb_get_lrealm(default_realm, 1) != KSUCCESS) + strcpy(default_realm, KRB_REALM); + + /* + * If we can reach the local realm, initialize to it. Otherwise, + * don't initialize. + */ + if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS) + bzero(krbrlm, sizeof(krbrlm)); + else + strcpy(krbrlm, default_realm); + + while ((c = getopt(argc, argv, OPTION_STRING)) != EOF) + switch (c) { + case 'u': + strncpy(myname, optarg, sizeof(myname) - 1); + break; + case 'r': + bzero(default_realm, sizeof(default_realm)); + strncpy(default_realm, optarg, sizeof(default_realm) - 1); + break; + case 'm': + multiple++; + break; + default: + usage(); + break; + } + if (optind < argc) + usage(); + if (!myname[0]) { + pw = getpwuid((int) getuid()); + if (!pw) { + fprintf(stderr, + "You aren't in the password file. Who are you?\n"); + exit(1); + } + (void) strcpy(myname, pw->pw_name); + } + inited = 1; + } +} + +int +main(int argc, char **argv) +{ + int sci_idx; + int code; + char tktstring[MAXPATHLEN]; + + sci_idx = ss_create_invocation("admin", "2.0", (char *) NULL, + &admin_cmds, &code); + if (code) { + ss_perror(sci_idx, code, "creating invocation"); + exit(1); + } + (void) sprintf(tktstring, "/tmp/tkt_adm_%d",(int)getpid()); + krb_set_tkt_string(tktstring); + + do_init(argc, argv); + + printf("Welcome to the Kerberos Administration Program, version 2\n"); + printf("Type \"help\" if you need it.\n"); + code = ss_listen(sci_idx); + printf("\n"); + quit(); + exit(0); +} + +static int +setvals(Kadm_vals *vals, char *string) +{ + char realm[REALM_SZ]; + int status = KADM_SUCCESS; + + bzero(vals, sizeof(*vals)); + bzero(realm, sizeof(realm)); + + SET_FIELD(KADM_NAME,vals->fields); + SET_FIELD(KADM_INST,vals->fields); + if ((status = kname_parse(vals->name, vals->instance, realm, string))) { + printf("kerberos error: %s\n", krb_err_txt[status]); + return status; + } + if (!realm[0]) + strcpy(realm, default_realm); + if (strcmp(realm, krbrlm)) { + strcpy(krbrlm, realm); + if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm)) + != KADM_SUCCESS) + printf("kadm error for realm %s: %s\n", + krbrlm, error_message(status)); + } + if (status) + return 1; + else + return KADM_SUCCESS; +} + +void +change_password(int argc, char **argv) +{ + Kadm_vals old, new; + int status; + char pw_prompt[BUFSIZ]; + + if (argc != 2) { + printf("Usage: change_password loginname\n"); + return; + } + + if (setvals(&old, argv[1]) != KADM_SUCCESS) + return; + + new = old; + + SET_FIELD(KADM_DESKEY,new.fields); + + if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) { + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return; + + /* get the new password */ + (void) sprintf(pw_prompt, "New password for %s:", argv[1]); + + if (get_password(&new.key_low, &new.key_high, + pw_prompt, SWAP) == GOOD_PW) { + status = kadm_mod(&old, &new); + if (status == KADM_SUCCESS) { + printf("Password changed for %s.\n", argv[1]); + } else { + printf("kadmin: %s\nwhile changing password for %s", + error_message(status), argv[1]); + } + } else + printf("Error reading password; password unchanged\n"); + bzero((char *)&new, sizeof(new)); + if (!multiple) + clean_up(); + } + else + printf("kadmin: Principal does not exist.\n"); + return; +} + +/*ARGSUSED*/ +void +change_admin_password(int argc, char **argv) +{ + des_cblock newkey; + u_int32_t low, high; + int status; + char prompt_pw[BUFSIZ]; + + if (argc != 1) { + printf("Usage: change_admin_password\n"); + return; + } + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return; + + (void) sprintf(prompt_pw, "New password for %s.admin:",myname); + if (get_password(&low, &high, prompt_pw, DONTSWAP) == GOOD_PW) { + bcopy((char *)&low,(char *) newkey,4); + bcopy((char *)&high, (char *)(((int32_t *) newkey) + 1),4); + low = high = 0L; + if ((status = kadm_change_pw(newkey)) == KADM_SUCCESS) + printf("Admin password changed\n"); + else + printf("kadm error: %s\n",error_message(status)); + bzero((char *)newkey, sizeof(newkey)); + } else + printf("Error reading password; password unchanged\n"); + if (!multiple) + clean_up(); + return; +} + +void +add_new_key(int argc, char **argv) +{ + Kadm_vals new; + char pw_prompt[BUFSIZ]; + int status; + + if (argc != 2) { + printf("Usage: add_new_key user_name.\n"); + return; + } + if (setvals(&new, argv[1]) != KADM_SUCCESS) + return; + + SET_FIELD(KADM_DESKEY,new.fields); + + if (princ_exists(new.name, new.instance, krbrlm) != PE_YES) { + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return; + + /* This is the default maximum lifetime for new principals. */ + if (krb_life_to_time(0, 162) >= 24*60*60) + new.max_life = 162; /* ca 100 hours */ + else + new.max_life = 255; /* ca 21 hours (maximum) */ + new.exp_date = time(0) + 2*(365*24*60*60); /* + ca 2 years */ + new.attributes = 0; + get_maxlife(&new); + get_attr(&new); + get_expdate(&new); + + /* get the new password */ + (void) sprintf(pw_prompt, "Password for %s:", argv[1]); + + if (get_password(&new.key_low, &new.key_high, + pw_prompt, SWAP) == GOOD_PW) { + status = kadm_add(&new); + if (status == KADM_SUCCESS) { + printf("%s added to database.\n", argv[1]); + } else { + printf("kadm error: %s\n",error_message(status)); + } + } else + printf("Error reading password; %s not added\n",argv[1]); + bzero((char *)&new, sizeof(new)); + if (!multiple) + clean_up(); + } + else + printf("kadmin: Principal already exists.\n"); + return; +} + +void +get_entry(int argc, char **argv) +{ + int status; + u_char fields[4]; + Kadm_vals vals; + + if (argc != 2) { + printf("Usage: get_entry username\n"); + return; + } + + bzero(fields, sizeof(fields)); + + SET_FIELD(KADM_NAME,fields); + SET_FIELD(KADM_INST,fields); + SET_FIELD(KADM_EXPDATE,fields); + SET_FIELD(KADM_ATTR,fields); + SET_FIELD(KADM_MAXLIFE,fields); + + if (setvals(&vals, argv[1]) != KADM_SUCCESS) + return; + + + if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) { + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return; + + if ((status = kadm_get(&vals, fields)) == KADM_SUCCESS) + prin_vals(&vals); + else + printf("kadm error: %s\n",error_message(status)); + + if (!multiple) + clean_up(); + } + else + printf("kadmin: Principal does not exist.\n"); + return; +} + +void +mod_entry(int argc, char **argv) +{ + int status; + u_char fields[4]; + Kadm_vals ovals, nvals; + + if (argc != 2) { + printf("Usage: mod_entry username\n"); + return; + } + + bzero(fields, sizeof(fields)); + + SET_FIELD(KADM_NAME,fields); + SET_FIELD(KADM_INST,fields); + SET_FIELD(KADM_EXPDATE,fields); + SET_FIELD(KADM_ATTR,fields); + SET_FIELD(KADM_MAXLIFE,fields); + + if (setvals(&ovals, argv[1]) != KADM_SUCCESS) + return; + + nvals = ovals; + + if (princ_exists(ovals.name, ovals.instance, krbrlm) == PE_NO) { + printf("kadmin: Principal does not exist.\n"); + return; + } + + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return; + + if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) { + printf("[ unable to retrieve current settings: %s ]\n", + error_message(status)); + nvals.max_life = DEFAULT_TKT_LIFE; + nvals.exp_date = 0; + nvals.attributes = 0; + } else { + nvals.max_life = ovals.max_life; + nvals.exp_date = ovals.exp_date; + nvals.attributes = ovals.attributes; + } + + get_maxlife(&nvals); + get_attr(&nvals); + get_expdate(&nvals); + + if (IS_FIELD(KADM_MAXLIFE, nvals.fields) || IS_FIELD(KADM_ATTR, nvals.fields) || IS_FIELD(KADM_EXPDATE, nvals.fields)) { + if ((status = kadm_mod(&ovals, &nvals)) != KADM_SUCCESS) { + printf("kadm error: %s\n",error_message(status)); + goto out; + } + if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) { + printf("kadm error: %s\n",error_message(status)); + goto out; + } + } + prin_vals(&ovals); + +out: + if (!multiple) + clean_up(); + return; +} + +void +help(int argc, char **argv) +{ + if (argc == 1) { + printf("Welcome to the Kerberos administration program."); + printf("Type \"?\" to get\n"); + printf("a list of requests that are available. You can"); + printf(" get help on each of\n"); + printf("the commands by typing \"help command_name\"."); + printf(" Some functions of this\n"); + printf("program will require an \"admin\" password"); + printf(" from you. This is a password\n"); + printf("private to you, that is used to authenticate"); + printf(" requests from this\n"); + printf("program. You can change this password with"); + printf(" the \"change_admin_password\"\n"); + printf("(or short form \"cap\") command. Good Luck! \n"); + } else if (!strcmp(argv[1], "change_password") || + !strcmp(argv[1], "cpw")) { + printf("Usage: change_password user_name.\n"); + printf("\n"); + printf("user_name is the name of the user whose password"); + printf(" you wish to change. \n"); + printf("His/her password is changed in the kerberos database\n"); + printf("When this command is issued, first the \"Admin\""); + printf(" password will be prompted\n"); + printf("for and if correct the user's new password will"); + printf(" be prompted for (twice with\n"); + printf("appropriate comparison). Note: No minimum password"); + printf(" length restrictions apply, but\n"); + printf("longer passwords are more secure.\n"); + } else if (!strcmp(argv[1], "change_admin_password") || + !strcmp(argv[1], "cap")) { + printf("Usage: change_admin_password.\n"); + printf("\n"); + printf("This command takes no arguments and is used"); + printf(" to change your private\n"); + printf("\"Admin\" password. It will first prompt for"); + printf(" the (current) \"Admin\"\n"); + printf("password and then ask for the new password"); + printf(" by prompting:\n"); + printf("\n"); + printf("New password for .admin:\n"); + printf("\n"); + printf("Enter the new admin password that you desire"); + printf(" (it will be asked for\n"); + printf("twice to avoid errors).\n"); + } else if (!strcmp(argv[1], "add_new_key") || + !strcmp(argv[1], "ank")) { + printf("Usage: add_new_key user_name.\n"); + printf("\n"); + printf("user_name is the name of a new user to put"); + printf(" in the kerberos database. Your\n"); + printf("\"Admin\" password and the user's password"); + printf(" are prompted for. The user's\n"); + printf("password will be asked for"); + printf(" twice to avoid errors.\n"); + printf("You are also prompted for the default ticket"); + printf(" lifetime, attributes\n"); + printf("and expiration date (see the 'mod_entry' command).\n"); + } else if (!strcmp(argv[1], "get_entry") || + !strcmp(argv[1], "get")) { + printf("Usage: get_entry user_name.\n"); + printf("\n"); + printf("user_name is the name of a user whose"); + printf(" entry you wish to review. Your\n"); + printf("\"Admin\" password is prompted for. "); + printf(" The key field is not filled in, for\n"); + printf("security reasons.\n"); + } else if (!strcmp(argv[1], "mod_entry") || + !strcmp(argv[1], "mod")) { + printf("Usage: mod_entry user_name.\n"); + printf("\n"); + printf("user_name is the name of a user whose"); + printf(" entry you wish to modify. Your\n"); + printf("\"Admin\" password is prompted for."); + printf(" You will also be prompted for the new\n"); + printf("default ticket lifetime, attributes"); + printf(" and expiration date. Attributes may\n"); + printf("be entered in decimal by default,"); + printf(" octal if begun with '0', or hexadecimal\n"); + printf("if begun with '0x'. End the lifetime"); + printf(" with 'm' to specify minutes, 'h'\n"); + printf("to specify hours.\n"); + } else if (!strcmp(argv[1], "destroy_tickets") || + !strcmp(argv[1], "dest")) { + printf("Usage: destroy_tickets\n"); + printf("\n"); + printf("Destroy your admin tickets. This will"); + printf(" cause you to be prompted for your\n"); + printf("admin password on your next request.\n"); + } else if (!strcmp(argv[1], "list_requests") || + !strcmp(argv[1], "lr") || + !strcmp(argv[1], "?")) { + printf("Usage: list_requests\n"); + printf("\n"); + printf("This command lists what other commands are"); + printf(" currently available.\n"); + } else if (!strcmp(argv[1], "exit") || + !strcmp(argv[1], "quit") || + !strcmp(argv[1], "q")) { + printf("Usage: quit\n"); + printf("\n"); + printf("This command exits this program.\n"); + } else { + printf("Sorry there is no such command as %s.", argv[1]); + printf(" Type \"help\" for more information. \n"); + } + return; +} +#if 0 +static void +go_home(str,x) +char *str; +int x; +{ + fprintf(stderr, "%s: %s\n", str, error_message(x)); + clean_up(); + exit(1); +} +#endif diff --git a/kerberosIV/kadmin/kadmin_cmds.ct b/kerberosIV/kadmin/kadmin_cmds.ct new file mode 100644 index 00000000000..af6202113f2 --- /dev/null +++ b/kerberosIV/kadmin/kadmin_cmds.ct @@ -0,0 +1,52 @@ +# $Id: kadmin_cmds.ct,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ + +#- +# Copyright 1988 by 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. + +# Command table for Kerberos administration tool + + command_table admin_cmds; + + request change_password, + "Change a user's password", + change_password, cpw; + + request change_admin_password, "Change your admin password", + change_admin_password, cap; + + request add_new_key, "Add new user to kerberos database", + add_new_key, ank; + + request get_entry, "Get entry from kerberos database", + get_entry, get; + + request mod_entry, "Modify entry in kerberos database", + mod_entry, mod; + + request clean_up, "Destroy admin tickets", + destroy_tickets, dest; + + request help,"Request help with this program", + help; + +# list_requests is generic -- unrelated to Kerberos + + request ss_list_requests, "List available requests.", + list_requests, lr, "?"; + + request quit, "Exit program.", + quit, exit, q; + + end; diff --git a/kerberosIV/kadmind/Makefile b/kerberosIV/kadmind/Makefile new file mode 100644 index 00000000000..0d008eef87c --- /dev/null +++ b/kerberosIV/kadmind/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ + +PROG= kadmind +SRCS= admin_server.c kadm_funcs.c kadm_ser_wrap.c kadm_server.c +.if exists(${.CURDIR}/../kadm/obj) +CFLAGS+=-I${.CURDIR}/../kadm/obj +.else +CFLAGS+=-I${.CURDIR}/../kadm +.endif +.if exists(${.CURDIR}/../krb/obj) +CFLAGS+=-I${.CURDIR}/../krb/obj +.else +CFLAGS+=-I${.CURDIR}/../krb +.endif +.if exists(${.CURDIR}/../ss/obj) +CFLAGS+=-I${.CURDIR}/../ss/obj +.else +CFLAGS+=-I${.CURDIR}/../ss +.endif +LDADD+= -lkadm -lkdb -lkrb -ldes -lacl -lcom_err +DPADD= ${LIBKADM} ${LIBKDB} ${LIBKRB} ${LIBDES} ${LIBACL} ${LIBCOM_ERR} +MAN= kadmind.8 +BINDIR=/usr/libexec + +.include diff --git a/kerberosIV/kadmind/admin_server.c b/kerberosIV/kadmind/admin_server.c new file mode 100644 index 00000000000..d184f9287dd --- /dev/null +++ b/kerberosIV/kadmind/admin_server.c @@ -0,0 +1,448 @@ +/* $Id: admin_server.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Top-level loop of the kerberos Administration server + */ + +/* + admin_server.c + this holds the main loop and initialization and cleanup code for the server +*/ + +#include + +/* Almost all procs and such need this, so it is global */ +admin_params prm; /* The command line parameters struct */ + +static char prog[32]; /* WHY IS THIS NEEDED??????? */ +char *progname = prog; +/* GLOBAL */ +char *acldir = DEFAULT_ACL_DIR; +static char krbrlm[REALM_SZ]; + +static unsigned pidarraysize = 0; +static int *pidarray = (int *)0; + +static exit_now = 0; + +static void +doexit() +{ + exit_now = 1; +#ifndef sgi /* Sigh -- sgi cc balks at this... */ + return (void)(0); +#endif +} + +static void +do_child() +{ + /* SIGCHLD brings us here */ + int pid; + register int i, j; + + int status; + + pid = wait(&status); + + for (i = 0; i < pidarraysize; i++) + if (pidarray[i] == pid) { + /* found it */ + for (j = i; j < pidarraysize-1; j++) + /* copy others down */ + pidarray[j] = pidarray[j+1]; + pidarraysize--; + if (WIFEXITED(status) || WIFSIGNALED(status)) + log("child %d: termsig %d, retcode %d", pid, + WTERMSIG(status), WEXITSTATUS(status)); +#ifndef sgi + return (void)(0); +#endif + } + log("child %d not in list: termsig %d, retcode %d", pid, + WTERMSIG(status), WEXITSTATUS(status)); +#ifndef sgi + return (void)(0); +#endif +} + +static int nSIGCHLD = 0; + +static void +count_SIGCHLD() +{ + nSIGCHLD++; +#ifndef sgi + return (void)(0); +#endif +} + +static void +kill_children(void) +{ + int i; + void (*ofunc)(); + + ofunc = signal(SIGCHLD, count_SIGCHLD); + + for (i = 0; i < pidarraysize; i++) { + kill(pidarray[i], SIGINT); + log("killing child %d", pidarray[i]); + } + + (void) signal(SIGCHLD, ofunc); + + for (; nSIGCHLD != 0; nSIGCHLD--) + do_child(); + + return; +} + +/* close the system log file */ +static void +close_syslog(void) +{ + log("Shutting down admin server"); +} + +static void +byebye(void) /* say goodnight gracie */ +{ + printf("Admin Server (kadm server) has completed operation.\n"); +} + +static void +clear_secrets(void) +{ + bzero((char *)server_parm.master_key, sizeof(server_parm.master_key)); + bzero((char *)server_parm.master_key_schedule, + sizeof(server_parm.master_key_schedule)); + server_parm.master_key_version = 0L; + return; +} + +#ifdef DEBUG +#define cleanexit(code) {kerb_fini(); return;} +#endif + +#ifndef DEBUG +static void +cleanexit(int val) +{ + kerb_fini(); + clear_secrets(); + exit(val); +} +#endif + +static void +process_client(int fd, struct sockaddr_in *who) +{ + u_char *dat; + int dat_len; + u_short dlen; + int retval; + int on = 1; + Principal service; + des_cblock skey; + int more; + int status; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) + log("setsockopt keepalive: %d",errno); + + server_parm.recv_addr = *who; + + if (kerb_init()) { /* Open as client */ + log("can't open krb db"); + cleanexit(1); + } + /* need to set service key to changepw.KRB_MASTER */ + + status = kerb_get_principal(server_parm.sname, server_parm.sinst, &service, + 1, &more); + if (status == -1) { + /* db locked */ + u_long retcode = KADM_DB_INUSE; + char *pdat; + + dat_len = KADM_VERSIZE + sizeof(u_long); + dat = (u_char *) malloc((unsigned)dat_len); + pdat = (char *) dat; + retcode = htonl((u_long) KADM_DB_INUSE); + (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE); + bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_long)); + goto out; + } else if (!status) { + log("no service %s.%s",server_parm.sname, server_parm.sinst); + cleanexit(2); + } + + bcopy((char *)&service.key_low, (char *)skey, 4); + bcopy((char *)&service.key_high, (char *)(((long *) skey) + 1), 4); + bzero((char *)&service, sizeof(service)); + kdb_encrypt_key (&skey, &skey, &server_parm.master_key, + server_parm.master_key_schedule, DES_DECRYPT); + (void) krb_set_key((char *)skey, 0); /* if error, will show up when + rd_req fails */ + bzero((char *)skey, sizeof(skey)); + + while (1) { + if ((retval = krb_net_read(fd, (char *)&dlen, sizeof(u_short))) != + sizeof(u_short)) { + if (retval < 0) + log("dlen read: %s",error_message(errno)); + else if (retval) + log("short dlen read: %d",retval); + (void) close(fd); + cleanexit(retval ? 3 : 0); + } + if (exit_now) { + cleanexit(0); + } + dat_len = (int) ntohs(dlen); + dat = (u_char *) malloc((unsigned)dat_len); + if (!dat) { + log("malloc: No memory"); + (void) close(fd); + cleanexit(4); + } + if ((retval = krb_net_read(fd, (char *)dat, dat_len)) != dat_len) { + if (retval < 0) + log("data read: %s",error_message(errno)); + else + log("short read: %d vs. %d", dat_len, retval); + (void) close(fd); + cleanexit(5); + } + if (exit_now) { + cleanexit(0); + } + if ((retval = kadm_ser_in(&dat,&dat_len)) != KADM_SUCCESS) + log("processing request: %s", error_message(retval)); + + /* kadm_ser_in did the processing and returned stuff in + dat & dat_len , return the appropriate data */ + + out: + dlen = (u_short) dat_len; + + if (dat_len != (int)dlen) { + clear_secrets(); + abort(); /* XXX */ + } + dlen = htons(dlen); + + if (krb_net_write(fd, (char *)&dlen, sizeof(u_short)) < 0) { + log("writing dlen to client: %s",error_message(errno)); + (void) close(fd); + cleanexit(6); + } + + if (krb_net_write(fd, (char *)dat, dat_len) < 0) { + log(LOG_ERR, "writing to client: %s",error_message(errno)); + (void) close(fd); + cleanexit(7); + } + free((char *)dat); + } + /*NOTREACHED*/ +} + +/* +kadm_listen +listen on the admin servers port for a request +*/ +static int +kadm_listen(void) +{ + int found; + int admin_fd; + int peer_fd; + fd_set mask, readfds; + struct sockaddr_in peer; + int addrlen; + int pid; + + (void) signal(SIGINT, doexit); + (void) signal(SIGTERM, doexit); + (void) signal(SIGHUP, doexit); + (void) signal(SIGQUIT, doexit); + (void) signal(SIGPIPE, SIG_IGN); /* get errors on write() */ + (void) signal(SIGALRM, doexit); + (void) signal(SIGCHLD, do_child); + + if ((admin_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return KADM_NO_SOCK; + if (bind(admin_fd, (struct sockaddr *)&server_parm.admin_addr, + sizeof(struct sockaddr_in)) < 0) + return KADM_NO_BIND; + (void) listen(admin_fd, 1); + FD_ZERO(&mask); + FD_SET(admin_fd, &mask); + + for (;;) { /* loop nearly forever */ + if (exit_now) { + clear_secrets(); + kill_children(); + return(0); + } + readfds = mask; + if ((found = select(admin_fd+1,&readfds,(fd_set *)0, + (fd_set *)0, (struct timeval *)0)) == 0) + continue; /* no things read */ + if (found < 0) { + if (errno != EINTR) + log("select: %s",error_message(errno)); + continue; + } + if (FD_ISSET(admin_fd, &readfds)) { + /* accept the conn */ + addrlen = sizeof(peer); + if ((peer_fd = accept(admin_fd, (struct sockaddr *)&peer, + &addrlen)) < 0) { + log("accept: %s",error_message(errno)); + continue; + } +#ifndef DEBUG + /* if you want a sep daemon for each server */ + if ((pid = fork())) { + /* parent */ + if (pid < 0) { + log("fork: %s",error_message(errno)); + (void) close(peer_fd); + continue; + } + /* fork succeded: keep tabs on child */ + (void) close(peer_fd); + if (pidarray) { + pidarray = (int *)realloc((char *)pidarray, ++pidarraysize); + pidarray[pidarraysize-1] = pid; + } else { + pidarray = (int *)malloc(pidarraysize = 1); + pidarray[0] = pid; + } + } else { + /* child */ + (void) close(admin_fd); +#endif /* DEBUG */ + /* do stuff */ + process_client (peer_fd, &peer); +#ifndef DEBUG + } +#endif + } else { + log("something else woke me up!"); + return(0); + } + } + /*NOTREACHED*/ +} + +/* +** Main does the logical thing, it sets up the database and RPC interface, +** as well as handling the creation and maintenance of the syslog file... +*/ +int +main(int argc, char **argv) /* admin_server main routine */ + + +{ + int errval; + int c; + + prog[sizeof(prog)-1]='\0'; /* Terminate... */ + (void) strncpy(prog, argv[0], sizeof(prog)-1); + + /* initialize the admin_params structure */ + prm.sysfile = KADM_SYSLOG; /* default file name */ + prm.inter = 1; + + bzero(krbrlm, sizeof(krbrlm)); + + while ((c = getopt(argc, argv, "f:hnd:a:r:")) != EOF) + switch(c) { + case 'f': /* Syslog file name change */ + prm.sysfile = optarg; + break; + case 'n': + prm.inter = 0; + break; + case 'a': /* new acl directory */ + acldir = optarg; + break; + case 'd': + /* put code to deal with alt database place */ + if ((errval = kerb_db_set_name(optarg))) { + fprintf(stderr, "opening database %s: %s", + optarg, error_message(errval)); + exit(1); + } + break; + case 'r': + (void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1); + break; + case 'h': /* get help on using admin_server */ + default: + printf("Usage: admin_server [-h] [-n] [-r realm] [-d dbname] [-f filename] [-a acldir]\n"); + exit(-1); /* failure */ + } + + if (krbrlm[0] == 0) + if (krb_get_lrealm(krbrlm, 0) != KSUCCESS) { + fprintf(stderr, + "Unable to get local realm. Fix krb.conf or use -r.\n"); + exit(1); + } + + printf("KADM Server %s initializing\n",KADM_VERSTR); + printf("Please do not use 'kill -9' to kill this job, use a\n"); + printf("regular kill instead\n\n"); + + set_logfile(prm.sysfile); + log("Admin server starting"); + + (void) kerb_db_set_lockmode(KERB_DBL_NONBLOCKING); + errval = kerb_init(); /* Open the Kerberos database */ + if (errval) { + fprintf(stderr, "error: kerb_init() failed"); + close_syslog(); + byebye(); + } + /* set up the server_parm struct */ + if ((errval = kadm_ser_init(prm.inter, krbrlm))==KADM_SUCCESS) { + kerb_fini(); /* Close the Kerberos database-- + will re-open later */ + errval = kadm_listen(); /* listen for calls to server from + clients */ + } + if (errval != KADM_SUCCESS) { + fprintf(stderr,"error: %s\n",error_message(errval)); + kerb_fini(); /* Close if error */ + } + close_syslog(); /* Close syslog file, print + closing note */ + byebye(); /* Say bye bye on the terminal + in use */ + exit(1); +} /* procedure main */ diff --git a/kerberosIV/kadmind/kadm_funcs.c b/kerberosIV/kadmind/kadm_funcs.c new file mode 100644 index 00000000000..5bed94d0591 --- /dev/null +++ b/kerberosIV/kadmind/kadm_funcs.c @@ -0,0 +1,371 @@ +/* $Id: kadm_funcs.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Kerberos administration server-side database manipulation routines + */ + +/* +kadm_funcs.c +the actual database manipulation code +*/ + +#include +#include + +static int +check_access(char *pname, char *pinst, char *prealm, enum acl_types acltype) +{ + char checkname[MAX_K_NAME_SZ]; + char filename[MAXPATHLEN]; + + (void) sprintf(checkname, "%s.%s@%s", pname, pinst, prealm); + + switch (acltype) { + case ADDACL: + (void) sprintf(filename, "%s%s", acldir, ADD_ACL_FILE); + break; + case GETACL: + (void) sprintf(filename, "%s%s", acldir, GET_ACL_FILE); + break; + case MODACL: + (void) sprintf(filename, "%s%s", acldir, MOD_ACL_FILE); + break; + } + return(acl_check(filename, checkname)); +} + +static int +wildcard(char *str) +{ + if (!strcmp(str, WILDCARD_STR)) + return(1); + return(0); +} + +#define failadd(code) { (void) log("FAILED addding '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; } + +int +kadm_add_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin, Kadm_vals *valsout) + /* requestors name */ + /* requestors instance */ + /* requestors realm */ + + +{ + long numfound; /* check how many we get written */ + int more; /* pointer to more grabbed records */ + Principal data_i, data_o; /* temporary principal */ + u_char flags[4]; + des_cblock newpw; + Principal default_princ; + + if (!check_access(rname, rinstance, rrealm, ADDACL)) { + (void) log("WARNING: '%s.%s@%s' tried to add an entry for '%s.%s'", + rname, rinstance, rrealm, valsin->name, valsin->instance); + return KADM_UNAUTH; + } + + /* Need to check here for "legal" name and instance */ + if (wildcard(valsin->name) || wildcard(valsin->instance)) { + failadd(KADM_ILL_WILDCARD); + } + + (void) log("request to add an entry for '%s.%s' from '%s.%s@%s'", + valsin->name, valsin->instance, rname, rinstance, rrealm); + + numfound = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + if (numfound == -1) { + failadd(KADM_DB_INUSE); + } else if (numfound != 1) { + failadd(KADM_UK_RERROR); + } + + kadm_vals_to_prin(valsin->fields, &data_i, valsin); + (void) strncpy(data_i.name, valsin->name, ANAME_SZ); + (void) strncpy(data_i.instance, valsin->instance, INST_SZ); + + if (!IS_FIELD(KADM_EXPDATE,valsin->fields)) + data_i.exp_date = default_princ.exp_date; + if (!IS_FIELD(KADM_ATTR,valsin->fields)) + data_i.attributes = default_princ.attributes; + if (!IS_FIELD(KADM_MAXLIFE,valsin->fields)) + data_i.max_life = default_princ.max_life; + + bzero((char *)&default_princ, sizeof(default_princ)); + + /* convert to host order */ + data_i.key_low = ntohl(data_i.key_low); + data_i.key_high = ntohl(data_i.key_high); + + + bcopy(&data_i.key_low,newpw,4); + bcopy(&data_i.key_high,(char *)(((long *) newpw) + 1),4); + + /* encrypt new key in master key */ + kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key, + server_parm.master_key_schedule, DES_ENCRYPT); + bcopy(newpw,&data_i.key_low,4); + bcopy((char *)(((long *) newpw) + 1), &data_i.key_high,4); + bzero((char *)newpw, sizeof(newpw)); + + data_o = data_i; + numfound = kerb_get_principal(valsin->name, valsin->instance, + &data_o, 1, &more); + if (numfound == -1) { + failadd(KADM_DB_INUSE); + } else if (numfound) { + failadd(KADM_INUSE); + } else { + data_i.key_version++; + data_i.kdc_key_ver = server_parm.master_key_version; + (void) strncpy(data_i.mod_name, rname, sizeof(data_i.mod_name)-1); + (void) strncpy(data_i.mod_instance, rinstance, + sizeof(data_i.mod_instance)-1); + + numfound = kerb_put_principal(&data_i, 1); + if (numfound == -1) { + failadd(KADM_DB_INUSE); + } else if (numfound) { + failadd(KADM_UK_SERROR); + } else { + numfound = kerb_get_principal(valsin->name, valsin->instance, + &data_o, 1, &more); + if ((numfound!=1) || (more!=0)) { + failadd(KADM_UK_RERROR); + } + bzero((char *)flags, sizeof(flags)); + SET_FIELD(KADM_NAME,flags); + SET_FIELD(KADM_INST,flags); + SET_FIELD(KADM_EXPDATE,flags); + SET_FIELD(KADM_ATTR,flags); + SET_FIELD(KADM_MAXLIFE,flags); + kadm_prin_to_vals(flags, valsout, &data_o); + (void) log("'%s.%s' added.", valsin->name, valsin->instance); + return KADM_DATA; /* Set all the appropriate fields */ + } + } +} +#undef failadd + +#define failget(code) { (void) log("FAILED retrieving '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; } + +int +kadm_get_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin, u_char *flags, Kadm_vals *valsout) + /* requestors name */ + /* requestors instance */ + /* requestors realm */ + /* what they wannt to get */ + /* which fields we want */ + /* what data is there */ +{ + long numfound; /* check how many were returned */ + int more; /* To point to more name.instances */ + Principal data_o; /* Data object to hold Principal */ + + + if (!check_access(rname, rinstance, rrealm, GETACL)) { + (void) log("WARNING: '%s.%s@%s' tried to get '%s.%s's entry", + rname, rinstance, rrealm, valsin->name, valsin->instance); + return KADM_UNAUTH; + } + + if (wildcard(valsin->name) || wildcard(valsin->instance)) { + failget(KADM_ILL_WILDCARD); + } + + (void) log("retrieve '%s.%s's entry for '%s.%s@%s'", + valsin->name, valsin->instance, rname, rinstance, rrealm); + + /* Look up the record in the database */ + numfound = kerb_get_principal(valsin->name, valsin->instance, + &data_o, 1, &more); + if (numfound == -1) { + failget(KADM_DB_INUSE); + } else if (numfound) { /* We got the record, let's return it */ + kadm_prin_to_vals(flags, valsout, &data_o); + (void) log("'%s.%s' retrieved.", valsin->name, valsin->instance); + return KADM_DATA; /* Set all the appropriate fields */ + } else { + failget(KADM_NOENTRY); /* Else whimper and moan */ + } +} +#undef failget + +#define failmod(code) { (void) log("FAILED modifying '%s.%s' (%s)", valsin1->name, valsin1->instance, error_message(code)); return code; } + +int +kadm_mod_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin1, Kadm_vals *valsin2, Kadm_vals *valsout) + /* requestors name */ + /* requestors instance */ + /* requestors realm */ + /* holds the parameters being + passed in */ + /* the actual record which is returned */ +{ + long numfound; + int more; + Principal data_o, temp_key; + u_char fields[4]; + des_cblock newpw; + + if (wildcard(valsin1->name) || wildcard(valsin1->instance)) { + failmod(KADM_ILL_WILDCARD); + } + + if (!check_access(rname, rinstance, rrealm, MODACL)) { + (void) log("WARNING: '%s.%s@%s' tried to change '%s.%s's entry", + rname, rinstance, rrealm, valsin1->name, valsin1->instance); + return KADM_UNAUTH; + } + + (void) log("request to modify '%s.%s's entry from '%s.%s@%s' ", + valsin1->name, valsin1->instance, rname, rinstance, rrealm); + + numfound = kerb_get_principal(valsin1->name, valsin1->instance, + &data_o, 1, &more); + if (numfound == -1) { + failmod(KADM_DB_INUSE); + } else if (numfound) { + kadm_vals_to_prin(valsin2->fields, &temp_key, valsin2); + (void) strncpy(data_o.name, valsin1->name, ANAME_SZ); + (void) strncpy(data_o.instance, valsin1->instance, INST_SZ); + if (IS_FIELD(KADM_EXPDATE,valsin2->fields)) + data_o.exp_date = temp_key.exp_date; + if (IS_FIELD(KADM_ATTR,valsin2->fields)) + data_o.attributes = temp_key.attributes; + if (IS_FIELD(KADM_MAXLIFE,valsin2->fields)) + data_o.max_life = temp_key.max_life; + if (IS_FIELD(KADM_DESKEY,valsin2->fields)) { + data_o.key_version++; + data_o.kdc_key_ver = server_parm.master_key_version; + + + /* convert to host order */ + temp_key.key_low = ntohl(temp_key.key_low); + temp_key.key_high = ntohl(temp_key.key_high); + + + bcopy(&temp_key.key_low,newpw,4); + bcopy(&temp_key.key_high,(char *)(((long *) newpw) + 1),4); + + /* encrypt new key in master key */ + kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key, + server_parm.master_key_schedule, DES_ENCRYPT); + bcopy(newpw,&data_o.key_low,4); + bcopy((char *)(((long *) newpw) + 1), &data_o.key_high,4); + bzero((char *)newpw, sizeof(newpw)); + } + bzero((char *)&temp_key, sizeof(temp_key)); + + (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1); + (void) strncpy(data_o.mod_instance, rinstance, + sizeof(data_o.mod_instance)-1); + more = kerb_put_principal(&data_o, 1); + + bzero((char *)&data_o, sizeof(data_o)); + + if (more == -1) { + failmod(KADM_DB_INUSE); + } else if (more) { + failmod(KADM_UK_SERROR); + } else { + numfound = kerb_get_principal(valsin1->name, valsin1->instance, + &data_o, 1, &more); + if ((more!=0)||(numfound!=1)) { + failmod(KADM_UK_RERROR); + } + bzero((char *) fields, sizeof(fields)); + SET_FIELD(KADM_NAME,fields); + SET_FIELD(KADM_INST,fields); + SET_FIELD(KADM_EXPDATE,fields); + SET_FIELD(KADM_ATTR,fields); + SET_FIELD(KADM_MAXLIFE,fields); + kadm_prin_to_vals(fields, valsout, &data_o); + (void) log("'%s.%s' modified.", valsin1->name, valsin1->instance); + return KADM_DATA; /* Set all the appropriate fields */ + } + } + else { + failmod(KADM_NOENTRY); + } +} +#undef failmod + +#define failchange(code) { (void) log("FAILED changing key for '%s.%s@%s' (%s)", rname, rinstance, rrealm, error_message(code)); return code; } + +int +kadm_change (char *rname, char *rinstance, char *rrealm, unsigned char *newpw) +{ + long numfound; + int more; + Principal data_o; + des_cblock local_pw; + + if (strcmp(server_parm.krbrlm, rrealm)) { + (void) log("change key request from wrong realm, '%s.%s@%s'!\n", + rname, rinstance, rrealm); + return(KADM_WRONG_REALM); + } + + if (wildcard(rname) || wildcard(rinstance)) { + failchange(KADM_ILL_WILDCARD); + } + (void) log("'%s.%s@%s' wants to change its password", + rname, rinstance, rrealm); + + bcopy(newpw, local_pw, sizeof(local_pw)); + + /* encrypt new key in master key */ + kdb_encrypt_key (&local_pw, &local_pw, &server_parm.master_key, + server_parm.master_key_schedule, DES_ENCRYPT); + + numfound = kerb_get_principal(rname, rinstance, + &data_o, 1, &more); + if (numfound == -1) { + failchange(KADM_DB_INUSE); + } else if (numfound) { + bcopy(local_pw,&data_o.key_low,4); + bcopy((char *)(((long *) local_pw) + 1), &data_o.key_high,4); + data_o.key_version++; + data_o.kdc_key_ver = server_parm.master_key_version; + (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1); + (void) strncpy(data_o.mod_instance, rinstance, + sizeof(data_o.mod_instance)-1); + more = kerb_put_principal(&data_o, 1); + bzero((char *) local_pw, sizeof(local_pw)); + bzero((char *) &data_o, sizeof(data_o)); + if (more == -1) { + failchange(KADM_DB_INUSE); + } else if (more) { + failchange(KADM_UK_SERROR); + } else { + (void) log("'%s.%s@%s' password changed.", rname, rinstance, rrealm); + return KADM_SUCCESS; + } + } + else { + failchange(KADM_NOENTRY); + } +} +#undef failchange diff --git a/kerberosIV/kadmind/kadm_ser_wrap.c b/kerberosIV/kadmind/kadm_ser_wrap.c new file mode 100644 index 00000000000..62430414e72 --- /dev/null +++ b/kerberosIV/kadmind/kadm_ser_wrap.c @@ -0,0 +1,210 @@ +/* $Id: kadm_ser_wrap.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Kerberos administration server-side support functions + */ + +/* +kadm_ser_wrap.c +unwraps wrapped packets and calls the appropriate server subroutine +*/ + +#include +#include + +/* GLOBAL */ +Kadm_Server server_parm; + +/* +kadm_ser_init +set up the server_parm structure +*/ +int +kadm_ser_init(int inter, char *realm) + /* interactive or from file */ + +{ + struct servent *sep; + struct hostent *hp; + char hostname[MAXHOSTNAMELEN]; + + (void) init_kadm_err_tbl(); + (void) init_krb_err_tbl(); + if (gethostname(hostname, sizeof(hostname))) + return KADM_NO_HOSTNAME; + + (void) strcpy(server_parm.sname, PWSERV_NAME); + (void) strcpy(server_parm.sinst, KRB_MASTER); + (void) strcpy(server_parm.krbrlm, realm); + + server_parm.admin_fd = -1; + /* setting up the addrs */ + if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL) + return KADM_NO_SERV; + bzero((char *)&server_parm.admin_addr,sizeof(server_parm.admin_addr)); + server_parm.admin_addr.sin_family = AF_INET; + if ((hp = gethostbyname(hostname)) == NULL) + return KADM_NO_HOSTNAME; + bcopy(hp->h_addr, (char *) &server_parm.admin_addr.sin_addr.s_addr, + hp->h_length); + server_parm.admin_addr.sin_port = sep->s_port; + /* setting up the database */ + if (kdb_get_master_key((inter==1), &server_parm.master_key, + server_parm.master_key_schedule) != 0) + return KADM_NO_MAST; + if ((server_parm.master_key_version = + kdb_verify_master_key(&server_parm.master_key, + server_parm.master_key_schedule,stderr))<0) + return KADM_NO_VERI; + return KADM_SUCCESS; +} + +static void errpkt(u_char **dat, int *dat_len, int code) +{ + u_int32_t retcode; + char *pdat; + + free((char *)*dat); /* free up req */ + *dat_len = KADM_VERSIZE + sizeof(u_int32_t); + *dat = (u_char *) malloc((unsigned)*dat_len); + pdat = (char *) *dat; + retcode = htonl((u_int32_t) code); + (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE); + bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_int32_t)); + return; +} + +/* +kadm_ser_in +unwrap the data stored in dat, process, and return it. +*/ +int +kadm_ser_in(u_char **dat, int *dat_len) +{ + u_char *in_st; /* pointer into the sent packet */ + int in_len,retc; /* where in packet we are, for + returns */ + u_int32_t r_len; /* length of the actual packet */ + KTEXT_ST authent; /* the authenticator */ + AUTH_DAT ad; /* who is this, klink */ + u_int32_t ncksum; /* checksum of encrypted data */ + des_key_schedule sess_sched; /* our schedule */ + MSG_DAT msg_st; + u_char *retdat, *tmpdat; + int retval, retlen; + + if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) { + errpkt(dat, dat_len, KADM_BAD_VER); + return KADM_BAD_VER; + } + in_len = KADM_VERSIZE; + /* get the length */ + if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0) + return KADM_LENGTH_ERROR; + in_len += retc; + authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(u_int32_t); + bcopy((char *)(*dat) + in_len, (char *)authent.dat, authent.length); + authent.mbz = 0; + /* service key should be set before here */ + if ((retc = krb_rd_req(&authent, server_parm.sname, server_parm.sinst, + server_parm.recv_addr.sin_addr.s_addr, &ad, (char *)0))) + { + errpkt(dat, dat_len,retc + krb_err_base); + return retc + krb_err_base; + } + +#define clr_cli_secrets() {bzero((char *)sess_sched, sizeof(sess_sched)); bzero((char *)ad.session, sizeof(ad.session));} + + in_st = *dat + *dat_len - r_len; +#ifdef NOENCRYPTION + ncksum = 0; +#else + ncksum = des_quad_cksum((des_cblock *)in_st, (des_cblock *)0, (long) r_len, 0, &ad.session); +#endif + if (ncksum!=ad.checksum) { /* yow, are we correct yet */ + clr_cli_secrets(); + errpkt(dat, dat_len,KADM_BAD_CHK); + return KADM_BAD_CHK; + } +#ifdef NOENCRYPTION + bzero(sess_sched, sizeof(sess_sched)); +#else + des_key_sched(&ad.session, sess_sched); +#endif + if ((retc = (int) krb_rd_priv(in_st, r_len, sess_sched, &ad.session, + &server_parm.recv_addr, + &server_parm.admin_addr, &msg_st))) { + clr_cli_secrets(); + errpkt(dat, dat_len,retc + krb_err_base); + return retc + krb_err_base; + } + switch (msg_st.app_data[0]) { + case CHANGE_PW: + retval = kadm_ser_cpw(msg_st.app_data+1,(int) msg_st.app_length,&ad, + &retdat, &retlen); + break; + case ADD_ENT: + retval = kadm_ser_add(msg_st.app_data+1,(int) msg_st.app_length,&ad, + &retdat, &retlen); + break; + case GET_ENT: + retval = kadm_ser_get(msg_st.app_data+1,(int) msg_st.app_length,&ad, + &retdat, &retlen); + break; + case MOD_ENT: + retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length,&ad, + &retdat, &retlen); + break; + default: + clr_cli_secrets(); + errpkt(dat, dat_len, KADM_NO_OPCODE); + return KADM_NO_OPCODE; + } + /* Now seal the response back into a priv msg */ + free((char *)*dat); + tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE + + sizeof(u_int32_t))); + (void) strncpy((char *)tmpdat, KADM_VERSTR, KADM_VERSIZE); + retval = htonl((u_int32_t)retval); + bcopy((char *)&retval, (char *)tmpdat + KADM_VERSIZE, sizeof(u_int32_t)); + if (retlen) { + bcopy((char *)retdat, (char *)tmpdat + KADM_VERSIZE + sizeof(u_int32_t), + retlen); + free((char *)retdat); + } + /* slop for mk_priv stuff */ + *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE + + sizeof(u_int32_t) + 200)); + if ((*dat_len = krb_mk_priv(tmpdat, *dat, + (u_int32_t) (retlen + KADM_VERSIZE + + sizeof(u_int32_t)), + sess_sched, + &ad.session, &server_parm.admin_addr, + &server_parm.recv_addr)) < 0) { + clr_cli_secrets(); + errpkt(dat, dat_len, KADM_NO_ENCRYPT); + return KADM_NO_ENCRYPT; + } + clr_cli_secrets(); + return KADM_SUCCESS; +} diff --git a/kerberosIV/kadmind/kadm_server.c b/kerberosIV/kadmind/kadm_server.c new file mode 100644 index 00000000000..1f15820204b --- /dev/null +++ b/kerberosIV/kadmind/kadm_server.c @@ -0,0 +1,154 @@ +/* $Id: kadm_server.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * Kerberos administration server-side subroutines + */ + +#include + +/* +kadm_ser_cpw - the server side of the change_password routine + recieves : KTEXT, {key} + returns : CKSUM, RETCODE + acl : caller can change only own password + +Replaces the password (i.e. des key) of the caller with that specified in key. +Returns no actual data from the master server, since this is called by a user +*/ +int +kadm_ser_cpw(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen) +{ + u_int32_t keylow, keyhigh; + des_cblock newkey; + int stvlen; + + /* take key off the stream, and change the database */ + + if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0) + return(KADM_LENGTH_ERROR); + if (stv_long(dat, &keylow, stvlen, len) < 0) + return(KADM_LENGTH_ERROR); + + keylow = ntohl(keylow); + keyhigh = ntohl(keyhigh); + bcopy((char *)&keyhigh, (char *)(((int32_t *)newkey) + 1), 4); + bcopy((char *)&keylow, (char *)newkey, 4); + *datout = 0; + *outlen = 0; + + return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey)); +} + +/* +kadm_ser_add - the server side of the add_entry routine + recieves : KTEXT, {values} + returns : CKSUM, RETCODE, {values} + acl : su, sms (as alloc) + +Adds and entry containing values to the database +returns the values of the entry, so if you leave certain fields blank you will + be able to determine the default values they are set to +*/ +int +kadm_ser_add(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen) +{ + Kadm_vals values, retvals; + long status; + + if ((status = stream_to_vals(dat, &values, len)) < 0) + return(KADM_LENGTH_ERROR); + if ((status = kadm_add_entry(ad->pname, ad->pinst, ad->prealm, + &values, &retvals)) == KADM_DATA) { + *outlen = vals_to_stream(&retvals,datout); + return KADM_SUCCESS; + } else { + *outlen = 0; + return status; + } +} + +/* +kadm_ser_mod - the server side of the mod_entry routine + recieves : KTEXT, {values, values} + returns : CKSUM, RETCODE, {values} + acl : su, sms (as register or dealloc) + +Modifies all entries corresponding to the first values so they match the + second values. +returns the values for the changed entries +*/ +int +kadm_ser_mod(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen) +{ + Kadm_vals vals1, vals2, retvals; + int wh; + long status; + + if ((wh = stream_to_vals(dat, &vals1, len)) < 0) + return KADM_LENGTH_ERROR; + if ((status = stream_to_vals(dat+wh,&vals2, len-wh)) < 0) + return KADM_LENGTH_ERROR; + if ((status = kadm_mod_entry(ad->pname, ad->pinst, ad->prealm, &vals1, + &vals2, &retvals)) == KADM_DATA) { + *outlen = vals_to_stream(&retvals,datout); + return KADM_SUCCESS; + } else { + *outlen = 0; + return status; + } +} + +/* +kadm_ser_get + recieves : KTEXT, {values, flags} + returns : CKSUM, RETCODE, {count, values, values, values} + acl : su + +gets the fields requested by flags from all entries matching values +returns this data for each matching recipient, after a count of how many such + matches there were +*/ +int +kadm_ser_get(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen) +{ + Kadm_vals values, retvals; + u_char fl[FLDSZ]; + int loop,wh; + long status; + + if ((wh = stream_to_vals(dat, &values, len)) < 0) + return KADM_LENGTH_ERROR; + if (wh + FLDSZ > len) + return KADM_LENGTH_ERROR; + for (loop=FLDSZ-1; loop>=0; loop--) + fl[loop] = dat[wh++]; + if ((status = kadm_get_entry(ad->pname, ad->pinst, ad->prealm, + &values, fl, &retvals)) == KADM_DATA) { + *outlen = vals_to_stream(&retvals,datout); + return KADM_SUCCESS; + } else { + *outlen = 0; + return status; + } +} + diff --git a/kerberosIV/kadmind/kadmind.8 b/kerberosIV/kadmind/kadmind.8 new file mode 100644 index 00000000000..88f4e7ec7ba --- /dev/null +++ b/kerberosIV/kadmind/kadmind.8 @@ -0,0 +1,126 @@ +.\" Copyright 1987, 1988, 1989 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. +.\" +.\" $Id: kadmind.8,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- Kerberos database administration daemon +.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/kerberosIV/kafs/Makefile b/kerberosIV/kafs/Makefile new file mode 100644 index 00000000000..3a7a91134bb --- /dev/null +++ b/kerberosIV/kafs/Makefile @@ -0,0 +1,6 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ + +LIB= kafs +SRCS= afssys.c + +.include diff --git a/kerberosIV/kafs/afssys.c b/kerberosIV/kafs/afssys.c new file mode 100644 index 00000000000..546b6cde5ef --- /dev/null +++ b/kerberosIV/kafs/afssys.c @@ -0,0 +1,300 @@ +/* $Id: afssys.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "afssysdefs.h" + +#define AUTH_SUPERUSER "afs" + +/* + * Here only ASCII characters are relevant. + */ + +#define IsAsciiUpper(c) ('A' <= (c) && (c) <= 'Z') + +#define ToAsciiLower(c) ((c) - 'A' + 'a') + +static void +folddown(a, b) + char *a, *b; +{ + for (; *b; a++, b++) + if (IsAsciiUpper(*b)) + *a = ToAsciiLower(*b); + else + *a = *b; + *a = '\0'; +} + +#if !defined(linux) /* won't work there -- no SIGSYS, no syscall */ + +int +k_afsklog(realm) + char *realm; +{ + int k_errno; + CREDENTIALS c; + KTEXT_ST ticket; + char username[256]; + char krealm[REALM_SZ]; + + if (!k_hasafs()) + return KSUCCESS; + + if (realm == 0 || realm[0] == 0) + { + k_errno = krb_get_lrealm(krealm, 0); + if (k_errno != KSUCCESS) + return k_errno; + realm = krealm; + } + + k_errno = krb_get_cred(AUTH_SUPERUSER, "", realm, &c); + if (k_errno != KSUCCESS) + { + k_errno = krb_mk_req(&ticket, AUTH_SUPERUSER, "", realm, 0); + if (k_errno == KSUCCESS) + k_errno = krb_get_cred(AUTH_SUPERUSER, "", realm, &c); + } + + if (k_errno == KSUCCESS) + { + char cell[256]; + struct ViceIoctl parms; + struct ClearToken ct; + int32_t sizeof_x; + char buf[2048], *t; + + folddown(cell, realm); + + /* + * Build a struct ClearToken + */ + ct.AuthHandle = c.kvno; + bcopy((char *)c.session, ct.HandShakeKey, sizeof(c.session)); + ct.ViceId = getuid(); /* is this always valid? */ + ct.BeginTimestamp = 1 + c.issue_date; + ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime); + + t = buf; + /* + * length of secret token followed by secret token + */ + sizeof_x = c.ticket_st.length; + bcopy((char *)&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); + bcopy((char *)c.ticket_st.dat, t, sizeof_x); + t += sizeof_x; + /* + * length of clear token followed by clear token + */ + sizeof_x = sizeof(ct); + bcopy((char *)&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); + bcopy((char *)&ct, t, sizeof_x); + t += sizeof_x; + + /* + * do *not* mark as primary cell + */ + sizeof_x = 0; + bcopy((char *)&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); + /* + * follow with cell name + */ + sizeof_x = strlen(cell) + 1; + bcopy(cell, t, sizeof_x); + t += sizeof_x; + + /* + * Build argument block + */ + parms.in = buf; + parms.in_size = t - buf; + parms.out = 0; + parms.out_size = 0; + (void) k_pioctl(0, VIOCSETTOK, &parms, 0); + } + return k_errno; +} + +#define NO_ENTRY_POINT 0 +#define SINGLE_ENTRY_POINT 1 +#define MULTIPLE_ENTRY_POINT 2 +#define SINGLE_ENTRY_POINT2 3 +#define AIX_ENTRY_POINTS 4 +#define UNKNOWN_ENTRY_POINT 5 +static int afs_entry_point = UNKNOWN_ENTRY_POINT; + +int +k_pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks) + char *a_path; + int o_opcode; + struct ViceIoctl *a_paramsP; + int a_followSymlinks; +{ +#ifdef AFS_SYSCALL + if (afs_entry_point == SINGLE_ENTRY_POINT) + return syscall(AFS_SYSCALL, AFSCALL_PIOCTL, + a_path, o_opcode, a_paramsP, a_followSymlinks); +#endif + +#ifdef AFS_PIOCTL + if (afs_entry_point == MULTIPLE_ENTRY_POINT) + return syscall(AFS_PIOCTL, + a_path, o_opcode, a_paramsP, a_followSymlinks); +#endif + +#ifdef AFS_SYSCALL2 + if (afs_entry_point == SINGLE_ENTRY_POINT2) + return syscall(AFS_SYSCALL2, AFSCALL_PIOCTL, + a_path, o_opcode, a_paramsP, a_followSymlinks); +#endif + +#ifdef _AIX + if (afs_entry_point == AIX_ENTRY_POINTS) + return lpioctl(a_path, o_opcode, a_paramsP, a_followSymlinks); +#endif + + errno = ENOSYS; + kill(getpid(), SIGSYS); /* You loose! */ + return -1; +} + +int +k_unlog() +{ + struct ViceIoctl parms; + bzero((char *)&parms, sizeof(parms)); + return k_pioctl(0, VIOCUNLOG, &parms, 0); +} + +int +k_setpag() +{ +#ifdef AFS_SYSCALL + if (afs_entry_point == SINGLE_ENTRY_POINT) + return syscall(AFS_SYSCALL, AFSCALL_SETPAG); +#endif + +#ifdef AFS_SETPAG + if (afs_entry_point == MULTIPLE_ENTRY_POINT) + return syscall(AFS_SETPAG); +#endif + +#ifdef AFS_SYSCALL2 + if (afs_entry_point == SINGLE_ENTRY_POINT2) + return syscall(AFS_SYSCALL2, AFSCALL_SETPAG); +#endif + +#ifdef _AIX + if (afs_entry_point == AIX_ENTRY_POINTS) + return lsetpag(); +#endif + + errno = ENOSYS; + kill(getpid(), SIGSYS); /* You loose! */ + return -1; +} +#endif /* defined(linux) */ +static jmp_buf catch_SIGSYS; + +static void +SIGSYS_handler() +{ + errno = 0; + longjmp(catch_SIGSYS, 1); +} + +int +k_hasafs() +{ + int saved_errno; + void (*saved_func)(); + struct ViceIoctl parms; + +#if defined(linux) + return 0; +#else + /* + * Already checked presence of AFS syscalls? + */ + if (afs_entry_point != UNKNOWN_ENTRY_POINT) + return afs_entry_point != NO_ENTRY_POINT; + + /* + * Probe kernel for AFS specific syscalls, + * they (currently) come in two flavors. + * If the syscall is absent we recive a SIGSYS. + */ + afs_entry_point = NO_ENTRY_POINT; + bzero(&parms, sizeof(parms)); + + saved_errno = errno; + saved_func = signal(SIGSYS, SIGSYS_handler); + +#ifdef AFS_SYSCALL + if (setjmp(catch_SIGSYS) == 0) + { + syscall(AFS_SYSCALL, AFSCALL_PIOCTL, + 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (errno == EINVAL) + { + afs_entry_point = SINGLE_ENTRY_POINT; + goto done; + } + } +#endif /* AFS_SYSCALL */ + +#ifdef AFS_PIOCTL + if (setjmp(catch_SIGSYS) == 0) + { + syscall(AFS_PIOCTL, + 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (errno == EINVAL) + { + afs_entry_point = MULTIPLE_ENTRY_POINT; + goto done; + } + } +#endif /* AFS_PIOCTL */ + +#ifdef AFS_SYSCALL2 + if (setjmp(catch_SIGSYS) == 0) + { + syscall(AFS_SYSCALL2, AFSCALL_PIOCTL, + 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (errno == EINVAL) + { + afs_entry_point = SINGLE_ENTRY_POINT2; + goto done; + } + } +#endif /* AFS_SYSCALL */ + +#ifdef _AIX + if (setjmp(catch_SIGSYS) == 0) + { + lpioctl(0, 0, 0, 0); + if (errno == EINVAL) + { + afs_entry_point = AIX_ENTRY_POINTS; + goto done; + } + } +#endif + + done: + (void) signal(SIGSYS, saved_func); + errno = saved_errno; + return afs_entry_point != NO_ENTRY_POINT; +#endif /* linux */ +} diff --git a/kerberosIV/kafs/afssysdefs.h b/kerberosIV/kafs/afssysdefs.h new file mode 100644 index 00000000000..cc712d9adc7 --- /dev/null +++ b/kerberosIV/kafs/afssysdefs.h @@ -0,0 +1,34 @@ +/* $Id: afssysdefs.h,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */ + +/* + * This section is for machines using single entry point AFS syscalls! + * or + * This section is for machines using multiple entry point AFS syscalls! + */ + +#if defined(sun) && !defined(__svr4__) +#define AFS_SYSCALL 31 +#endif + +#if defined(sun) && defined(__svr4__) +#define AFS_SYSCALL 105 +#endif + +#if defined(hpux) +#define AFS_SYSCALL 50 +#define AFS_SYSCALL2 49 +#endif + +#if defined(_AIX) +/* _AIX is too weird */ +#endif + +#if defined(sgi) +#define AFS_PIOCTL (64+1000) +#define AFS_SETPAG (65+1000) +#endif + +#if defined(__osf__) +#define AFS_SYSCALL 232 +#define AFS_SYSCALL2 258 +#endif diff --git a/kerberosIV/kafs/shlib_version b/kerberosIV/kafs/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/kafs/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/kdb/Makefile b/kerberosIV/kdb/Makefile new file mode 100644 index 00000000000..cbd1af5aa84 --- /dev/null +++ b/kerberosIV/kdb/Makefile @@ -0,0 +1,8 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ + +LIB= kdb +CFLAGS+=-I${.CURDIR} +SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c + +.include diff --git a/kerberosIV/kdb/kdb_locl.h b/kerberosIV/kdb/kdb_locl.h new file mode 100644 index 00000000000..df18f9e20ce --- /dev/null +++ b/kerberosIV/kdb/kdb_locl.h @@ -0,0 +1,60 @@ +/* $Id: kdb_locl.h,v 1.1.1.1 1995/12/14 06:52:37 tholo Exp $ */ + +#ifndef __kdb_locl_h +#define __kdb_locl_h + +#include "kerberosIV/site.h" + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* --- */ + +/* Globals! */ + +/* Utils */ + +int kerb_db_set_lockmode __P((int)); +void kerb_db_fini __P((void)); +int kerb_db_init __P((void)); +int kerb_db_set_name __P((char *name)); +time_t kerb_get_db_age __P((void)); +int kerb_db_create __P((char *db_name)); +int kerb_db_rename __P((char *from, char *to)); + +int kerb_db_get_principal __P((char *name, char *, Principal *, unsigned int, int *)); +int kerb_db_put_principal __P((Principal *, unsigned int)); +int kerb_db_get_dba __P((char *, char *, Dba *, unsigned int, int *)); + +void kerb_db_get_stat __P((DB_stat *)); +void kerb_db_put_stat __P((DB_stat *)); +void delta_stat __P((DB_stat *, DB_stat *, DB_stat *)); + +int kerb_db_iterate __P((int (*func) (/* ??? */), char *arg)); + +int kerb_cache_init __P((void)); +int kerb_cache_get_principal __P((char *name, char *, Principal *, unsigned int)); +int kerb_cache_put_principal __P((Principal *, unsigned int)); +int kerb_cache_get_dba __P((char *, char *, Dba *, unsigned int)); +int kerb_cache_put_dba __P((Dba *, unsigned int)); + +void krb_print_principal __P((Principal *)); + +#endif /* __kdb_locl_h */ diff --git a/kerberosIV/kdb/krb_cache.c b/kerberosIV/kdb/krb_cache.c new file mode 100644 index 00000000000..141908738ac --- /dev/null +++ b/kerberosIV/kdb/krb_cache.c @@ -0,0 +1,186 @@ +/* $Id: krb_cache.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * Copyright (C) 1989 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * This is where a cache would be implemented, if it were necessary. + */ + +#include "kdb_locl.h" + +#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; + + 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 */ + +{ + 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; + + 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 */ + +{ + 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/kerberosIV/kdb/krb_dbm.c b/kerberosIV/kdb/krb_dbm.c new file mode 100644 index 00000000000..d4a37c7646a --- /dev/null +++ b/kerberosIV/kdb/krb_dbm.c @@ -0,0 +1,739 @@ +/* $Id: krb_dbm.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * Copyright (C) 1989 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "kdb_locl.h" + +#include + +#define KERB_DB_MAX_RETRY 5 + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +extern char *progname; +#endif + +static init = 0; +static char default_db_name[] = DBM_FILE; +static char *current_db_name = default_db_name; + +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. + */ + +#define dbm_next(db,key) dbm_nextkey(db) + +static char *gen_dbsuffix __P((char *db_name, char *sfx)); +static void decode_princ_key __P((datum *key, char *name, char *instance)); +static void encode_princ_contents __P((datum *contents, Principal *principal)); +static void decode_princ_contents __P((datum *contents, Principal *principal)); +static void encode_princ_key __P((datum *key, char *name, char *instance)); +static int kerb_dbl_init __P((void)); +static void kerb_dbl_fini __P((void)); +static int kerb_dbl_lock __P((int mode)); +static void kerb_dbl_unlock __P((void)); +static time_t kerb_start_update __P((char *db_name)); +static int kerb_end_update __P((char *db_name, time_t age)); +static time_t kerb_start_read __P((void)); +static int kerb_end_read __P((time_t age)); + +/* + * 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; +} + +static void +decode_princ_key(key, name, instance) + datum *key; + char *name; + char *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)); +} + +static void +encode_princ_key(key, name, instance) + datum *key; + char *name; + char *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 int dblfd = -1; /* db LOCK fd */ +static int mylock = 0; +static int inited = 0; + +static int +kerb_dbl_init() +{ + if (!inited) { + char *filename = gen_dbsuffix (current_db_name, ".ok"); + if ((dblfd = open(filename, O_RDWR)) < 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; +} + +/* + * initialization for data base routines. + */ + +int +kerb_db_init() +{ + init = 1; + return (0); +} + +/* + * gracefully shut down database--must be called by ANY program that does + * a kerb_db_init + */ + +void +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. + */ + +int +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. + */ + +time_t +kerb_get_db_age() +{ + struct stat st; + char *okname; + time_t 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 time_t +kerb_start_update(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + time_t age = kerb_get_db_age(); + + if (unlink(okname) < 0 + && errno != ENOENT) { + age = -1; + } + free (okname); + return age; +} + +static int +kerb_end_update(db_name, age) + char *db_name; + time_t 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 utimbuf tv; + /* make sure that semaphore is "after" previous value. */ + if (fstat (fd, &st) == 0 + && st.st_mtime <= age) { + tv.actime = st.st_atime; + tv.modtime = age; + /* set times.. */ + utime (new_okname, &tv); + fsync(fd); + } + close(fd); + if (rename (new_okname, okname) < 0) + retval = errno; + } + + free (new_okname); + free (okname); + + return retval; +} + +static time_t +kerb_start_read() +{ + return kerb_get_db_age(); +} + +static int +kerb_end_read(age) + time_t age; +{ + if (kerb_get_db_age() != age || age == -1) { + return -1; + } + return 0; +} + +/* + * Create the database, assuming it's not there. + */ + +int +kerb_db_create(db_name) + char *db_name; +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + int fd; + register int ret = 0; + DBM *db; + + db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (db == NULL) + ret = errno; + else + dbm_close(db); + 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... + */ + +int +kerb_db_rename(from, to) + char *from; + char *to; +{ +#if defined(__NetBSD__) || defined(__FreeBSD__) + char *fromdb = gen_dbsuffix (from, ".db"); + char *todb = gen_dbsuffix (from, ".db"); +#else + char *fromdir = gen_dbsuffix (from, ".dir"); + char *todir = gen_dbsuffix (to, ".dir"); + char *frompag = gen_dbsuffix (from , ".pag"); + char *topag = gen_dbsuffix (to, ".pag"); +#endif + char *fromok = gen_dbsuffix(from, ".ok"); + long trans = kerb_start_update(to); + int ok = 0; + +#if defined(__NetBSD__) || defined(__FreeBSD__) + if (rename (fromdb, todb) == 0) { + (void) unlink (fromdb); + ok = 1; + } + free (fromdb); + free (todb); +#else + if ((rename (fromdir, todir) == 0) + && (rename (frompag, topag) == 0)) { + (void) unlink (fromok); + ok = 1; + } + free (fromdir); + free (todir); + free (frompag); + free (topag); +#endif + free (fromok); + 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. + */ + +int +kerb_db_get_principal(name, inst, principal, max, more) + char *name; /* could have wild card */ + char *inst; /* could have wild card */ + Principal *principal; /* max number of name structs to return */ + unsigned int max; /* where there more than 'max' tuples? */ + int *more; +{ + 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. + */ + +int +kerb_db_put_principal(principal, max) + Principal *principal; /* number of principal structs to */ + unsigned int max; /* 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); +} + +void +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 */ +} + +void +kerb_db_put_stat(s) + DB_stat *s; +{ +} + +void +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. + */ + +int +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; /* max number of name structs to return */ + unsigned int max; /* where there more than 'max' tuples? */ + int *more; +{ + *more = 0; + return (0); +} + +int +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; +} diff --git a/kerberosIV/kdb/krb_kdb_utils.c b/kerberosIV/kdb/krb_kdb_utils.c new file mode 100644 index 00000000000..d9c81855917 --- /dev/null +++ b/kerberosIV/kdb/krb_kdb_utils.c @@ -0,0 +1,153 @@ +/* $Id: krb_kdb_utils.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * 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 + */ + +#include "kdb_locl.h" + +#include + +long +kdb_get_master_key(prompt, master_key, master_key_sched) + int prompt; + des_cblock *master_key; + struct des_ks_struct *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 + des_key_sched(master_key,master_key_sched); +#endif + return (0); +} + +/* The old algorithm used the key schedule as the initial vector which + was byte order depedent ... */ + +void +kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag) + des_cblock *in; + des_cblock *out; + des_cblock *master_key; + struct des_ks_struct *master_key_sched; + int e_d_flag; +{ + +#ifdef NOENCRYPTION + bcopy(in, out, sizeof(des_cblock)); +#else + des_pcbc_encrypt(in,out,(long)sizeof(des_cblock),master_key_sched,master_key, + e_d_flag); +#endif +} + +/* 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) + des_cblock *master_key; + struct des_ks_struct *master_key_sched; + FILE *out; /* setting this to non-null be do output */ +{ + des_cblock 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, DES_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); +} diff --git a/kerberosIV/kdb/krb_lib.c b/kerberosIV/kdb/krb_lib.c new file mode 100644 index 00000000000..f5d963490ae --- /dev/null +++ b/kerberosIV/kdb/krb_lib.c @@ -0,0 +1,236 @@ +/* $Id: krb_lib.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * Copyright (C) 1989 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "kdb_locl.h" + +#ifdef DEBUG +extern int debug; +extern char *progname; +long kerb_debug; +#endif + +static int 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. + */ + +void +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 */ +int +kerb_put_principal(principal, n) + Principal *principal; + unsigned int n; /* number of principal structs to write */ +{ + struct tm *tp; + + /* set mod date */ + principal->mod_date = time((time_t *)0); + /* and mod date string */ + + tp = k_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/kerberosIV/kdb/print_princ.c b/kerberosIV/kdb/print_princ.c new file mode 100644 index 00000000000..3c358c61403 --- /dev/null +++ b/kerberosIV/kdb/print_princ.c @@ -0,0 +1,48 @@ +/* $Id: print_princ.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * Copyright (C) 1989 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "kdb_locl.h" + +void +krb_print_principal(a_n) + Principal *a_n; +{ + struct tm *time_p; + + /* run-time database does not contain string versions */ + time_p = k_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%08lx k_high 0x%08lx akv %d exists %ld\n", + a_n->key_version, (long)a_n->key_low, (long)a_n->key_high, + a_n->kdc_key_ver, (long)a_n->old); + + fflush(stderr); +} diff --git a/kerberosIV/kdb/shlib_version b/kerberosIV/kdb/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/kdb/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/kdb_destroy/Makefile b/kerberosIV/kdb_destroy/Makefile new file mode 100644 index 00000000000..1389546df6e --- /dev/null +++ b/kerberosIV/kdb_destroy/Makefile @@ -0,0 +1,7 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ + +PROG= kdb_destroy +MAN= kdb_destroy.8 + +.include diff --git a/kerberosIV/kdb_destroy/kdb_destroy.8 b/kerberosIV/kdb_destroy/kdb_destroy.8 new file mode 100644 index 00000000000..9898be97d0f --- /dev/null +++ b/kerberosIV/kdb_destroy/kdb_destroy.8 @@ -0,0 +1,32 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kdb_destroy.8,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ +.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/kerberosIV/kdb_destroy/kdb_destroy.c b/kerberosIV/kdb_destroy/kdb_destroy.c new file mode 100644 index 00000000000..96ec912abbc --- /dev/null +++ b/kerberosIV/kdb_destroy/kdb_destroy.c @@ -0,0 +1,61 @@ +/* $Id: kdb_destroy.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include + +int +main(void) +{ + char answer[10]; /* user input */ + char dbm[256]; /* database path and name */ + char dbm1[256]; /* database path and name */ +#if defined(__FreeBSD__) || defined(__NetBSD__) + char *file; /* database file names */ +#else + char *file1, *file2; /* database file names */ +#endif + + strcpy(dbm, DBM_FILE); +#if defined(__FreeBSD__) || defined(__NetBSD__) + file = strcat(dbm, ".db"); +#else + strcpy(dbm1, DBM_FILE); + file1 = strcat(dbm, ".dir"); + file2 = strcat(dbm1, ".pag"); +#endif + + 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 defined(__FreeBSD__) || defined(__NetBSD__) + if (unlink(file) == 0) +#else + if (unlink(file1) == 0 && unlink(file2) == 0) +#endif + 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"); + exit(1); +} diff --git a/kerberosIV/kdb_edit/Makefile b/kerberosIV/kdb_edit/Makefile new file mode 100644 index 00000000000..5134f3dad36 --- /dev/null +++ b/kerberosIV/kdb_edit/Makefile @@ -0,0 +1,11 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ + +PROG= kdb_edit +SRCS= kdb_edit.c maketime.c +CFLAGS+=-I${.CURDIR} +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kdb_edit.8 + +.include diff --git a/kerberosIV/kdb_edit/kdb_edit.8 b/kerberosIV/kdb_edit/kdb_edit.8 new file mode 100644 index 00000000000..974f08e938c --- /dev/null +++ b/kerberosIV/kdb_edit/kdb_edit.8 @@ -0,0 +1,54 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kdb_edit.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ +.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/kerberosIV/kdb_edit/kdb_edit.c b/kerberosIV/kdb_edit/kdb_edit.c new file mode 100644 index 00000000000..7d79d3f3cd7 --- /dev/null +++ b/kerberosIV/kdb_edit/kdb_edit.c @@ -0,0 +1,473 @@ +/* $Id: kdb_edit.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * This routine changes the Kerberos encryption keys for principals, + * i.e., users or services. + */ + +/* + * exit returns 0 ==> success -1 ==> error + */ + +#include + +#ifdef DEBUG +extern kerb_debug; +#endif + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +static char prog[32]; +char *progname = prog; +static int nflag = 0; +static int debug; + +static des_cblock new_key; + +static int i, j; +static int more; + +static char input_name[ANAME_SZ]; +static char input_instance[INST_SZ]; + +#define MAX_PRINCIPAL 10 +static Principal principal_data[MAX_PRINCIPAL]; + +static Principal old_principal; +static Principal default_princ; + +static des_cblock master_key; +static des_cblock session_key; +static des_key_schedule master_key_schedule; +static char pw_str[255]; +static long master_key_version; + +static void +Usage(void) +{ + fprintf(stderr, "Usage: %s [-n]\n", progname); + exit(1); +} + +/* + * "fgets" where the nl is zapped afterwards. + */ +static char* +z_fgets(cp, count, fp) + char *cp; + int count; + FILE *fp; +{ + int ix; + char *p; + + if (fgets(cp, count, fp) == 0) { + return 0; + } + cp[count-1] = 0; + if ((p = strchr(cp, '\n')) == 0) { + return 0; + } + *p = 0; + return cp; +} + + +static int +change_principal(void) +{ + static char temp[255]; + int creating = 0; + int editpw = 0; + int changed = 0; + long temp_long; + int n; + struct tm *tp, edate, *localtime(const time_t *); + long maketime(struct tm *tp, int local); + + fprintf(stdout, "\nPrincipal name: "); + fflush(stdout); + if (!z_fgets(input_name, sizeof input_name, stdin) || *input_name == '\0') + return 0; + fprintf(stdout, "Instance: "); + fflush(stdout); + /* instance can be null */ + z_fgets(input_instance, sizeof input_instance, stdin); + j = kerb_get_principal(input_name, input_instance, principal_data, + MAX_PRINCIPAL, &more); + if (!j) { + fprintf(stdout, "\n\07\07, Create [y] ? "); + z_fgets(temp, sizeof temp, stdin); /* 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 = k_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] ? "); + z_fgets(temp, sizeof temp, stdin); + if (strcmp("y", temp) && strcmp("Y", temp)) + editpw = 0; + } + fflush(stdout); + /* 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") == 0 + || strcmp(pw_str, "") == 0) { + printf("\nRandom password [y] ? "); + z_fgets(temp, sizeof temp, stdin); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(des_cblock)); + new_key[0] = 127; +#else + des_string_to_key(pw_str, &new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "RANDOM" */ + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(des_cblock)); + new_key[0] = 127; +#else + des_new_random_key(&new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + } else if (!strcmp(pw_str, "NULL")) { + printf("\nNull Key [y] ? "); + z_fgets(temp, sizeof temp, stdin); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(des_cblock)); + new_key[0] = 127; +#else + des_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(des_cblock)); + new_key[0] = 127; +#else + des_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, + DES_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 (z_fgets(temp, sizeof temp, stdin) && + ((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 (z_fgets(temp, sizeof temp, stdin) && *temp) { + if (sscanf(temp, "%ld", &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 (z_fgets(temp, sizeof temp, stdin) && *temp) { + if (sscanf(temp, "%ld", &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; +} + +static void +cleanup(void) +{ + + 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)); +} + +int +main(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", prog, (int)sizeof(long)); + 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 */ +#ifdef DEBUG + case 'l': + kerb_debug |= 1; + continue; +#endif + 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); + + /* Initialize non shared random sequence */ + des_init_random_number_generator(&master_key); + + /* 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, %ld 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(); + exit(0); +} + +#if 0 +static 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); +} + +static void +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); +} +#endif diff --git a/kerberosIV/kdb_edit/maketime.c b/kerberosIV/kdb_edit/maketime.c new file mode 100644 index 00000000000..3264dd87db5 --- /dev/null +++ b/kerberosIV/kdb_edit/maketime.c @@ -0,0 +1,88 @@ +/* $Id: maketime.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Convert a struct tm * to a UNIX time. + */ + +#include + +#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(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/kerberosIV/kdb_init/Makefile b/kerberosIV/kdb_init/Makefile new file mode 100644 index 00000000000..3672139a50f --- /dev/null +++ b/kerberosIV/kdb_init/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ + +PROG= kdb_init +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kdb_init.8 + +.include diff --git a/kerberosIV/kdb_init/kdb_init.8 b/kerberosIV/kdb_init/kdb_init.8 new file mode 100644 index 00000000000..92314dbd528 --- /dev/null +++ b/kerberosIV/kdb_init/kdb_init.8 @@ -0,0 +1,40 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kdb_init.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ +.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/kerberosIV/kdb_init/kdb_init.c b/kerberosIV/kdb_init/kdb_init.c new file mode 100644 index 00000000000..9866e5466c9 --- /dev/null +++ b/kerberosIV/kdb_init/kdb_init.c @@ -0,0 +1,173 @@ +/* $Id: kdb_init.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * program to initialize the database, reports error if database file + * already exists. + */ + +#include + +enum ap_op { + NULL_KEY, /* setup null keys */ + MASTER_KEY, /* use master key as new key */ + RANDOM_KEY /* choose a random key */ +}; + +char *progname; +static des_cblock master_key; +static des_key_schedule master_key_schedule; + +/* use a return code to indicate success or failure. check the return */ +/* values of the routines called by this routine. */ + +static int +add_principal(char *name, char *instance, enum ap_op aap_op) +{ + Principal principal; + struct tm *tm; + des_cblock 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(des_cblock)); + new_key[0] = 127; +#else + des_new_random_key(&new_key); +#endif + kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule, + DES_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 (des_cblock)); + kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule, + DES_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 = k_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; + + if (kerb_db_put_principal(&principal, 1) != 1) + return -1; /* FAIL */ + + /* let's play it safe */ + bzero (new_key, sizeof (des_cblock)); + bzero (&principal.key_low, 4); + bzero (&principal.key_high, 4); + return 0; +} + +int +main(int argc, char **argv) +{ + char realm[REALM_SZ]; + char *cp; + int code; + char *database; + + progname = (cp = strrchr(*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", + strerror(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 = strchr(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); + } + + /* Initialize non shared random sequence */ + des_init_random_number_generator(&master_key); + + 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 (des_cblock)); + bzero (master_key_schedule, sizeof (des_key_schedule)); + exit(0); +} diff --git a/kerberosIV/kdb_util/Makefile b/kerberosIV/kdb_util/Makefile new file mode 100644 index 00000000000..8916b72cecc --- /dev/null +++ b/kerberosIV/kdb_util/Makefile @@ -0,0 +1,11 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ + +PROG= kdb_util +SRCS= kdb_util.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kdb_util.8 + +.include diff --git a/kerberosIV/kdb_util/kdb_util.8 b/kerberosIV/kdb_util/kdb_util.8 new file mode 100644 index 00000000000..523bdf39665 --- /dev/null +++ b/kerberosIV/kdb_util/kdb_util.8 @@ -0,0 +1,63 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kdb_util.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ +.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/kerberosIV/kdb_util/kdb_util.c b/kerberosIV/kdb_util/kdb_util.c new file mode 100644 index 00000000000..2805e2efbf4 --- /dev/null +++ b/kerberosIV/kdb_util/kdb_util.c @@ -0,0 +1,484 @@ +/* $Id: kdb_util.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * 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 + */ + +#include + +static char *prog; + +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))) + +/* 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 void +print_time(FILE *file, time_t timeval) +{ + struct tm *tm; + tm = gmtime(&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); +} + +static long +time_explode(char *cp) +{ + char wbuf[5]; + struct tm tp; + long maketime(struct tm *tp, int local); + 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)); +} + +static int +dump_db_1(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, + (int)htonl (principal->key_low), + (int)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; +} + +static int +dump_db (char *db_file, FILE *output_file, void (*cv_key) (Principal *)) +{ + 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); +} + +static void +load_db (char *db_file, FILE *input_file) +{ + char exp_date_str[50]; + char mod_date_str[50]; + int temp1, temp2, temp3; + 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, strerror(code)); + exit(1); + } + kerb_db_set_name(temp_db_file); + for (;;) { /* explicit break on eof from fscanf */ + u_long key_lo, key_hi; /* Must match format string */ + bzero((char *)&aprinc, sizeof(aprinc)); + if (fscanf(input_file, + "%s %s %d %d %d %hd %lx %lx %s %s %s %s\n", + aprinc.name, + aprinc.instance, + &temp1, + &temp2, + &temp3, + &aprinc.attributes, + &key_lo, + &key_hi, + exp_date_str, + mod_date_str, + aprinc.mod_name, + aprinc.mod_instance) == EOF) + break; + aprinc.key_low = ntohl (key_lo); + aprinc.key_high = ntohl (key_hi); + 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, + strerror(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); +} + +/*ARGSUSED*/ +static void +update_ok_file (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); +} + +static void +convert_key_new_master (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, DES_DECRYPT); + } + + kdb_encrypt_key (&key, &key, &new_master_key, new_master_key_schedule, DES_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)++; +} + +static void +clear_secrets (void) +{ + bzero((char *)master_key, sizeof (des_cblock)); + bzero((char *)master_key_schedule, sizeof (des_key_schedule)); + bzero((char *)new_master_key, sizeof (des_cblock)); + bzero((char *)new_master_key_schedule, sizeof (des_key_schedule)); +} + +static void +convert_new_master_key (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", prog); + 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", prog); + clear_secrets (); + exit (-1); + } + + dump_db (db_file, out, convert_key_new_master); +} + +static void +convert_key_old_db (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, DES_DECRYPT); +#endif + + /* make new key, new style */ + kdb_encrypt_key (&key, &key, &master_key, master_key_schedule, DES_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 ... */ +} + +static void +convert_old_format_db (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", prog); + 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, DES_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\07verify_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); +} + +int +main(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 *db_name; + prog = argv[0]; + + 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); + } diff --git a/kerberosIV/kdestroy/Makefile b/kerberosIV/kdestroy/Makefile new file mode 100644 index 00000000000..6bef35d2906 --- /dev/null +++ b/kerberosIV/kdestroy/Makefile @@ -0,0 +1,8 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 + +PROG= kdestroy +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes +BINDIR= /usr/bin + +.include diff --git a/kerberosIV/kdestroy/kdestroy.1 b/kerberosIV/kdestroy/kdestroy.1 new file mode 100644 index 00000000000..0fd7d4d0258 --- /dev/null +++ b/kerberosIV/kdestroy/kdestroy.1 @@ -0,0 +1,80 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kdestroy.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ +.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/kerberosIV/kdestroy/kdestroy.c b/kerberosIV/kdestroy/kdestroy.c new file mode 100644 index 00000000000..c5e05d55023 --- /dev/null +++ b/kerberosIV/kdestroy/kdestroy.c @@ -0,0 +1,71 @@ +/* $Id: kdestroy.c,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * 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 + */ + +#include + +static char *pname; + +static void +usage() +{ + fprintf(stderr, "Usage: %s [-f] [-q]\n", pname); + exit(1); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int fflag=0, qflag=0, k_errno; + register char *cp; + + cp = strrchr (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/kerberosIV/kerberos/Makefile b/kerberosIV/kerberos/Makefile new file mode 100644 index 00000000000..e346e8bc2de --- /dev/null +++ b/kerberosIV/kerberos/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ + +PROG= kerberos +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kerberos.8 + +.include diff --git a/kerberosIV/kerberos/kerberos.8 b/kerberosIV/kerberos/kerberos.8 new file mode 100644 index 00000000000..3fc6b6234c5 --- /dev/null +++ b/kerberosIV/kerberos/kerberos.8 @@ -0,0 +1,258 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kerberos.8,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ +.TH KERBEROS 8 "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/kerberosIV/kerberos/kerberos.c b/kerberosIV/kerberos/kerberos.c new file mode 100644 index 00000000000..a87d11c3eab --- /dev/null +++ b/kerberosIV/kerberos/kerberos.c @@ -0,0 +1,814 @@ +/* $Id: kerberos.c,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include "kerberosIV/site.h" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +static struct sockaddr_in sina = {AF_INET}; +int f; + +/* XXX several files in libkdb know about this */ +char *progname; + +static des_key_schedule master_key_schedule; +static des_cblock master_key; + +static struct timeval kerb_time; +static Principal a_name_data; /* for requesting user */ +static Principal s_name_data; /* for services requested */ +static des_cblock session_key; +static u_char master_key_version; +static char k_instance[INST_SZ]; +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_long req_time_ws; + +int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */ + +static char local_realm[REALM_SZ]; + +/* statistics */ +static int q_bytes; /* current bytes remaining in queue */ +static int q_n; /* how many consecutive non-zero + * q_bytes */ +static int max_q_bytes; +static int max_q_n; +static int n_auth_req; +static int n_appl_req; +static int n_packets; + +static int max_age = -1; +static int pause_int = -1; + +/* + * Print usage message and exit. + */ +static void +usage(void) +{ + 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); +} + +/* + * kerb_er_reply creates an error reply packet and sends it to the + * client. + */ + +static void +kerb_err_reply(struct sockaddr_in *client, KTEXT pkt, long int 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); +} + +static void +hang(void) +{ + 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); + } +} + +/* + * 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" + */ + +static char * +strtime(time_t *t) +{ + static char st_data[40]; + static char *st = st_data; + struct tm *tm; + char *month_sname(int n); + + 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; +} + +static int +check_princ(char *p_name, char *instance, unsigned int lifetime, Principal *p) +{ + static int n; + static int more; + + 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, + strtime((time_t*)&(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 */ +static int +set_tgtkey(char *r) + /* Realm for desired key */ +{ + int n; + static char lastrealm[REALM_SZ]; + Principal p_st; + Principal *p = &p_st; + des_cblock 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, DES_DECRYPT); + krb_set_key(key, 0); + strcpy(lastrealm, r); + return (KSUCCESS); +} + +static void +kerberos(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; + u_long lifetime; + int i; + des_cblock key; + des_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 req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + + 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 = (unsigned char) (*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, 0, + &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(des_cblock)); +#else + des_new_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, DES_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, DES_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((char*)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, (char*)(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 = (unsigned char) (*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, + krb_time_to_life(kerb_time.tv_sec,krb_life_to_time(ad->time_sec,ad->life))); + 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, DES_DECRYPT); + /* construct and seal the ticket */ + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(des_cblock)); +#else + des_new_random_key(&session_key); +#endif + + krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, + ad->prealm, 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)); + + 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. + */ + +static void +setup_disc(void) +{ + int s; + + for (s = 0; s < 3; s++) { + (void) close(s); + } + + (void) open("/dev/null", 0); + (void) dup2(0, 1); + (void) dup2(0, 2); + + setsid(); + + (void) chdir("/tmp"); + return; +} + +/* + * Make sure that database isn't stale. + * + * Exit if it is; we don't want to tell lies. + */ + +static void check_db_age(void) +{ + 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 */ + } + } +} + +int +main(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; + int kerror; + 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); + } + sina.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*)&sina, sizeof(sina)) < 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); + des_init_random_number_generator(&master_key); + + 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); + } +} diff --git a/kerberosIV/kinit/Makefile b/kerberosIV/kinit/Makefile new file mode 100644 index 00000000000..3bf26ce1cb9 --- /dev/null +++ b/kerberosIV/kinit/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $ + +PROG= kinit +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes +BINDIR= /usr/bin + +.include diff --git a/kerberosIV/kinit/kinit.1 b/kerberosIV/kinit/kinit.1 new file mode 100644 index 00000000000..2fa87fcf075 --- /dev/null +++ b/kerberosIV/kinit/kinit.1 @@ -0,0 +1,132 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kinit.1,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ +.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/kerberosIV/kinit/kinit.c b/kerberosIV/kinit/kinit.c new file mode 100644 index 00000000000..75176eb2cc7 --- /dev/null +++ b/kerberosIV/kinit/kinit.c @@ -0,0 +1,184 @@ +/* $Id: kinit.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * 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] + */ + +#include +#include + +#define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */ + +char *progname; + +static void +get_input(s, size, stream) +char *s; +int size; +FILE *stream; +{ + char *p; + + if (fgets(s, size, stream) == NULL) + exit(1); + if ( (p = strchr(s, '\n')) != NULL) + *p = '\0'; +} + + +static void +usage() +{ + fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname); + exit(1); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + char aname[ANAME_SZ]; + char inst[INST_SZ]; + char realm[REALM_SZ]; + char buf[MAXHOSTNAMELEN]; + 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 = strrchr(*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 (gethostname(buf, MAXHOSTNAMELEN)) { + fprintf(stderr, "%s: 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 { + printf("Kerberos Initialization\n"); + printf("Kerberos name: "); + get_input(aname, sizeof(aname), stdin); + 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 /= krb_time_to_life(0, lifetime*60); + /* 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); + } + exit(0); +} diff --git a/kerberosIV/klist/Makefile b/kerberosIV/klist/Makefile new file mode 100644 index 00000000000..8a3dd2e26d5 --- /dev/null +++ b/kerberosIV/klist/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ + +PROG= klist +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes +BINDIR= /usr/bin + +.include diff --git a/kerberosIV/klist/klist.1 b/kerberosIV/klist/klist.1 new file mode 100644 index 00000000000..e16d25e47bd --- /dev/null +++ b/kerberosIV/klist/klist.1 @@ -0,0 +1,83 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: klist.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ +.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/kerberosIV/klist/klist.c b/kerberosIV/klist/klist.c new file mode 100644 index 00000000000..a7ced8ca4fd --- /dev/null +++ b/kerberosIV/klist/klist.c @@ -0,0 +1,282 @@ +/* $Id: klist.c,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Lists your current Kerberos tickets. + * Written by Bill Sommerfeld, MIT Project Athena. + */ + +#include + +char *whoami; /* What was I invoked as?? */ + +static char * +short_date(dp) + time_t *dp; +{ + register char *cp; + + if (*dp == (time_t)(-1L)) return "*** Never *** "; + cp = ctime(dp) + 4; + cp[15] = '\0'; + return (cp); +} + +static void +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 = krb_life_to_time(c.issue_date, c.lifetime); + 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 = krb_life_to_time(c.issue_date, c.lifetime); + if (time(0) < (unsigned long) c.issue_date) + (void) strcpy(buf2, short_date(&c.issue_date)); + else + (void) strcpy(buf2, ">>> Expired <<< "); + 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"); + } +} + +/* 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) + */ + +static int +ok_getst(fd, s, n) + int fd; + register char *s; + int n; +{ + 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); +} + +static void +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); +} + +static void +usage() +{ + fprintf(stderr, + "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami); + exit(1); +} + +/* ARGSUSED */ +int +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 = strrchr(*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); +} diff --git a/kerberosIV/kpasswdd/Makefile b/kerberosIV/kpasswdd/Makefile new file mode 100644 index 00000000000..7de4dc6bd46 --- /dev/null +++ b/kerberosIV/kpasswdd/Makefile @@ -0,0 +1,13 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/4/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:54 tholo Exp $ + +PROG= kpasswdd +SRCS= kpasswdd.c des_rw.c +.PATH: ${.CURDIR}/../../usr.bin/rlogin +CFLAGS+=-DKERBEROS -I${.CURDIR}/../../usr.bin/passwd +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kpasswdd.8 +BINDIR=/usr/libexec + +.include diff --git a/kerberosIV/kpasswdd/kpasswdd.8 b/kerberosIV/kpasswdd/kpasswdd.8 new file mode 100644 index 00000000000..791667e0e91 --- /dev/null +++ b/kerberosIV/kpasswdd/kpasswdd.8 @@ -0,0 +1,61 @@ +.\" 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. +.\" +.\" from @(#)kpasswdd.8 8.1 (Berkeley) 6/9/93 +.\" $Id: kpasswdd.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ +.\" +.Dd June 9, 1993 +.Dt KPASSWDD 8 +.Os +.Sh NAME +.Nm kpasswdd +.Nd Kerberos password changing daemon +.Sh SYNOPSIS +.Nm kpasswdd +.Sh DESCRIPTION +.Nm Kpasswdd +is the server for the +.Xr passwd 1 +program. +The server provides a remote password changing facility +with Kerberos authentication. +A user must provide the old Kerberos password, encrypted +in a random session key, to the server. +.Nm Kpasswdd +runs only on the Kerberos server, as it directly updates the +Kerberos database. +.Sh SEE ALSO +.Xr kerberos 1 , +.Xr passwd 1 +.Sh HISTORY +The +.Nm kpasswdd +utility first appeared in 4.4BSD. diff --git a/kerberosIV/kpasswdd/kpasswdd.c b/kerberosIV/kpasswdd/kpasswdd.c new file mode 100644 index 00000000000..5fa1ec8dbe8 --- /dev/null +++ b/kerberosIV/kpasswdd/kpasswdd.c @@ -0,0 +1,273 @@ +/* $Id: kpasswdd.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ */ + +/*- + * 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[] = "@(#)kpasswdd.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* + * kpasswdd - update a principal's passwd field in the Kerberos + * database. Called from inetd. + * K. Fall + * 12-Dec-88 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kpasswd_proto.h" + +static struct kpasswd_data kpwd_data; +static des_cblock master_key, key; +static Key_schedule master_key_schedule, + key_schedule, random_sched; +long mkeyversion; +AUTH_DAT kdata; +static Principal principal_data; +static struct update_data ud_data; + +char inst[INST_SZ]; +char version[9]; +KTEXT_ST ticket; + +char *progname; /* for the library */ + +main() +{ + struct sockaddr_in foreign; + int foreign_len = sizeof(foreign); + int rval, more; + static char name[] = "kpasswdd"; + + static struct rlimit rl = { 0, 0 }; + + progname = name; + openlog("kpasswdd", LOG_CONS | LOG_PID, LOG_AUTH); + + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + syslog(LOG_ERR, "setrlimit: %m"); + exit(1); + } + + if (getpeername(0, &foreign, &foreign_len) < 0) { + syslog(LOG_ERR,"getpeername: %m"); + exit(1); + } + + strcpy(inst, "*"); + rval = krb_recvauth( + 0L, /* options--!MUTUAL */ + 0, /* file desc */ + &ticket, /* client's ticket */ + SERVICE, /* expected service */ + inst, /* expected instance */ + &foreign, /* foreign addr */ + (struct sockaddr_in *) 0, /* local addr */ + &kdata, /* returned krb data */ + "", /* service keys file */ + (bit_64 *) NULL, /* returned key schedule */ + version + ); + + + if (rval != KSUCCESS) { + syslog(LOG_NOTICE, "krb_recvauth: %s", krb_err_txt[rval]); + cleanup(); + exit(1); + } + + if (*version == '\0') { + /* indicates error on client's side (no tickets, etc.) */ + cleanup(); + exit(0); + } else if (strcmp(version, "KPWDV0.1") != 0) { + syslog(LOG_NOTICE, + "kpasswdd version conflict (recv'd %s)", + version); + cleanup(); + exit(1); + } + + + /* get master key */ + if (kdb_get_master_key(0, &master_key, master_key_schedule) != 0) { + syslog(LOG_ERR, "couldn't get master key"); + cleanup(); + exit(1); + } + + mkeyversion = kdb_get_master_key(NULL, &master_key, master_key_schedule); + + if (mkeyversion < 0) { + syslog(LOG_NOTICE, "couldn't verify master key"); + cleanup(); + exit(1); + } + + /* get principal info */ + rval = kerb_get_principal( + kdata.pname, + kdata.pinst, + &principal_data, + 1, + &more + ); + + if (rval < 0) { + syslog(LOG_NOTICE, + "error retrieving principal record for %s.%s", + kdata.pname, kdata.pinst); + cleanup(); + exit(1); + } + + if (rval != 1 || (more != 0)) { + syslog(LOG_NOTICE, "more than 1 dbase entry for %s.%s", + kdata.pname, kdata.pinst); + cleanup(); + exit(1); + } + + /* get the user's key */ + + bcopy(&principal_data.key_low, key, 4); + bcopy(&principal_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(&key, &key, &master_key, master_key_schedule, + DECRYPT); + key_sched(&key, key_schedule); + des_set_key(&key, key_schedule); + + + /* get random key and send it over {random} Kperson */ + + random_key(kpwd_data.random_key); + strcpy(kpwd_data.secure_msg, SECURE_STRING); + if (des_write(0, &kpwd_data, sizeof(kpwd_data)) != sizeof(kpwd_data)) { + syslog(LOG_NOTICE, "error writing initial data"); + cleanup(); + exit(1); + } + + bzero(key, sizeof(key)); + bzero(key_schedule, sizeof(key_schedule)); + + /* now read update info: { info }Krandom */ + + key_sched(&kpwd_data.random_key, random_sched); + des_set_key(&kpwd_data.random_key, random_sched); + if (des_read(0, &ud_data, sizeof(ud_data)) != sizeof(ud_data)) { + syslog(LOG_NOTICE, "update aborted"); + cleanup(); + exit(1); + } + + /* validate info string by looking at the embedded string */ + + if (strcmp(ud_data.secure_msg, SECURE_STRING) != 0) { + syslog(LOG_NOTICE, "invalid update from %s", + inet_ntoa(foreign.sin_addr)); + cleanup(); + exit(1); + } + + /* produce the new key entry in the database { key }Kmaster */ + string_to_key(ud_data.pw, &key); + kdb_encrypt_key(&key, &key, + &master_key, master_key_schedule, + ENCRYPT); + bcopy(key, &principal_data.key_low, 4); + bcopy(((long *) key) + 1, + &principal_data.key_high, 4); + bzero(key, sizeof(key)); + principal_data.key_version++; + if (kerb_put_principal(&principal_data, 1)) { + syslog(LOG_ERR, "couldn't write new record for %s.%s", + principal_data.name, principal_data.instance); + cleanup(); + exit(1); + } + + syslog(LOG_NOTICE,"wrote new password field for %s.%s from %s", + principal_data.name, + principal_data.instance, + inet_ntoa(foreign.sin_addr) + ); + + send_ack(0, "Update complete.\n"); + cleanup(); + exit(0); +} + +cleanup() +{ + bzero(&kpwd_data, sizeof(kpwd_data)); + bzero(&master_key, sizeof(master_key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(key, sizeof(key)); + bzero(key_schedule, sizeof(key_schedule)); + bzero(random_sched, sizeof(random_sched)); + bzero(&principal_data, sizeof(principal_data)); + bzero(&ud_data, sizeof(ud_data)); +} + +send_ack(remote, msg) + int remote; + char *msg; +{ + int cc; + cc = des_write(remote, msg, strlen(msg) + 1); + if (cc <= 0) { + syslog(LOG_NOTICE, "error writing ack"); + cleanup(); + exit(1); + } +} diff --git a/kerberosIV/kprop/Makefile b/kerberosIV/kprop/Makefile new file mode 100644 index 00000000000..09c90350fa4 --- /dev/null +++ b/kerberosIV/kprop/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ + +PROG= kprop +LDADD+= -lkrb -ldes +DPADD+= ${LIBKRB} ${LIBDES} +NOMAN= noman + +.include diff --git a/kerberosIV/kprop/kprop.c b/kerberosIV/kprop/kprop.c new file mode 100644 index 00000000000..b61cb791f32 --- /dev/null +++ b/kerberosIV/kprop/kprop.c @@ -0,0 +1,538 @@ +/* $Id: kprop.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $ */ + +/*- + * Copyright 1987 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file . + */ + +#include +#include +#include + +static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION; + +int debug = 0; + +char my_realm[REALM_SZ]; +int princ_data_size = 3 * sizeof(long) + 3 * sizeof(unsigned char); +short transfer_mode, net_transfer_mode; +int force_flag; +static char ok[] = ".dump_ok"; + +struct slave_host { + u_long net_addr; + char *name; + char *instance; + char *realm; + int not_time_yet; + int succeeded; + struct slave_host *next; +}; + +static void +Death(char *s) +{ + fprintf(stderr, "kprop: "); + perror(s); + exit(1); +} + +static +int get_slaves(struct slave_host **psl, char *file, time_t ok_mtime) +{ + FILE *fin; + char namebuf[128], *inst; + char *pc; + struct hostent *host; + struct slave_host **th; + char path[256]; + char *ppath; + struct stat stbuf; + + if ((fin = fopen(file, "r")) == NULL) { + fprintf(stderr, "Can't open slave host file, '%s'.\n", file); + exit(-1); + } + strcpy(path, file); + if ((ppath = strrchr(path, '/'))) { + ppath += 1; + } else { + ppath = path; + } + for (th = psl; fgets(namebuf, sizeof namebuf, fin); th = &(*th)->next) { + if ((pc = strchr(namebuf, '\n'))) { + *pc = '\0'; + } else { + fprintf(stderr, "Host name too long (>= %d chars) in '%s'.\n", + (int)(sizeof(namebuf)), file); + exit(-1); + } + host = gethostbyname(namebuf); + if (host == NULL) { + fprintf(stderr, "Unknown host '%s' in '%s'.\n", namebuf, file); + exit(-1); + } + (*th) = (struct slave_host *) malloc(sizeof(struct slave_host)); + if (!*th) { + fprintf(stderr, "No memory reading host list from '%s'.\n", + file); + exit(-1); + } + bzero( (*th) , (sizeof(struct slave_host)) ); + (*th)->name = malloc(strlen(namebuf) + 1); + if (!(*th)->name) { + fprintf(stderr, "No memory reading host list from '%s'.\n", + file); + exit(-1); + } + /* get kerberos cannonical instance name */ + strcpy((*th)->name, namebuf); + inst = krb_get_phost ((*th)->name); + (*th)->instance = malloc(strlen(inst) + 1); + if (!(*th)->instance) { + fprintf(stderr, "No memory reading host list from '%s'.\n", + file); + exit(-1); + } + strcpy((*th)->instance, inst); + /* what a concept, slave servers in different realms! */ + (*th)->realm = my_realm; + bcopy(host->h_addr, (char *)&(*th)->net_addr, sizeof(host->h_addr)); + (*th)->not_time_yet = 0; + (*th)->succeeded = 0; + (*th)->next = NULL; + strcat(strcpy(ppath, (*th)->name), "-last-prop"); + if (!force_flag && !stat(path, &stbuf) && stbuf.st_mtime > ok_mtime) { + (*th)->not_time_yet = 1; + (*th)->succeeded = 1; /* no change since last success */ + } + } + fclose(fin); + return (1); +} + +/* The master -> slave protocol looks like this: + 1) 8 byte version string + 2) 2 bytes of "transfer mode" (net byte order of course) + 3) ticket/authentication send by sendauth + 4) 4 bytes of "block" length (u_long) + 5) data + + 4 and 5 repeat til EOF ... +*/ + +static int +prop_to_slaves(struct slave_host *sl, int fd, char *fslv) +{ + char buf[KPROP_BUFSIZ]; + char obuf[KPROP_BUFSIZ + 64 /* leave room for private msg overhead */ ]; + struct servent *sp; + struct sockaddr_in sin, my_sin; + int i, n, s; + struct slave_host *cs; /* current slave */ + char path[256], my_host_name[MAXHOSTNAMELEN], *p_my_host_name; + char kprop_service_instance[INST_SZ]; + char *pc; + u_long cksum; + u_long length, nlength; + long kerror; + KTEXT_ST ticket; + CREDENTIALS cred; + MSG_DAT msg_dat; + static char tkstring[] = "/tmp/kproptktXXXXXX"; + + des_key_schedule session_sched; + + (void) mktemp(tkstring); + krb_set_tkt_string(tkstring); + + if ((sp = getservbyname("krb_prop", "tcp")) == 0) { + fprintf(stderr, "tcp/krb_prop: service unknown.\n"); + exit(1); + } + + bzero(&sin, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_port = sp->s_port; + sin.sin_addr.s_addr = INADDR_ANY; + + strcpy(path, fslv); + if ((pc = strrchr(path, '/'))) { + pc += 1; + } else { + pc = path; + } + + for (i = 0; i < 5; i++) { /* try each slave five times max */ + for (cs = sl; cs; cs = cs->next) { + if (!cs->succeeded) { + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("kprop: socket"); + exit(1); + } + bcopy(&cs->net_addr, &sin.sin_addr, + sizeof cs->net_addr); + + if (connect(s, (struct sockaddr *) &sin, sizeof sin) < 0) { + fprintf(stderr, "%s: ", cs->name); + perror("connect"); + close(s); + continue; /*** NEXT SLAVE ***/ + } + + /* for krb_mk_{priv, safe} */ + bzero (&my_sin, sizeof my_sin); + n = sizeof my_sin; + if (getsockname (s, (struct sockaddr *) &my_sin, &n) != 0) { + fprintf (stderr, "kprop: can't get socketname."); + perror ("getsockname"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + if (n != sizeof (my_sin)) { + fprintf (stderr, "kprop: can't get socketname. len"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + /* Get ticket */ + kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, + cs->instance, cs->realm, (u_long) 0); + /* if ticket has expired try to get a new one, but + * first get a TGT ... + */ + if (kerror != MK_AP_OK) { + if (gethostname (my_host_name, sizeof(my_host_name)) != 0) { + fprintf (stderr, "%s:", cs->name); + perror ("getting my hostname"); + close (s); + break; /* next one can't work either! */ + } + /* get canonical kerberos service instance name */ + p_my_host_name = krb_get_phost (my_host_name); + /* copy it to make sure gethostbyname static doesn't + * screw us. */ + strcpy (kprop_service_instance, p_my_host_name); + kerror = krb_get_svc_in_tkt (KPROP_SERVICE_NAME, +#if 0 + kprop_service_instance, +#else + KRB_MASTER, +#endif + my_realm, + TGT_SERVICE_NAME, + my_realm, + 96, + KPROP_SRVTAB); + if (kerror != INTK_OK) { + fprintf (stderr, + "%s: %s. While getting initial ticket\n", + cs->name, krb_err_txt[kerror]); + close (s); + goto punt; + } + kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, + cs->instance, cs->realm, (u_long) 0); + } + if (kerror != MK_AP_OK) { + fprintf (stderr, "%s: %s. Calling krb_mk_req.", + cs->name, krb_err_txt[kerror]); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + if (write(s, kprop_version, sizeof(kprop_version)) + != sizeof(kprop_version)) { + fprintf (stderr, "%s: ", cs->name); + perror ("write (version) error"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + net_transfer_mode = htons (transfer_mode); + if (write(s, &net_transfer_mode, sizeof(net_transfer_mode)) + != sizeof(net_transfer_mode)) { + fprintf (stderr, "%s: ", cs->name); + perror ("write (transfer_mode) error"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + kerror = krb_get_cred (KPROP_SERVICE_NAME, cs->instance, + cs->realm, &cred); + if (kerror != KSUCCESS) { + fprintf (stderr, "%s: %s. Getting session key.", + cs->name, krb_err_txt[kerror]); + close (s); + continue; /*** NEXT SLAVE ***/ + } +#ifdef NOENCRYPTION + bzero((char *)session_sched, sizeof(session_sched)); +#else + if (des_key_sched (&cred.session, session_sched)) { + fprintf (stderr, "%s: can't make key schedule.", + cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } +#endif + /* SAFE (quad_cksum) and CLEAR are just not good enough */ + cksum = 0; +#ifdef not_working_yet + if (transfer_mode != KPROP_TRANSFER_PRIVATE) { + cksum = get_data_checksum(fd, session_sched); + lseek(fd, 0L, 0); + } + else +#endif + { + struct stat st; + fstat (fd, &st); + cksum = st.st_size; + } + kerror = krb_sendauth(KOPT_DO_MUTUAL, + s, + &ticket, + KPROP_SERVICE_NAME, + cs->instance, + cs->realm, + cksum, + &msg_dat, + &cred, + session_sched, + &my_sin, + &sin, + KPROP_PROT_VERSION); + if (kerror != KSUCCESS) { + fprintf (stderr, "%s: %s. Calling krb_sendauth.", + cs->name, krb_err_txt[kerror]); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + lseek(fd, 0L, SEEK_SET); /* Rewind file before rereading it. */ + while ((n = read(fd, buf, sizeof buf))) { + if (n < 0) { + perror("input file read error"); + exit(1); + } + switch (transfer_mode) { + case KPROP_TRANSFER_PRIVATE: + case KPROP_TRANSFER_SAFE: + if (transfer_mode == KPROP_TRANSFER_PRIVATE) + length = krb_mk_priv (buf, obuf, n, + session_sched, &cred.session, + &my_sin, &sin); + else + length = krb_mk_safe (buf, obuf, n, + &cred.session, + &my_sin, &sin); + if (length == -1) { + fprintf (stderr, "%s: %s failed.", + cs->name, + (transfer_mode == KPROP_TRANSFER_PRIVATE) + ? "krb_rd_priv" : "krb_rd_safe"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + nlength = htonl(length); + if (write(s, &nlength, sizeof nlength) + != sizeof nlength) { + fprintf (stderr, "%s: ", cs->name); + perror ("write error"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + if (write(s, obuf, length) != length) { + fprintf(stderr, "%s: ", cs->name); + perror("write error"); + close(s); + continue; /*** NEXT SLAVE ***/ + } + break; + case KPROP_TRANSFER_CLEAR: + if (write(s, buf, n) != n) { + fprintf(stderr, "%s: ", cs->name); + perror("write error"); + close(s); + continue; /*** NEXT SLAVE ***/ + } + break; + } + } + close(s); + cs->succeeded = 1; + fprintf(stderr, "%s: success.\n", cs->name); + strcat(strcpy(pc, cs->name), "-last-prop"); + unlink(path); + close(creat(path, 0600)); + } + } + } +punt: + + dest_tkt(); + for (cs = sl; cs; cs = cs->next) { + if (!cs->succeeded) + return (0); /* didn't get this slave */ + } + return (1); +} + +int +main(int argc, char **argv) +{ + int fd, i; + char *floc, *floc_ok; + char *fslv; + struct stat stbuf, stbuf_ok; + time_t l_init, l_final; + char *pc; + int l_diff; + static struct slave_host *slave_host_list = NULL; + struct slave_host *sh; + + transfer_mode = KPROP_TRANSFER_PRIVATE; + + time(&l_init); + pc = ctime(&l_init); + pc[strlen(pc) - 1] = '\0'; + printf("\nStart slave propagation: %s\n", pc); + + floc = (char *) NULL; + fslv = (char *) NULL; + + if (krb_get_lrealm(my_realm,1) != KSUCCESS) + Death ("Getting my kerberos realm. Check krb.conf"); + + for (i = 1; i < argc; i++) + switch (argv[i][0]) { + case '-': + if (strcmp (argv[i], "-private") == 0) + transfer_mode = KPROP_TRANSFER_PRIVATE; +#ifdef not_safe_yet + else if (strcmp (argv[i], "-safe") == 0) + transfer_mode = KPROP_TRANSFER_SAFE; + else if (strcmp (argv[i], "-clear") == 0) + transfer_mode = KPROP_TRANSFER_CLEAR; +#endif + else if (strcmp (argv[i], "-realm") == 0) { + i++; + if (i < argc) + strcpy(my_realm, argv[i]); + else + goto usage; + } else if (strcmp (argv[i], "-force") == 0) + force_flag++; + else { + fprintf (stderr, "kprop: unknown control argument %s.\n", + argv[i]); + exit (1); + } + break; + default: + /* positional arguments are marginal at best ... */ + if (floc == (char *) NULL) + floc = argv[i]; + else { + if (fslv == (char *) NULL) + fslv = argv[i]; + else { + usage: + /* already got floc and fslv, what is this? */ + fprintf(stderr, + "\nUsage: kprop [-force] [-realm realm] [-private|-safe|-clear] data_file slaves_file\n\n"); + exit(1); + } + } + } + if ((floc == (char *)NULL) || (fslv == (char *)NULL)) + goto usage; + + if ((floc_ok = (char *) malloc(strlen(floc) + strlen(ok) + 1)) + == NULL) { + Death(floc); + } + strcat(strcpy(floc_ok, floc), ok); + + if ((fd = open(floc, O_RDONLY)) < 0) { + Death(floc); + } + if (flock(fd, LOCK_EX | LOCK_NB)) { + Death(floc); + } + if (stat(floc, &stbuf)) { + Death(floc); + } + if (stat(floc_ok, &stbuf_ok)) { + Death(floc_ok); + } + if (stbuf.st_mtime > stbuf_ok.st_mtime) { + fprintf(stderr, "kprop: '%s' more recent than '%s'.\n", + floc, floc_ok); + exit(1); + } + if (!get_slaves(&slave_host_list, fslv, stbuf_ok.st_mtime)) { + fprintf(stderr, + "kprop: can't read slave host file '%s'.\n", fslv); + exit(1); + } +#ifdef KPROP_DBG + { + struct slave_host *sh; + int i; + fprintf(stderr, "\n\n"); + fflush(stderr); + for (sh = slave_host_list; sh; sh = sh->next) { + fprintf(stderr, "slave %d: %s, %s", i++, sh->name, + inet_ntoa(sh->net_addr)); + fflush(stderr); + } + } +#endif /* KPROP_DBG */ + + if (!prop_to_slaves(slave_host_list, fd, fslv)) { + fprintf(stderr, + "kprop: propagation failed.\n"); + exit(1); + } + if (flock(fd, LOCK_UN)) { + Death(floc); + } + fprintf(stderr, "\n\n"); + for (sh = slave_host_list; sh; sh = sh->next) { + fprintf(stderr, "%s:\t\t%s\n", sh->name, + (sh->not_time_yet? "Not time yet" : (sh->succeeded ? "Succeeded" : "FAILED"))); + } + + time(&l_final); + l_diff = l_final - l_init; + printf("propagation finished, %d:%02d:%02d elapsed\n", + l_diff / 3600, (l_diff % 3600) / 60, l_diff % 60); + + exit(0); +} + +#ifdef doesnt_work_yet +u_long get_data_checksum(fd, key_sched) + int fd; + des_key_schedule key_sched; +{ + unsigned long cksum = 0; + int n; + char buf[BUFSIZ]; + long obuf[2]; + + while (n = read(fd, buf, sizeof buf)) { + if (n < 0) { + fprintf(stderr, "Input data file read error: "); + perror("read"); + exit(1); + } + cksum = cbc_cksum(buf, obuf, n, key_sched, key_sched); + } + return cksum; +} +#endif diff --git a/kerberosIV/kpropd/Makefile b/kerberosIV/kpropd/Makefile new file mode 100644 index 00000000000..3d12f9af527 --- /dev/null +++ b/kerberosIV/kpropd/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ + +PROG= kpropd +LDADD+= -lkrb -ldes +DPADD+= ${LIBKRB} ${LIBDES} +NOMAN= noman +BINDIR=/usr/libexec + +.include diff --git a/kerberosIV/kpropd/kpropd.c b/kerberosIV/kpropd/kpropd.c new file mode 100644 index 00000000000..91b547a4c43 --- /dev/null +++ b/kerberosIV/kpropd/kpropd.c @@ -0,0 +1,412 @@ +/* $Id: kpropd.c,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ */ + +/*- + * Copyright 1987 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file . + */ + +/* + * This program is run on slave servers, to catch updates "pushed" + * from the master kerberos server in a realm. + */ + +#include +#include + +static char *kdb_util_path = "kdb_util"; + +static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION; + +int debug = 0; + +char *logfile = K_LOGFIL; + +char errmsg[256]; +int pause_int = 300; /* 5 minutes in seconds */ + +static char buf[KPROP_BUFSIZ+64 /* leave room for private msg overhead */]; + +static void +SlowDeath(void) +{ + klog(L_KRB_PERR, "kpropd will pause before dying so as not to loop init"); + sleep(pause_int); + klog(L_KRB_PERR, "AAAAAHHHHhhhh...."); + exit(1); +} + +static void +usage(void) +{ + fprintf(stderr, "\nUsage: kpropd [-r realm] [-s srvtab] [-l logfile] fname\n\n"); + SlowDeath(); +} + +static void +recv_auth (int in, int out, int private, struct sockaddr_in *remote, struct sockaddr_in *local, AUTH_DAT *ad) +{ + u_long length; + long kerror; + int n; + MSG_DAT msg_data; + des_key_schedule session_sched; + + if (private) +#ifdef NOENCRYPTION + bzero((char *)session_sched, sizeof(session_sched)); +#else + if (des_key_sched (&ad->session, session_sched)) { + klog (L_KRB_PERR, "kpropd: can't make key schedule"); + SlowDeath(); + } +#endif + + while (1) { + n = krb_net_read (in, (char *)&length, sizeof length); + if (n == 0) break; + if (n < 0) { + sprintf (errmsg, "kpropd: read: %s", strerror(errno)); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + length = ntohl (length); + if (length > sizeof buf) { + sprintf (errmsg, "kpropd: read length %ld, bigger than buf %d", + length, (int)(sizeof(buf))); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + n = krb_net_read(in, buf, length); + if (n < 0) { + sprintf(errmsg, "kpropd: read: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + if (private) + kerror = krb_rd_priv (buf, n, session_sched, &ad->session, + remote, local, &msg_data); + else + kerror = krb_rd_safe (buf, n, &ad->session, + remote, local, &msg_data); + if (kerror != KSUCCESS) { + sprintf (errmsg, "kpropd: %s: %s", + private ? "krb_rd_priv" : "krb_rd_safe", + krb_err_txt[kerror]); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + if (write(out, msg_data.app_data, msg_data.app_length) != + msg_data.app_length) { + sprintf(errmsg, "kpropd: write: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + } +} + +static void +recv_clear (int in, int out) +{ + int n; + + while (1) { + n = read (in, buf, sizeof buf); + if (n == 0) break; + if (n < 0) { + sprintf (errmsg, "kpropd: read: %s", strerror(errno)); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + if (write(out, buf, n) != n) { + sprintf(errmsg, "kpropd: write: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + } +} + +int +main(int argc, char **argv) +{ + struct sockaddr_in from; + struct sockaddr_in sin; + struct servent *sp; + int s, s2, fd, n, fdlock; + int from_len; + char local_file[256]; + char local_temp[256]; + struct hostent *hp; + char hostname[256]; + char from_str[128]; + long kerror; + AUTH_DAT auth_dat; + KTEXT_ST ticket; + char my_instance[INST_SZ]; + char my_realm[REALM_SZ]; + char cmd[1024]; + short net_transfer_mode, transfer_mode; + des_key_schedule session_sched; + char version[9]; + int c; + extern char *optarg; + extern int optind; + int rflag = 0; + char *srvtab = ""; + char *local_db = DBM_FILE; + + if (argv[argc - 1][0] == 'k' && isdigit(argv[argc - 1][1])) { + argc--; /* ttys file hack */ + } + while ((c = getopt(argc, argv, "r:s:d:l:p:P:")) != EOF) { + switch(c) { + case 'r': + rflag++; + strcpy(my_realm, optarg); + break; + case 's': + srvtab = optarg; + break; + case 'd': + local_db = optarg; + break; + case 'l': + logfile = optarg; + break; + case 'p': + case 'P': + kdb_util_path = optarg; + break; + default: + usage(); + break; + } + } + if (optind != argc-1) + usage(); + + kset_logfile(logfile); + + klog(L_KRB_PERR, "\n\n***** kpropd started *****"); + + strcpy(local_file, argv[optind]); + strcat(strcpy(local_temp, argv[optind]), ".tmp"); + + if ((sp = getservbyname("krb_prop", "tcp")) == NULL) { + klog(L_KRB_PERR, "kpropd: tcp/krb_prop: unknown service."); + SlowDeath(); + } + bzero((char *)&sin, sizeof(sin)); + sin.sin_port = sp->s_port; + sin.sin_family = AF_INET; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + sprintf(errmsg, "kpropd: socket: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + if (bind(s, (struct sockaddr*)&sin, sizeof sin) < 0) { + sprintf(errmsg, "kpropd: bind: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + + if (!rflag) { + kerror = krb_get_lrealm(my_realm,1); + if (kerror != KSUCCESS) { + sprintf (errmsg, "kpropd: Can't get local realm. %s", + krb_err_txt[kerror]); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + } + + /* Responder uses KPROP_SERVICE_NAME.'hostname' and requestor always + uses KPROP_SERVICE_NAME.KRB_MASTER (rcmd.kerberos) */ + strcpy(my_instance, "*"); + + klog(L_KRB_PERR, "Established socket"); + + listen(s, 5); + for (;;) { + from_len = sizeof from; + if ((s2 = accept(s, (struct sockaddr *) &from, &from_len)) < 0) { + sprintf(errmsg, "kpropd: accept: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + continue; + } + strcpy(from_str, inet_ntoa(from.sin_addr)); + + if ((hp = gethostbyaddr((char*)&(from.sin_addr.s_addr), from_len, AF_INET)) == NULL) { + strcpy(hostname, "UNKNOWN"); + } else { + strcpy(hostname, hp->h_name); + } + + sprintf(errmsg, "Connection from %s, %s", hostname, from_str); + klog(L_KRB_PERR, errmsg); + + /* for krb_rd_{priv, safe} */ + n = sizeof sin; + if (getsockname (s2, (struct sockaddr *) &sin, &n) != 0) { + fprintf (stderr, "kpropd: can't get socketname.\n"); + perror ("getsockname"); + SlowDeath(); + } + if (n != sizeof (sin)) { + fprintf (stderr, "kpropd: can't get socketname. len"); + SlowDeath(); + } + + if ((fdlock = open(local_temp, O_WRONLY | O_CREAT, 0600)) < 0) { + sprintf(errmsg, "kpropd: open: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + if (flock(fdlock, LOCK_EX | LOCK_NB)) { + sprintf(errmsg, "kpropd: flock: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + if ((fd = creat(local_temp, 0600)) < 0) { + sprintf(errmsg, "kpropd: creat: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + if ((n = read (s2, buf, sizeof (kprop_version))) + != sizeof (kprop_version)) { + klog (L_KRB_PERR, "kpropd: can't read kprop protocol version str."); + SlowDeath(); + } + if (strncmp (buf, kprop_version, sizeof (kprop_version)) + != 0) { + sprintf (errmsg, "kpropd: unsupported version %s", buf); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + + if ((n = read (s2, &net_transfer_mode, sizeof (net_transfer_mode))) + != sizeof (net_transfer_mode)) { + klog (L_KRB_PERR, "kpropd: can't read transfer mode."); + SlowDeath(); + } + transfer_mode = ntohs (net_transfer_mode); + kerror = krb_recvauth(KOPT_DO_MUTUAL, s2, &ticket, + KPROP_SERVICE_NAME, + my_instance, + &from, + &sin, + &auth_dat, + srvtab, + session_sched, + version); + if (kerror != KSUCCESS) { + sprintf (errmsg, "kpropd: %s: Calling getkdata", + krb_err_txt[kerror]); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + + sprintf (errmsg, "kpropd: Connection from %s.%s@%s", + auth_dat.pname, auth_dat.pinst, auth_dat.prealm); + klog (L_KRB_PERR, errmsg); + + /* AUTHORIZATION is done here. We might want to expand this to + * read an acl file at some point, but allowing for now + * KPROP_SERVICE_NAME.KRB_MASTER@local-realm is fine ... */ + + if ((strcmp (KPROP_SERVICE_NAME, auth_dat.pname) != 0) || + (strcmp (KRB_MASTER, auth_dat.pinst) != 0) || + (strcmp (my_realm, auth_dat.prealm) != 0)) { + klog (L_KRB_PERR, "Authorization denied!"); + SlowDeath(); + } + + switch (transfer_mode) { + case KPROP_TRANSFER_PRIVATE: + recv_auth (s2, fd, 1 /* private */, &from, &sin, &auth_dat); + break; + case KPROP_TRANSFER_SAFE: + recv_auth (s2, fd, 0 /* safe */, &from, &sin, &auth_dat); + break; + case KPROP_TRANSFER_CLEAR: + recv_clear (s2, fd); + break; + default: + sprintf (errmsg, "kpropd: bad transfer mode %d", transfer_mode); + klog (L_KRB_PERR, errmsg); + SlowDeath(); + } + + if (transfer_mode != KPROP_TRANSFER_PRIVATE) { + klog(L_KRB_PERR, "kpropd: non-private transfers not supported\n"); + SlowDeath(); +#ifdef doesnt_work_yet + lseek(fd, (long) 0, L_SET); + if (auth_dat.checksum != get_data_checksum (fd, session_sched)) { + klog(L_KRB_PERR, "kpropd: checksum doesn't match"); + SlowDeath(); + } +#endif + } else + + { + struct stat st; + fstat(fd, &st); + if (st.st_size != auth_dat.checksum) { + klog(L_KRB_PERR, "kpropd: length doesn't match"); + SlowDeath(); + } + } + close(fd); + close(s2); + klog(L_KRB_PERR, "File received."); + + if (rename(local_temp, local_file) < 0) { + sprintf(errmsg, "kpropd: rename: %s", strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + klog(L_KRB_PERR, "Temp file renamed to %s", local_file); + + if (flock(fdlock, LOCK_UN)) { + sprintf(errmsg, "kpropd: flock (unlock): %s", + strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } + close(fdlock); + sprintf(cmd, "%s load %s %s\n", kdb_util_path, local_file, local_db); + if (system (cmd) != 0) { + klog (L_KRB_PERR, "Couldn't load database"); + SlowDeath(); + } + } +} + +#ifdef doesnt_work_yet +unsigned long get_data_checksum(fd, key_sched) + int fd; + des_key_schedule key_sched; +{ + unsigned long cksum = 0; + unsigned long cbc_cksum(); + int n; + char buf[BUFSIZ]; + char obuf[8]; + + while (n = read(fd, buf, sizeof buf)) { + if (n < 0) { + sprintf(errmsg, "kpropd: read (in checksum test): %s", + strerror(errno)); + klog(L_KRB_PERR, errmsg); + SlowDeath(); + } +#ifndef NOENCRYPTION + cksum += des_cbc_cksum(buf, obuf, n, key_sched, key_sched); +#endif + } + return cksum; +} +#endif diff --git a/kerberosIV/krb/Makefile b/kerberosIV/krb/Makefile new file mode 100644 index 00000000000..80fc074bfae --- /dev/null +++ b/kerberosIV/krb/Makefile @@ -0,0 +1,42 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 + +LIB= krb +CFLAGS+=-I${.CURDIR} +SRCS= cr_err_reply.c create_auth_reply.c create_ciph.c \ + create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \ + dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c get_admhst.c \ + get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c get_phost.c \ + get_pw_tkt.c get_request.c get_svc_in_tkt.c get_tf_fullname.c \ + get_tf_realm.c getrealm.c getst.c in_tkt.c k_localtime.c klog.c \ + kname_parse.c kntoln.c kparse.c krb_equiv.c krb_err.c krb_err_txt.c \ + krb_get_in_tkt.c kuserok.c lifetime.c log.c mk_err.c mk_priv.c \ + mk_req.c mk_safe.c month_sname.c netread.c netwrite.c one.c \ + pkt_cipher.c pkt_clen.c rd_err.c rd_priv.c rd_req.c rd_safe.c \ + read_service_key.c recvauth.c save_credentials.c send_to_kdc.c \ + sendauth.c str2key.c tf_util.c tkt_string.c +MAN= kerberos.3 krb_realmofhost.3 krb_sendauth.3 krb_set_tkt_string.3 \ + kuserok.3 tf_util.3 +MLINKS+=kerberos.3 krb_mk_req.3 kerberos.3 krb_rd_req.3 kerberos.3 krb_kntoln.3 \ + kerberos.3 krb_set_key.3 kerberos.3 krb_get_cred.3 kerberos.3 krb_mk_priv.3 \ + kerberos.3 krb_rd_priv.3 kerberos.3 krb_mk_safe.3 kerberos.3 krb_rd_safe.3 \ + kerberos.3 krb_mk_err.3 kerberos.3 krb_rd_err.3 kerberos.3 krb_ck_repl.3 +MLINKS+=krb_realmofhost.3 krb_get_phost.3 krb_realmofhost.3 krb_get_krbhst.3 \ + krb_realmofhost.3 krb_get_admhst.3 krb_realmofhost.3 krb_get_lrealm.3 +MLINKS+=krb_sendauth.3 krb_recvauth.3 krb_sendauth.3 krb_net_write.3 \ + krb_sendauth.3 krb_net_read.3 +MLINKS+=tf_util.3 tf_init.3 tf_util.3 tf_get_pname.3 tf_util.3 tf_get_pinst.3 \ + tf_util.3 tf_get_cred.3 tf_util.3 tf_close.3 + +LDADD+= ${COM_ERR} +CLEANFILES+= krb_err.c krb_err.h + +krb_err.c krb_err.h: krb_err.et + test -e krb_err.et || ln -s ${.CURDIR}/krb_err.et . + ${COMPILE_ET} krb_err.et + -test -h krb_err.et && rm krb_err.et + +beforeinstall: + -cd ${.OBJDIR}; cmp -s krb_err.h ${DESTDIR}/usr/include/kerberosIV/krb_err.h || \ + install -c -o ${BINOWN} -g ${BINGRP} -m 444 krb_err.h ${DESTDIR}/usr/include/kerberosIV + +.include diff --git a/kerberosIV/krb/cr_err_reply.c b/kerberosIV/krb/cr_err_reply.c new file mode 100644 index 00000000000..e2db6188ae0 --- /dev/null +++ b/kerberosIV/krb/cr_err_reply.c @@ -0,0 +1,117 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/cr_err_reply.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * req_act_vno used to be defined as an extern ("defined in server"). + * However, that does noone anything good, so we define our own so + * that the shared libraries do not turn up with an undefined variable! + */ +static int my_req_act_vno = KRB_PROT_VERSION; + +/* + * This routine is used by the Kerberos authentication server to + * create an error reply packet to send back to its client. + * + * It takes a pointer to the packet to be built, the name, instance, + * and realm of the principal, the client's timestamp, an error code + * and an error string as arguments. Its return value is undefined. + * + * The packet is built in the following format: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char req_ack_vno protocol version number + * + * unsigned char AUTH_MSG_ERR_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned long e error code + * + * string e_string error text + */ + +void +cr_err_reply(pkt, pname, pinst, prealm, time_ws, e, e_string) + KTEXT pkt; + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + u_int32_t time_ws; /* Workstation time */ + u_int32_t e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *v = (u_char *) pkt->dat; /* Prot vers number */ + u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */ + + /* Create fixed part of packet */ + *v = (unsigned char) my_req_act_vno; /* KRB_PROT_VERSION; */ + *t = (unsigned char) AUTH_MSG_ERR_REPLY; + *t |= HOST_BYTE_ORDER; + + if (pname == 0) + pname = ""; + if (pinst == 0) + pinst = ""; + if (prealm == 0) + prealm = ""; + + /* Add the basic info */ + (void) strcpy((char *) (pkt->dat+2),pname); + pkt->length = 3 + strlen(pname); + (void) strcpy((char *)(pkt->dat+pkt->length),pinst); + pkt->length += 1 + strlen(pinst); + (void) strcpy((char *)(pkt->dat+pkt->length),prealm); + pkt->length += 1 + strlen(prealm); + /* ws timestamp */ + bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err code */ + bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err text */ + (void) strcpy((char *)(pkt->dat+pkt->length),e_string); + pkt->length += 1 + strlen(e_string); + + /* And return */ + return; +} diff --git a/kerberosIV/krb/create_auth_reply.c b/kerberosIV/krb/create_auth_reply.c new file mode 100644 index 00000000000..0918470c263 --- /dev/null +++ b/kerberosIV/krb/create_auth_reply.c @@ -0,0 +1,128 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_auth_reply.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine is called by the Kerberos authentication server + * to create a reply to an authentication request. The routine + * takes the user's name, instance, and realm, the client's + * timestamp, the number of tickets, the user's key version + * number and the ciphertext containing the tickets themselves. + * It constructs a packet and returns a pointer to it. + * + * Notes: The packet returned by this routine is static. Thus, if you + * intend to keep the result beyond the next call to this routine, you + * must copy it elsewhere. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_KDC_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned char n number of tickets + * + * unsigned long x_date expiration date + * + * unsigned char kvno master key version + * + * short w_1 cipher length + * + * --- cipher->dat cipher data + */ + +KTEXT +create_auth_reply(pname, pinst, prealm, time_ws, n, x_date, kvno, cipher) + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + int32_t time_ws; /* Workstation time */ + int n; /* Number of tickets */ + u_int32_t x_date; /* Principal's expiration date */ + int kvno; /* Principal's key version number */ + KTEXT cipher; /* Cipher text with tickets and + * session keys */ +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + unsigned char *v = pkt->dat; /* Prot vers number */ + unsigned char *t = (pkt->dat+1); /* Prot message type */ + short w_l; /* Cipher length */ + + /* Create fixed part of packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REPLY; + *t |= HOST_BYTE_ORDER; + + if (n != 0) + *v = 3; + + /* Add the basic info */ + (void) strcpy((char *) (pkt->dat+2), pname); + pkt->length = 3 + strlen(pname); + (void) strcpy((char *) (pkt->dat+pkt->length),pinst); + pkt->length += 1 + strlen(pinst); + (void) strcpy((char *) (pkt->dat+pkt->length),prealm); + pkt->length += 1 + strlen(prealm); + /* Workstation timestamp */ + bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (unsigned char) n; + /* Expiration date */ + bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + + /* Now send the ciphertext and info to help decode it */ + *(pkt->dat+(pkt->length)++) = (unsigned char) kvno; + w_l = (short) cipher->length; + bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2); + pkt->length += 2; + bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length), + cipher->length); + pkt->length += cipher->length; + + /* And return the packet */ + return pkt; +} diff --git a/kerberosIV/krb/create_ciph.c b/kerberosIV/krb/create_ciph.c new file mode 100644 index 00000000000..ddc6ef72c57 --- /dev/null +++ b/kerberosIV/krb/create_ciph.c @@ -0,0 +1,122 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_ciph.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine is used by the authentication server to create + * a packet for its client, containing a ticket for the requested + * service (given in "tkt"), and some information about the ticket, + * + * Returns KSUCCESS no matter what. + * + * The length of the cipher is stored in c->length; the format of + * c->dat is as follows: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * + * 8 bytes session session key for client, service + * + * string service service name + * + * string instance service instance + * + * string realm KDC realm + * + * unsigned char life ticket lifetime + * + * unsigned char kvno service key version number + * + * unsigned char tkt->length length of following ticket + * + * data tkt->dat ticket for service + * + * 4 bytes kdc_time KDC's timestamp + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +int +create_ciph(c, session, service, instance, realm, + life, kvno, tkt, kdc_time, key) + KTEXT c; /* Text block to hold ciphertext */ + unsigned char *session; /* Session key to send to user */ + char *service; /* Service name on ticket */ + char *instance; /* Instance name on ticket */ + char *realm; /* Realm of this KDC */ + u_int32_t life; /* Lifetime of the ticket */ + int kvno; /* Key version number for service */ + KTEXT tkt; /* The ticket for the service */ + u_int32_t kdc_time; /* KDC time */ + des_cblock *key; /* Key to encrypt ciphertext with */ +{ + char *ptr; + des_key_schedule key_s; + + ptr = (char *) c->dat; + + bcopy((char *) session, ptr, 8); + ptr += 8; + + (void) strcpy(ptr,service); + ptr += strlen(service) + 1; + + (void) strcpy(ptr,instance); + ptr += strlen(instance) + 1; + + (void) strcpy(ptr,realm); + ptr += strlen(realm) + 1; + + *(ptr++) = (unsigned char) life; + *(ptr++) = (unsigned char) kvno; + *(ptr++) = (unsigned char) tkt->length; + + bcopy((char *)(tkt->dat),ptr,tkt->length); + ptr += tkt->length; + + bcopy((char *) &kdc_time,ptr,4); + ptr += 4; + + /* guarantee null padded encrypted data to multiple of 8 bytes */ + bzero(ptr, 7); + + c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8; + +#ifndef NOENCRYPTION + des_key_sched(key,key_s); + des_pcbc_encrypt((des_cblock *)c->dat,(des_cblock *)c->dat,(long) c->length,key_s, + key, DES_ENCRYPT); +#endif /* NOENCRYPTION */ + + return(KSUCCESS); +} diff --git a/kerberosIV/krb/create_death_packet.c b/kerberosIV/krb/create_death_packet.c new file mode 100644 index 00000000000..60bd7ec66cf --- /dev/null +++ b/kerberosIV/krb/create_death_packet.c @@ -0,0 +1,75 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_death_packet.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine creates a packet to type AUTH_MSG_DIE which is sent to + * the Kerberos server to make it shut down. It is used only in the + * development environment. + * + * It takes a string "a_name" which is sent in the packet. A pointer + * to the packet is returned. + * + * The format of the killer packet is: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char KRB_PROT_VERSION protocol version number + * + * unsigned char AUTH_MSG_DIE message type + * + * [least significant HOST_BYTE_ORDER byte order of sender + * bit of above field] + * + * string a_name presumably, name of + * principal sending killer + * packet + */ + +#ifdef DEBUG +KTEXT +krb_create_death_packet(a_name) + char *a_name; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + + unsigned char *v = pkt->dat; + unsigned char *t = (pkt->dat+1); + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_DIE; + *t |= HOST_BYTE_ORDER; + (void) strcpy((char *) (pkt->dat+2),a_name); + pkt->length = 3 + strlen(a_name); + return pkt; +} +#endif /* DEBUG */ diff --git a/kerberosIV/krb/create_ticket.c b/kerberosIV/krb/create_ticket.c new file mode 100644 index 00000000000..4de275badb0 --- /dev/null +++ b/kerberosIV/krb/create_ticket.c @@ -0,0 +1,141 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * Create ticket takes as arguments information that should be in a + * ticket, and the KTEXT object in which the ticket should be + * constructed. It then constructs a ticket and returns, leaving the + * newly created ticket in tkt. + * The length of the ticket is a multiple of + * eight bytes and is in tkt->length. + * + * If the ticket is too long, the ticket will contain nulls. + * The return value of the routine is undefined. + * + * The corresponding routine to extract information from a ticket it + * decomp_ticket. When changes are made to this routine, the + * corresponding changes should also be made to that file. + * + * The packet is built in the following format: + * + * variable + * type or constant data + * ---- ----------- ---- + * + * tkt->length length of ticket (multiple of 8 bytes) + * + * tkt->dat: + * + * unsigned char flags namely, HOST_BYTE_ORDER + * + * string pname client's name + * + * string pinstance client's instance + * + * string prealm client's realm + * + * 4 bytes paddress client's address + * + * 8 bytes session session key + * + * 1 byte life ticket lifetime + * + * 4 bytes time_sec KDC timestamp + * + * string sname service's name + * + * string sinstance service's instance + * + * <=7 bytes null null pad to 8 byte multiple + * + */ + +int +krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + int32_t paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + int16_t life; /* Lifetime of the ticket */ + int32_t time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + des_cblock *key; /* Service's secret key */ +{ + des_key_schedule key_s; + register char *data; /* running index into ticket */ + + tkt->length = 0; /* Clear previous data */ + flags |= HOST_BYTE_ORDER; /* ticket byte order */ + bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags)); + data = ((char *)tkt->dat) + sizeof(flags); + (void) strcpy(data, pname); + data += 1 + strlen(pname); + (void) strcpy(data, pinstance); + data += 1 + strlen(pinstance); + (void) strcpy(data, prealm); + data += 1 + strlen(prealm); + bcopy((char *) &paddress, data, 4); + data += 4; + + bcopy((char *) session, data, 8); + data += 8; + *(data++) = (char) life; + /* issue time */ + bcopy((char *) &time_sec, data, 4); + data += 4; + (void) strcpy(data, sname); + data += 1 + strlen(sname); + (void) strcpy(data, sinstance); + data += 1 + strlen(sinstance); + + /* guarantee null padded ticket to multiple of 8 bytes */ + bzero(data, 7); + tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8; + + /* Check length of ticket */ + if (tkt->length > (sizeof(KTEXT_ST) - 7)) { + bzero(tkt->dat, tkt->length); + tkt->length = 0; + return KFAILURE /* XXX */; + } + +#ifndef NOENCRYPTION + des_key_sched(key,key_s); + des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length, + key_s,key, DES_ENCRYPT); +#endif + return 0; +} diff --git a/kerberosIV/krb/debug_decl.c b/kerberosIV/krb/debug_decl.c new file mode 100644 index 00000000000..97ab1acba38 --- /dev/null +++ b/kerberosIV/krb/debug_decl.c @@ -0,0 +1,33 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/debug_decl.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* Declare global debugging variables. */ + +int krb_ap_req_debug = 0; +int krb_debug = 0; diff --git a/kerberosIV/krb/decomp_ticket.c b/kerberosIV/krb/decomp_ticket.c new file mode 100644 index 00000000000..c8778dc0807 --- /dev/null +++ b/kerberosIV/krb/decomp_ticket.c @@ -0,0 +1,134 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/decomp_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine takes a ticket and pointers to the variables that + * should be filled in based on the information in the ticket. It + * fills in values for its arguments. + * + * Note: if the client realm field in the ticket is the null string, + * then the "prealm" variable is filled in with the local realm (as + * defined by KRB_REALM). + * + * If the ticket byte order is different than the host's byte order + * (as indicated by the byte order bit of the "flags" field), then + * the KDC timestamp "time_sec" is byte-swapped. The other fields + * potentially affected by byte order, "paddress" and "session" are + * not byte-swapped. + * + * The routine returns KFAILURE if any of the "pname", "pinstance", + * or "prealm" fields is too big, otherwise it returns KSUCCESS. + * + * The corresponding routine to generate tickets is create_ticket. + * When changes are made to this routine, the corresponding changes + * should also be made to that file. + * + * See create_ticket.c for the format of the ticket packet. + */ + +int +decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + u_int32_t *paddress; /* Net address of entity + * requesting ticket */ + unsigned char *session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + u_int32_t *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + des_cblock *key; /* Service's secret key + * (to decrypt the ticket) */ + struct des_ks_struct *key_s; /* The precomputed key schedule */ +{ + static int tkt_swap_bytes; + unsigned char *uptr; + char *ptr = (char *)tkt->dat; + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length, + key_s,key, DES_DECRYPT); +#endif /* ! NOENCRYPTION */ + + *flags = *ptr; /* get flags byte */ + ptr += sizeof(*flags); + tkt_swap_bytes = 0; + if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1)) + tkt_swap_bytes++; + + if (strlen(ptr) > ANAME_SZ) + return(KFAILURE); + (void) strcpy(pname,ptr); /* pname */ + ptr += strlen(pname) + 1; + + if (strlen(ptr) > INST_SZ) + return(KFAILURE); + (void) strcpy(pinstance,ptr); /* instance */ + ptr += strlen(pinstance) + 1; + + if (strlen(ptr) > REALM_SZ) + return(KFAILURE); + (void) strcpy(prealm,ptr); /* realm */ + ptr += strlen(prealm) + 1; + /* temporary hack until realms are dealt with properly */ + if (*prealm == 0) + (void) strcpy(prealm,KRB_REALM); + + bcopy(ptr,(char *)paddress,4); /* net address */ + ptr += 4; + + bcopy(ptr,(char *)session,8); /* session key */ + ptr+= 8; +#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */ + if (tkt_swap_bytes) + swap_C_Block(session); +#endif + + /* get lifetime, being certain we don't get negative lifetimes */ + uptr = (unsigned char *) ptr++; + *life = (int) *uptr; + + bcopy(ptr,(char *) time_sec,4); /* issue time */ + ptr += 4; + if (tkt_swap_bytes) + swap_u_long(*time_sec); + + (void) strcpy(sname,ptr); /* service name */ + ptr += 1 + strlen(sname); + + (void) strcpy(sinstance,ptr); /* instance */ + ptr += 1 + strlen(sinstance); + return(KSUCCESS); +} diff --git a/kerberosIV/krb/dest_tkt.c b/kerberosIV/krb/dest_tkt.c new file mode 100644 index 00000000000..1f6d83a3ae6 --- /dev/null +++ b/kerberosIV/krb/dest_tkt.c @@ -0,0 +1,100 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/dest_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include +#ifdef TKT_SHMEM +#include +#endif + +/* + * dest_tkt() is used to destroy the ticket store upon logout. + * If the ticket file does not exist, dest_tkt() returns RET_TKFIL. + * Otherwise the function returns RET_OK on success, KFAILURE on + * failure. + * + * The ticket file (TKT_FILE) is defined in "krb.h". + */ + +int +dest_tkt() +{ + char *file = TKT_FILE; + int i,fd; + struct stat statb; + char buf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MaxPathLen]; +#endif /* TKT_SHMEM */ + + errno = 0; + if (lstat(file,&statb) < 0) + goto out; + + if (!(statb.st_mode & S_IFREG) +#ifdef notdef + || statb.st_mode & 077 +#endif + ) + goto out; + + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; + + bzero(buf, BUFSIZ); + + for (i = 0; i < statb.st_size; i += BUFSIZ) + if (write(fd, buf, BUFSIZ) != BUFSIZ) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + + (void) unlink(file); + +out: + if (errno == ENOENT) return RET_TKFIL; + else if (errno != 0) return KFAILURE; +#ifdef TKT_SHMEM + /* + * handle the shared memory case + */ + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + if ((i = krb_shm_dest(shmidname)) != KSUCCESS) + return(i); +#endif /* TKT_SHMEM */ + return(KSUCCESS); +} diff --git a/kerberosIV/krb/extract_ticket.c b/kerberosIV/krb/extract_ticket.c new file mode 100644 index 00000000000..a3cd8775c14 --- /dev/null +++ b/kerberosIV/krb/extract_ticket.c @@ -0,0 +1,71 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/extract_ticket.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine is obsolete. + * + * This routine accepts the ciphertext returned by kerberos and + * extracts the nth ticket. It also fills in the variables passed as + * session, liftime and kvno. + */ + +void +extract_ticket(cipher, n, session, lifetime, kvno, realm, ticket) + KTEXT cipher; /* The ciphertext */ + int n; /* Which ticket */ + char *session; /* The session key for this tkt */ + int *lifetime; /* The life of this ticket */ + int *kvno; /* The kvno for the service */ + char *realm; /* Realm in which tkt issued */ + KTEXT ticket; /* The ticket itself */ +{ + char *ptr; + int i; + + /* Start after the ticket lengths */ + ptr = (char *) cipher->dat; + ptr = ptr + 1 + (int) *(cipher->dat); + + /* Step through earlier tickets */ + for (i = 1; i < n; i++) + ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i); + bcopy(ptr, (char *) session, 8); /* Save the session key */ + ptr += 8; + *lifetime = (unsigned char) *(ptr++); /* Save the life of the ticket */ + *kvno = *(ptr++); /* Save the kvno */ + (void) strcpy(realm,ptr); /* instance */ + ptr += strlen(realm) + 1; + + /* Save the ticket if its length is non zero */ + ticket->length = *(cipher->dat+n); + if (ticket->length) + bcopy(ptr, (char *) (ticket->dat), ticket->length); +} diff --git a/kerberosIV/krb/fgetst.c b/kerberosIV/krb/fgetst.c new file mode 100644 index 00000000000..46319bd1ac0 --- /dev/null +++ b/kerberosIV/krb/fgetst.c @@ -0,0 +1,55 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/fgetst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * fgetst takes a file descriptor, a character pointer, and a count. + * It reads from the file it has either read "count" characters, or + * until it reads a null byte. When finished, what has been read exists + * in "s". If "count" characters were actually read, the last is changed + * to a null, so the returned string is always null-terminated. fgetst + * returns the number of characters read, including the null terminator. + */ + +int +fgetst(f, s, n) + FILE *f; + register char *s; + int n; +{ + register count = n; + int ch; /* NOT char; otherwise you don't see EOF */ + + while ((ch = getc(f)) != EOF && ch && --count) { + *s++ = ch; + } + *s = '\0'; + return (n - count); +} diff --git a/kerberosIV/krb/get_ad_tkt.c b/kerberosIV/krb/get_ad_tkt.c new file mode 100644 index 00000000000..fe5b7fd3f13 --- /dev/null +++ b/kerberosIV/krb/get_ad_tkt.c @@ -0,0 +1,278 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_ad_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +static int swap_bytes; + +/* + * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of + * its ciphertext portion. The external variable "swap_bytes" is assumed + * to have been set to indicate whether or not the packet is in local + * byte order. pkt_clen() takes this into account when reading the + * ciphertext length out of the packet. + */ + +static int +pkt_clen(pkt) + KTEXT pkt; +{ + static unsigned short temp,temp2; + int clen = 0; + + /* Start of ticket list */ + unsigned char *ptr = pkt_a_realm(pkt) + 10 + + strlen((char *)pkt_a_realm(pkt)); + + /* Finally the length */ + bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */ + if (swap_bytes) { + /* assume a short is 2 bytes?? */ + swab((char *)&temp,(char *)&temp2,2); + temp = temp2; + } + + clen = (int) temp; + + if (krb_debug) + printf("Clen is %d\n",clen); + return(clen); +} + +/* use the bsd time.h struct defs for PC too! */ +#include +#include + +static struct timeval tt_local = { 0, 0 }; +static unsigned long rep_err_code; + +/* + * get_ad_tkt obtains a new service ticket from Kerberos, using + * the ticket-granting ticket which must be in the ticket file. + * It is typically called by krb_mk_req() when the client side + * of an application is creating authentication information to be + * sent to the server side. + * + * get_ad_tkt takes four arguments: three pointers to strings which + * contain the name, instance, and realm of the service for which the + * ticket is to be obtained; and an integer indicating the desired + * lifetime of the ticket. + * + * It returns an error status if the ticket couldn't be obtained, + * or AD_OK if all went well. The ticket is stored in the ticket + * cache. + * + * The request sent to the Kerberos ticket-granting service looks + * like this: + * + * pkt->dat + * + * TEXT original contents of authenticator+ticket + * pkt->dat built in krb_mk_req call + * + * 4 bytes time_ws always 0 (?) + * char lifetime lifetime argument passed + * string service service name argument + * string sinstance service instance arg. + * + * See "prot.h" for the reply packet layout and definitions of the + * extraction macros like pkt_version(), pkt_msg_type(), etc. + */ + +int +get_ad_tkt(service, sinstance, realm, lifetime) + char *service; + char *sinstance; + char *realm; + int lifetime; +{ + static KTEXT_ST pkt_st; + KTEXT pkt = & pkt_st; /* Packet to KDC */ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + static KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + static KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + des_cblock ses; /* Session key for tkt */ + CREDENTIALS cr; + int kvno; /* Kvno for session key */ + char lrealm[REALM_SZ]; + des_cblock key; /* Key for decrypting cipher */ + des_key_schedule key_s; + long time_ws = 0; + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + int msg_byte_order; + int kerror; + char rlm[REALM_SZ]; + char *ptr; + + unsigned long kdc_time; /* KDC time */ + + if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS) + return(kerror); + + /* Create skeleton of packet to be sent */ + (void) gettimeofday(&tt_local,(struct timezone *) 0); + + pkt->length = 0; + + /* + * Look for the session key (and other stuff we don't need) + * in the ticket file for krbtgt.realm@lrealm where "realm" + * is the service's realm (passed in "realm" argument) and + * lrealm is the realm of our initial ticket. If we don't + * have this, we will try to get it. + */ + + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) { + /* + * If realm == lrealm, we have no hope, so let's not even try. + */ + if ((strncmp(realm, lrealm, REALM_SZ)) == 0) + return(AD_NOTGT); + else{ + if ((kerror = + get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS) + return(kerror); + if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) + return(kerror); + } + } + + /* + * Make up a request packet to the "krbtgt.realm@lrealm". + * Start by calling krb_mk_req() which puts ticket+authenticator + * into "pkt". Then tack other stuff on the end. + */ + + kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L); + + if (kerror) + return(AD_NOTGT); + + /* timestamp */ + bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4); + pkt->length += 4; + *(pkt->dat+(pkt->length)++) = (char) lifetime; + (void) strcpy((char *) (pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* Send the request to the local ticket-granting server */ + if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION ) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) + swap_bytes++; + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4); + if (swap_bytes) + swap_u_long(rep_err_code); + return(rep_err_code); + + default: + return(INTK_PROT); + } + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length); + +#ifndef NOENCRYPTION + /* Attempt to decrypt it */ + + des_key_sched(&cr.session,key_s); + if (krb_debug) printf("About to do decryption ..."); + des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)cip->dat, + (long) cip->length,key_s,&cr.session,0); +#endif /* !NOENCRYPTION */ + /* Get rid of all traces of key */ + bzero((char *) cr.session, sizeof(key)); + bzero((char *) key_s, sizeof(key_s)); + + ptr = (char *) cip->dat; + + bcopy(ptr,(char *)ses,8); + ptr += 8; + + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + lifetime = (unsigned char) ptr[0]; + kvno = (unsigned long) ptr[1]; + tkt->length = (int) ptr[2]; + ptr += 3; + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&tt_local,(struct timezone *) 0); + if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + if ((kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime, + kvno,tkt,tt_local.tv_sec))) + return(kerror); + + return(AD_OK); +} diff --git a/kerberosIV/krb/get_admhst.c b/kerberosIV/krb/get_admhst.c new file mode 100644 index 00000000000..1aedd738a10 --- /dev/null +++ b/kerberosIV/krb/get_admhst.c @@ -0,0 +1,98 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_admhst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * Given a Kerberos realm, find a host on which the Kerberos database + * administration server can be found. + * + * krb_get_admhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer n, and + * returns (in h) the nth administrative host entry from the configuration + * file (KRB_CONF, defined in "krb.h") associated with the specified realm. + * + * On error, get_admhst returns KFAILURE. If all goes well, the routine + * returns KSUCCESS. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + * + * This is a temporary hack to allow us to find the nearest system running + * a Kerberos admin server. In the long run, this functionality will be + * provided by a nameserver. + */ + +int +krb_get_admhst(h, r, n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + char scratch[64]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"r")) == NULL) + return(KFAILURE); + } + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + /* error reading */ + (void) fclose(cnffile); + return(KFAILURE); + } + if (!strchr(linebuf, '\n')) { + /* didn't all fit into buffer, punt */ + (void) fclose(cnffile); + return(KFAILURE); + } + for (i = 0; i < n; ) { + /* run through the file, looking for admin host */ + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + /* need to scan for a token after 'admin' to make sure that + admin matched correctly */ + if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/kerberosIV/krb/get_cred.c b/kerberosIV/krb/get_cred.c new file mode 100644 index 00000000000..a301af4a1f7 --- /dev/null +++ b/kerberosIV/krb/get_cred.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_cred.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * krb_get_cred takes a service name, instance, and realm, and a + * structure of type CREDENTIALS to be filled in with ticket + * information. It then searches the ticket file for the appropriate + * ticket and fills in the structure with the corresponding + * information from the file. If successful, it returns KSUCCESS. + * On failure it returns a Kerberos error code. + */ + +int +krb_get_cred(service, instance, realm, c) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + CREDENTIALS *c; /* Credentials struct */ +{ + int tf_status; /* return value of tf function calls */ + + /* Open ticket file and lock it for shared reading */ + if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Copy principal's name and instance into the CREDENTIALS struc c */ + + if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS || + (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS ) + return (tf_status); + + /* Search for requested service credentials and copy into c */ + + while ((tf_status = tf_get_cred(c)) == KSUCCESS) { + /* Is this the right ticket? */ + if ((strcmp(c->service,service) == 0) && + (strcmp(c->instance,instance) == 0) && + (strcmp(c->realm,realm) == 0)) + break; + } + (void) tf_close(); + + if (tf_status == EOF) + return (GC_NOTKT); + return(tf_status); +} diff --git a/kerberosIV/krb/get_in_tkt.c b/kerberosIV/krb/get_in_tkt.c new file mode 100644 index 00000000000..7e5f1addd22 --- /dev/null +++ b/kerberosIV/krb/get_in_tkt.c @@ -0,0 +1,319 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This file contains two routines: passwd_to_key() converts + * a password into a DES key (prompting for the password if + * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for + * a user. + */ + +/* + * passwd_to_key(): given a password, return a DES key. + * There are extra arguments here which (used to be?) + * used by srvtab_to_key(). + * + * If the "passwd" argument is not null, generate a DES + * key from it, using string_to_key(). + * + * If the "passwd" argument is null, call des_read_password() + * to prompt for a password and then convert it into a DES key. + * + * In either case, the resulting key is put in the "key" argument, + * and 0 is returned. + */ + +/*ARGSUSED */ +static int +passwd_to_key(user, instance, realm, passwd, key) + char *user; + char *instance; + char *realm; + char *passwd; + des_cblock *key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else + if (passwd) + des_string_to_key(passwd,key); + else + des_read_password(key,"Password: ",0); +#endif + return (0); +} + +/*ARGSUSED */ +static int +afs_passwd_to_key(user, instance, realm, passwd, key) + char *user; + char *instance; + char *realm; + char *passwd; + des_cblock *key; +{ +#ifdef NOENCRYPTION + if (!passwd) + placebo_read_password(key, "Password: ", 0); +#else /* Do encyryption */ + if (passwd) + afs_string_to_key(passwd, realm, key); + else { + des_read_password(key, "Password: ", 0); + } +#endif /* NOENCRYPTION */ + return (0); +} + +/* + * krb_get_pw_in_tkt() takes the name of the server for which the initial + * ticket is to be obtained, the name of the principal the ticket is + * for, the desired lifetime of the ticket, and the user's password. + * It passes its arguments on to krb_get_in_tkt(), which contacts + * Kerberos to get the ticket, decrypts it using the password provided, + * and stores it away for future use. + * + * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt(): + * the name of a routine (passwd_to_key()) to be used to get the + * password in case the "password" argument is null and NULL for the + * decryption procedure indicating that krb_get_in_tkt should use the + * default method of decrypting the response from the KDC. + * + * The result of the call to krb_get_in_tkt() is returned. + */ + +int +krb_get_pw_in_tkt(user, instance, realm, service, sinstance, life, password) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + char *password; +{ + char pword[100]; /* storage for the password */ + int code; + + /* Only request password once! */ + if (!password) { + if (des_read_pw_string(pword, sizeof(pword)-1, "Password: ", 0)) + pword[0] = '\0'; /* something wrong */ + password = pword; + } + + code = krb_get_in_tkt(user,instance,realm,service,sinstance,life, + passwd_to_key, NULL, password); + if (code != INTK_BADPW) + goto done; + + code = krb_get_in_tkt(user,instance,realm,service,sinstance,life, + afs_passwd_to_key, NULL, password); + if (code != INTK_BADPW) + goto done; + + done: + if (password == pword) + bzero(pword, sizeof(pword)); + return(code); +} + +#ifdef NOENCRYPTION +/* + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_in_tkt.c,v $ + * $Author: tholo $ + * + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * + * For copying and distribution information, please see the file + * . + * + * 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/kerberosIV/krb/Attic/get_in_tkt.c,v 1.1.1.1 1995/12/14 06:52:39 tholo Exp $"; +#endif /* lint */ + +#include +#include "conf.h" + +#include +#include +#include +#include +#include + +static jmp_buf env; + +static void sig_restore(); +static push_signals(), pop_signals(); +int placebo_read_pw_string(); + +/*** Routines ****************************************************** */ +int +placebo_read_password(k,prompt,verify) + des_cblock *k; + char *prompt; + int verify; +{ + int ok; + char key_string[BUFSIZ]; + + if (setjmp(env)) { + ok = -1; + goto lose; + } + + ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify); + if (ok == 0) + bzero(k, sizeof(C_Block)); + +lose: + bzero(key_string, sizeof (key_string)); + return ok; +} + +/* + * This version just returns the string, doesn't map to key. + * + * Returns 0 on success, non-zero on failure. + */ + +int +placebo_read_pw_string(s,max,prompt,verify) + char *s; + int max; + char *prompt; + int verify; +{ + int ok = 0; + char *ptr; + + jmp_buf old_env; + struct sgttyb tty_state; + char key_string[BUFSIZ]; + + if (max > BUFSIZ) { + return -1; + } + + bcopy(old_env, env, sizeof(env)); + if (setjmp(env)) + goto lose; + + /* save terminal state*/ + if (ioctl(0,TIOCGETP,&tty_state) == -1) + return -1; + + push_signals(); + /* Turn off echo */ + tty_state.sg_flags &= ~ECHO; + if (ioctl(0,TIOCSETP,&tty_state) == -1) + return -1; + while (!ok) { + printf(prompt); + fflush(stdout); + if (!fgets(s, max, stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(s, '\n'))) + *ptr = '\0'; + if (verify) { + printf("\nVerifying, please re-enter %s",prompt); + fflush(stdout); + if (!fgets(key_string, sizeof(key_string), stdin)) { + clearerr(stdin); + continue; + } + if ((ptr = index(key_string, '\n'))) + *ptr = '\0'; + if (strcmp(s,key_string)) { + printf("\n\07\07Mismatch - try again\n"); + fflush(stdout); + continue; + } + } + ok = 1; + } + +lose: + if (!ok) + bzero(s, max); + printf("\n"); + /* turn echo back on */ + tty_state.sg_flags |= ECHO; + if (ioctl(0,TIOCSETP,&tty_state)) + ok = 0; + pop_signals(); + bcopy(env, old_env, sizeof(env)); + if (verify) + bzero(key_string, sizeof (key_string)); + s[max-1] = 0; /* force termination */ + return !ok; /* return nonzero if not okay */ +} + +/* + * this can be static since we should never have more than + * one set saved.... + */ +static RETSIGTYPE (*old_sigfunc[NSIG])(); + +static +push_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + old_sigfunc[i] = signal(i,sig_restore); +} + +static +pop_signals() +{ + register i; + for (i = 0; i < NSIG; i++) + signal(i,old_sigfunc[i]); +} + +static void +sig_restore(sig,code,scp) + int sig,code; + struct sigcontext *scp; +{ + longjmp(env,1); +} +#endif /* NOENCRYPTION */ diff --git a/kerberosIV/krb/get_krbhst.c b/kerberosIV/krb/get_krbhst.c new file mode 100644 index 00000000000..3b386c87393 --- /dev/null +++ b/kerberosIV/krb/get_krbhst.c @@ -0,0 +1,103 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_krbhst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * Given a Kerberos realm, find a host on which the Kerberos authenti- + * cation server can be found. + * + * krb_get_krbhst takes a pointer to be filled in, a pointer to the name + * of the realm for which a server is desired, and an integer, n, and + * returns (in h) the nth entry from the configuration file (KRB_CONF, + * defined in "krb.h") associated with the specified realm. + * + * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the + * configuration file does not exist, krb_get_krbhst will return KRB_HOST + * (also defined in "krb.h"). If all goes well, the routine returnes + * KSUCCESS. + * + * The KRB_CONF file contains the name of the local realm in the first + * line (not used by this routine), followed by lines indicating realm/host + * entries. The words "admin server" following the hostname indicate that + * the host provides an administrative database server. + * + * For example: + * + * ATHENA.MIT.EDU + * ATHENA.MIT.EDU kerberos-1.mit.edu admin server + * ATHENA.MIT.EDU kerberos-2.mit.edu + * LCS.MIT.EDU kerberos.lcs.mit.edu admin server + * + * This is a temporary hack to allow us to find the nearest system running + * kerberos. In the long run, this functionality will be provided by a + * nameserver. + */ + +int +krb_get_krbhst(h, r, n) + char *h; + char *r; + int n; +{ + FILE *cnffile; + char tr[REALM_SZ]; + char linebuf[BUFSIZ]; + register int i; + + if ((cnffile = fopen(KRB_CONF,"r")) == NULL) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"r")) == NULL) + if (n==1) { + (void) strcpy(h,KRB_HOST); + return(KSUCCESS); + } + else + return(KFAILURE); + } + if (fscanf(cnffile,"%s",tr) == EOF) + return(KFAILURE); + /* run through the file, looking for the nth server for this realm */ + for (i = 1; i <= n;) { + if (fgets(linebuf, BUFSIZ, cnffile) == NULL) { + (void) fclose(cnffile); + return(KFAILURE); + } + if (sscanf(linebuf, "%s %s", tr, h) != 2) + continue; + if (!strcmp(tr,r)) + i++; + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/kerberosIV/krb/get_krbrlm.c b/kerberosIV/krb/get_krbrlm.c new file mode 100644 index 00000000000..1c8ea6e81c0 --- /dev/null +++ b/kerberosIV/krb/get_krbrlm.c @@ -0,0 +1,78 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_krbrlm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * krb_get_lrealm takes a pointer to a string, and a number, n. It fills + * in the string, r, with the name of the nth realm specified on the + * first line of the kerberos config file (KRB_CONF, defined in "krb.h"). + * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the + * config file does not exist, and if n=1, a successful return will occur + * with r = KRB_REALM (also defined in "krb.h"). + * + * NOTE: for archaic & compatibility reasons, this routine will only return + * valid results when n = 1. + * + * For the format of the KRB_CONF file, see comments describing the routine + * krb_get_krbhst(). + */ + +int +krb_get_lrealm(r, n) + char *r; + int n; +{ + FILE *cnffile; + + if (n > 1) + return(KFAILURE); /* Temporary restriction */ + + if ((cnffile = fopen(KRB_CONF, "r")) == NULL) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.conf", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((cnffile = fopen(tbuf,"r")) == NULL) + if (n == 1) { + (void) strcpy(r, KRB_REALM); + return(KSUCCESS); + } + else + return(KFAILURE); + } + + if (fscanf(cnffile,"%s",r) != 1) { + (void) fclose(cnffile); + return(KFAILURE); + } + (void) fclose(cnffile); + return(KSUCCESS); +} diff --git a/kerberosIV/krb/get_phost.c b/kerberosIV/krb/get_phost.c new file mode 100644 index 00000000000..81f7c05aea1 --- /dev/null +++ b/kerberosIV/krb/get_phost.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_phost.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define USE_FULL_HOST_NAME 0 + +#include +#include + +/* + * This routine takes an alias for a host name and returns the first + * field, lower case, of its domain name. For example, if "menel" is + * an alias for host officially named "menelaus" (in /etc/hosts), for + * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus" + * is returned. + * + * This is done for historical Athena reasons: the Kerberos name of + * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm" + * where "host"is the lowercase for of the host name ("menelaus"). + * This should go away: the instance should be the domain name + * (MENELAUS.MIT.EDU). But for now we need this routine... + * + * A pointer to the name is returned, if found, otherwise a pointer + * to the original "alias" argument is returned. + */ + +char * +krb_get_phost(alias) + char *alias; +{ + struct hostent *h; + char *phost = alias; + if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) { +#if USE_FULL_HOST_NAME + char *p; +#else /* USE_FULL_HOST_NAME */ + char *p = strchr( h->h_name, '.' ); + if (p) + *p = 0; +#endif /* USE_FULL_HOST_NAME */ + p = phost = h->h_name; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/kerberosIV/krb/get_pw_tkt.c b/kerberosIV/krb/get_pw_tkt.c new file mode 100644 index 00000000000..a94ff237f52 --- /dev/null +++ b/kerberosIV/krb/get_pw_tkt.c @@ -0,0 +1,86 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_pw_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * Get a ticket for the password-changing server ("changepw.KRB_MASTER"). + * + * Given the name, instance, realm, and current password of the + * principal for which the user wants a password-changing-ticket, + * return either: + * + * GT_PW_BADPW if current password was wrong, + * GT_PW_NULL if principal had a NULL password, + * or the result of the krb_get_pw_in_tkt() call. + * + * First, try to get a ticket for "user.instance@realm" to use the + * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h"). + * The requested lifetime for the ticket is "1", and the current + * password is the "cpw" argument given. + * + * If the password was bad, give up. + * + * If the principal had a NULL password in the Kerberos database + * (indicating that the principal is known to Kerberos, but hasn't + * got a password yet), try instead to get a ticket for the principal + * "default.changepw@realm" to use the "changepw.KRB_MASTER" server. + * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL + * if all goes well, otherwise the error. + * + * If this routine succeeds, a ticket and session key for either the + * principal "user.instance@realm" or "default.changepw@realm" to use + * the password-changing server will be in the user's ticket file. + */ + +int +get_pw_tkt(user, instance, realm, cpw) + char *user; + char *instance; + char *realm; + char *cpw; +{ + int kerror; + + kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw", + KRB_MASTER, 1, cpw); + + if (kerror == INTK_BADPW) + return(GT_PW_BADPW); + + if (kerror == KDC_NULL_KEY) { + kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw", + KRB_MASTER,1,"changepwkrb"); + if (kerror) + return(kerror); + return(GT_PW_NULL); + } + + return(kerror); +} diff --git a/kerberosIV/krb/get_request.c b/kerberosIV/krb/get_request.c new file mode 100644 index 00000000000..b7bf0083b1e --- /dev/null +++ b/kerberosIV/krb/get_request.c @@ -0,0 +1,66 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_request.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This procedure is obsolete. It is used in the kerberos_slave + * code for Version 3 tickets. + * + * This procedure sets s_name, and instance to point to + * the corresponding fields from tne nth request in the packet. + * it returns the lifetime requested. Garbage will be returned + * if there are less than n requests in the packet. + */ + +int +get_request(pkt, n, s_name, instance) + KTEXT pkt; /* The packet itself */ + int n; /* Which request do we want */ + char **s_name; /* Service name to be filled in */ + char **instance; /* Instance name to be filled in */ +{ + /* Go to the beginning of the request list */ + char *ptr = (char *) pkt_a_realm(pkt) + 6 + + strlen((char *)pkt_a_realm(pkt)); + + /* Read requests until we hit the right one */ + while (n-- > 1) { + ptr++; + ptr += 1 + strlen(ptr); + ptr += 1 + strlen(ptr); + } + + /* Set the arguments to point to the right place */ + *s_name = 1 + ptr; + *instance = 2 + ptr + strlen(*s_name); + + /* Return the requested lifetime */ + return((int) *ptr); +} diff --git a/kerberosIV/krb/get_svc_in_tkt.c b/kerberosIV/krb/get_svc_in_tkt.c new file mode 100644 index 00000000000..dd388c26a12 --- /dev/null +++ b/kerberosIV/krb/get_svc_in_tkt.c @@ -0,0 +1,92 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_svc_in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This file contains two routines: srvtab_to_key(), which gets + * a server's key from a srvtab file, and krb_get_svc_in_tkt() which + * gets an initial ticket for a server. + */ + +/* + * srvtab_to_key(): given a "srvtab" file (where the keys for the + * service on a host are stored), return the private key of the + * given service (user.instance@realm). + * + * srvtab_to_key() passes its arguments on to read_service_key(), + * plus one additional argument, the key version number. + * (Currently, the key version number is always 0; this value + * is treated as a wildcard by read_service_key().) + * + * If the "srvtab" argument is null, KEYFILE (defined in "krb.h") + * is passed in its place. + * + * It returns the return value of the read_service_key() call. + * The service key is placed in "key". + */ + +static int +srvtab_to_key(user, instance, realm, srvtab, key) + char *user; + char *instance; + char *realm; + char *srvtab; + unsigned char *key; +{ + if (!srvtab) + srvtab = KEYFILE; + + return(read_service_key(user, instance, realm, 0, srvtab, + (char *)key)); +} + +/* + * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(), + * plus two additional arguments: a pointer to the srvtab_to_key() + * function to be used to get the key from the key file and a NULL + * for the decryption procedure indicating that krb_get_in_tkt should + * use the default method of decrypting the response from the KDC. + * + * It returns the return value of the krb_get_in_tkt() call. + */ + +int +krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + char *srvtab; +{ + return(krb_get_in_tkt(user, instance, realm, service, sinstance, + life, srvtab_to_key, NULL, srvtab)); +} diff --git a/kerberosIV/krb/get_tf_fullname.c b/kerberosIV/krb/get_tf_fullname.c new file mode 100644 index 00000000000..13b64d3ffbd --- /dev/null +++ b/kerberosIV/krb/get_tf_fullname.c @@ -0,0 +1,80 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_tf_fullname.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This file contains a routine to extract the fullname of a user + * from the ticket file. + */ + +/* + * krb_get_tf_fullname() takes four arguments: the name of the + * ticket file, and variables for name, instance, and realm to be + * returned in. Since the realm of a ticket file is not really fully + * supported, the realm used will be that of the the first ticket in + * the file as this is the one that was obtained with a password by + * krb_get_in_tkt(). + */ + +int +krb_get_tf_fullname(ticket_file, name, instance, realm) + char *ticket_file; + char *name; + char *instance; + char *realm; +{ + int tf_status; + CREDENTIALS c; + + if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS) + return(tf_status); + + if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) || + ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS)) + return (tf_status); + + if (name) + strcpy(name, c.pname); + if (instance) + strcpy(instance, c.pinst); + if ((tf_status = tf_get_cred(&c)) == KSUCCESS) { + if (realm) + strcpy(realm, c.realm); + } + else { + if (tf_status == EOF) + return(KFAILURE); + else + return(tf_status); + } + (void) tf_close(); + + return(tf_status); +} diff --git a/kerberosIV/krb/get_tf_realm.c b/kerberosIV/krb/get_tf_realm.c new file mode 100644 index 00000000000..0195fc77876 --- /dev/null +++ b/kerberosIV/krb/get_tf_realm.c @@ -0,0 +1,49 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_tf_realm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This file contains a routine to extract the realm of a kerberos + * ticket file. + */ + +/* + * krb_get_tf_realm() takes two arguments: the name of a ticket + * and a variable to store the name of the realm in. + * + */ + +int +krb_get_tf_realm(ticket_file, realm) + char *ticket_file; + char *realm; +{ + return(krb_get_tf_fullname(ticket_file, 0, 0, realm)); +} diff --git a/kerberosIV/krb/getrealm.c b/kerberosIV/krb/getrealm.c new file mode 100644 index 00000000000..f4bd245e59a --- /dev/null +++ b/kerberosIV/krb/getrealm.c @@ -0,0 +1,132 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/getrealm.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define MATCH_SUBDOMAINS 0 + +/* for Ultrix and friends ... */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +/* + * krb_realmofhost. + * Given a fully-qualified domain-style primary host name, + * return the name of the Kerberos realm for the host. + * If the hostname contains no discernable domain, or an error occurs, + * return the local realm name, as supplied by get_krbrlm(). + * If the hostname contains a domain, but no translation is found, + * the hostname's domain is converted to upper-case and returned. + * + * The format of each line of the translation file is: + * domain_name kerberos_realm + * -or- + * host_name kerberos_realm + * + * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU) + * host names should be in the usual form (e.g. FOO.BAR.BAZ) + */ + +static char ret_realm[REALM_SZ+1]; + +char * +krb_realmofhost(host) + char *host; +{ + char *domain; + FILE *trans_file; + char trans_host[MAXHOSTNAMELEN+1]; + char trans_realm[REALM_SZ+1]; + int retval; + + domain = strchr(host, '.'); + + /* prepare default */ + if (domain) { + char *cp; + + strncpy(ret_realm, &domain[1], REALM_SZ); + ret_realm[REALM_SZ] = '\0'; + /* Upper-case realm */ + for (cp = ret_realm; *cp; cp++) + if (islower(*cp)) + *cp = toupper(*cp); + } else { + krb_get_lrealm(ret_realm, 1); + } + + if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) { + char tbuf[128]; + char *tdir = (char *) getenv("KRBCONFDIR"); + strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf)); + strncat(tbuf, "/krb.realms", sizeof(tbuf)); + tbuf[sizeof(tbuf)-1] = 0; + if ((trans_file = fopen(tbuf,"r")) == NULL) + return(ret_realm); /* krb_errno = KRB_NO_TRANS */ + } + while (1) { + if ((retval = fscanf(trans_file, "%s %s", + trans_host, trans_realm)) != 2) { + if (retval == EOF) { + fclose(trans_file); + return(ret_realm); + } + continue; /* ignore broken lines */ + } + trans_host[MAXHOSTNAMELEN] = '\0'; + trans_realm[REALM_SZ] = '\0'; + if (!strcasecmp(trans_host, host)) { + /* exact match of hostname, so return the realm */ + (void) strcpy(ret_realm, trans_realm); + fclose(trans_file); + return(ret_realm); + } + if ((trans_host[0] == '.') && domain) { +#if MATCH_SUBDOMAINS + char *cp; + for (cp = domain; cp != NULL; cp = strchr(cp+1, '.')) { + /* this is a domain match */ + if (!strcasecmp(trans_host, cp)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } + } +#else /* MATCH_SUBDOMAINS */ + /* this is a domain match */ + if (!strcasecmp(trans_host, domain)) { + /* domain match, save for later */ + (void) strcpy(ret_realm, trans_realm); + continue; + } +#endif /* MATCH_SUBDOMAINS */ + } + } +} diff --git a/kerberosIV/krb/getst.c b/kerberosIV/krb/getst.c new file mode 100644 index 00000000000..fa3d2333f4c --- /dev/null +++ b/kerberosIV/krb/getst.c @@ -0,0 +1,54 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/getst.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * getst() takes a file descriptor, a string and a count. It reads + * from the file until either it has read "count" characters, or until + * it reads a null byte. When finished, what has been read exists in + * the given string "s". If "count" characters were actually read, the + * last is changed to a null, so the returned string is always null- + * terminated. getst() returns the number of characters read, including + * the null terminator. + */ + +int +getst(fd, s, n) + int fd; + register char *s; + int n; +{ + register count = n; + while (read(fd, s, 1) > 0 && --count) + if (*s++ == '\0') + return (n - count); + *s = '\0'; + return (n - count); +} diff --git a/kerberosIV/krb/in_tkt.c b/kerberosIV/krb/in_tkt.c new file mode 100644 index 00000000000..bddb2d80932 --- /dev/null +++ b/kerberosIV/krb/in_tkt.c @@ -0,0 +1,149 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/in_tkt.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include +#ifdef TKT_SHMEM +#include +#endif + +/* + * in_tkt() is used to initialize the ticket store. It creates the + * file to contain the tickets and writes the given user's name "pname" + * and instance "pinst" in the file. in_tkt() returns KSUCCESS on + * success, or KFAILURE if something goes wrong. + */ + +int +in_tkt(pname, pinst) + char *pname; + char *pinst; +{ + int tktfile; + uid_t me, metoo; + struct stat buf; + int count; + char *file = TKT_FILE; + int fd; + register int i; + char charbuf[BUFSIZ]; +#ifdef TKT_SHMEM + char shmidname[MaxPathLen]; +#endif /* TKT_SHMEM */ + + me = getuid (); + metoo = geteuid(); + if (lstat(file,&buf) == 0) { + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",file); + return(KFAILURE); + } + /* file already exists, and permissions appear ok, so nuke it */ + if ((fd = open(file, O_RDWR, 0)) < 0) + goto out; /* can't zero it, but we can still try truncating it */ + + bzero(charbuf, sizeof(charbuf)); + + for (i = 0; i < buf.st_size; i += sizeof(charbuf)) + if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) { + (void) fsync(fd); + (void) close(fd); + goto out; + } + + (void) fsync(fd); + (void) close(fd); + } + out: + /* arrange so the file is owned by the ruid + (swap real & effective uid if necessary). + This isn't a security problem, since the ticket file, if it already + exists, has the right uid (== ruid) and mode. */ + if (me != metoo) { + if (setreuid(metoo, me) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",(int)metoo,(int)me); + } + if ((tktfile = creat(file,0600)) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + if (me != metoo) { + if (setreuid(me, metoo) < 0) { + /* can't switch??? barf! */ + if (krb_debug) + perror("in_tkt: setreuid2"); + return(KFAILURE); + } else + if (krb_debug) + printf("swapped UID's %d and %d\n",(int)me,(int)metoo); + } + if (lstat(file,&buf) < 0) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + if (buf.st_uid != me || !(buf.st_mode & S_IFREG) || + buf.st_mode & 077) { + if (krb_debug) + fprintf(stderr,"Error initializing %s",TKT_FILE); + return(KFAILURE); + } + + count = strlen(pname)+1; + if (write(tktfile,pname,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + count = strlen(pinst)+1; + if (write(tktfile,pinst,count) != count) { + (void) close(tktfile); + return(KFAILURE); + } + (void) close(tktfile); +#ifdef TKT_SHMEM + (void) strcpy(shmidname, file); + (void) strcat(shmidname, ".shm"); + return(krb_shm_create(shmidname)); +#else /* !TKT_SHMEM */ + return(KSUCCESS); +#endif /* TKT_SHMEM */ +} diff --git a/kerberosIV/krb/k_localtime.c b/kerberosIV/krb/k_localtime.c new file mode 100644 index 00000000000..88aa16f8e7f --- /dev/null +++ b/kerberosIV/krb/k_localtime.c @@ -0,0 +1,35 @@ +/* + * $Source: /home/cvs/src/kerberosIV/krb/Attic/k_localtime.c,v $ + * + * $Locker: $ + */ + +/* + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include + +#include + +struct tm * +k_localtime(tp) + u_int32_t *tp; +{ + time_t t; + t = *tp; + return localtime(&t); +} diff --git a/kerberosIV/krb/kerberos.3 b/kerberosIV/krb/kerberos.3 new file mode 100644 index 00000000000..5a6649aa747 --- /dev/null +++ b/kerberosIV/krb/kerberos.3 @@ -0,0 +1,462 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/kerberos.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/kerberos.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.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 +#include +.PP +.ft B +extern char *krb_err_txt[]; +.PP +.ft B +int krb_mk_req(authent,service,instance,realm,checksum) +KTEXT authent; +char *service; +char *instance; +char *realm; +u_long checksum; +.PP +.ft B +int krb_rd_req(authent,service,instance,from_addr,ad,fn) +KTEXT authent; +char *service; +char *instance; +u_long from_addr; +AUTH_DAT *ad; +char *fn; +.PP +.ft B +int krb_kntoln(ad,lname) +AUTH_DAT *ad; +char *lname; +.PP +.ft B +int krb_set_key(key,cvt) +char *key; +int cvt; +.PP +.ft B +int krb_get_cred(service,instance,realm,c) +char *service; +char *instance; +char *realm; +CREDENTIALS *c; +.PP +.ft B +long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver) +u_char *in; +u_char *out; +u_long in_length; +des_cblock key; +des_key_schedule schedule; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +.PP +.ft B +long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data) +u_char *in; +u_long in_length; +Key_schedule schedule; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg_data; +.PP +.ft B +long krb_mk_safe(in,out,in_length,key,sender,receiver) +u_char *in; +u_char *out; +u_long in_length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +.PP +.ft B +long krb_rd_safe(in,length,key,sender,receiver,msg_data) +u_char *in; +u_long length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg_data; +.PP +.ft B +long krb_mk_err(out,code,string) +u_char *out; +long code; +char *string; +.PP +.ft B +long krb_rd_err(in,length,code,msg_data) +u_char *in; +u_long length; +long code; +MSG_DAT *msg_data; +.fi +.ft R +.SH DESCRIPTION +This library supports network authentication and various related +operations. The library contains many routines beyond those described +in this man page, but they are not intended to be used directly. +Instead, they are called by the routines that are described, the +authentication server and the login program. +.PP +.I krb_err_txt[] +contains text string descriptions of various Kerberos error codes returned +by some of the routines below. +.PP +.I krb_mk_req +takes a pointer to a text structure in which an authenticator is to be +built. It also takes the name, instance, and realm of the service to be +used and an optional checksum. It is up to the application to decide +how to generate the checksum. +.I krb_mk_req +then retrieves a ticket for the desired service and creates an +authenticator. The authenticator is built in +.I authent +and is accessible +to the calling procedure. +.PP +It is up to the application to get the authenticator to the service +where it will be read by +.I krb_rd_req. +Unless an attacker posesses the session key contained in the ticket, it +will be unable to modify the authenticator. Thus, the checksum can be +used to verify the authenticity of the other data that will pass through +a connection. +.PP +.I krb_rd_req +takes an authenticator of type +.B KTEXT, +a service name, an instance, the address of the +host originating the request, and a pointer to a structure of type +.B AUTH_DAT +which is filled in with information obtained from the authenticator. +It also optionally takes the name of the file in which it will find the +secret key(s) for the service. +If the supplied +.I instance +contains "*", then the first service key with the same service name +found in the service key file will be used, and the +.I instance +argument will be filled in with the chosen instance. This means that +the caller must provide space for such an instance name. +.PP +It is used to find out information about the principal when a request +has been made to a service. It is up to the application protocol to get +the authenticator from the client to the service. The authenticator is +then passed to +.I krb_rd_req +to extract the desired information. +.PP +.I krb_rd_req +returns zero (RD_AP_OK) upon successful authentication. If a packet was +forged, modified, or replayed, authentication will fail. If the +authentication fails, a non-zero value is returned indicating the +particular problem encountered. See +.I krb.h +for the list of error codes. +.PP +If the last argument is the null string (""), krb_rd_req will use the +file /etc/srvtab to find its keys. If the last argument is NULL, it +will assume that the key has been set by +.I krb_set_key +and will not bother looking further. +.PP +.I krb_kntoln +converts a Kerberos name to a local name. It takes a structure +of type AUTH_DAT and uses the name and instance to look in the database +/etc/aname to find the corresponding local name. The local name is +returned and can be used by an application to change uids, directories, +or other parameters. It is not an integral part of Kerberos, but is +instead provided to support the use of Kerberos in existing utilities. +.PP +.I krb_set_key +takes as an argument a des key. It then creates +a key schedule from it and saves the original key to be used as an +initialization vector. +It is used to set the server's key which +must be used to decrypt tickets. +.PP +If called with a non-zero second argument, +.I krb_set_key +will first convert the input from a string of arbitrary length to a DES +key by encrypting it with a one-way function. +.PP +In most cases it should not be necessary to call +.I krb_set_key. +The necessary keys will usually be obtained and set inside +.I krb_rd_req. krb_set_key +is provided for those applications that do not wish to place the +application keys on disk. +.PP +.I krb_get_cred +searches the caller's ticket file for a ticket for the given service, instance, +and realm; and, if a ticket is found, fills in the given CREDENTIALS structure +with the ticket information. +.PP +If the ticket was found, +.I krb_get_cred +returns GC_OK. +If the ticket file can't be found, can't be read, doesn't belong to +the user (other than root), isn't a regular file, or is in the wrong +mode, the error GC_TKFIL is returned. +.PP +.I krb_mk_priv +creates an encrypted, authenticated +message from any arbitrary application data, pointed to by +.I in +and +.I in_length +bytes long. +The private session key, pointed to by +.I key +and the key schedule, +.I schedule, +are used to encrypt the data and some header information using +.I pcbc_encrypt. +.I sender +and +.I receiver +point to the Internet address of the two parties. +In addition to providing privacy, this protocol message protects +against modifications, insertions or replays. The encapsulated message and +header are placed in the area pointed to by +.I out +and the routine returns the length of the output, or -1 indicating +an error. +.PP +.I krb_rd_priv +decrypts and authenticates a received +.I krb_mk_priv +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +The private session key, pointed to by +.I key, +and the key schedule, +.I schedule, +are used to decrypt and verify the received message. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h. +The routine fills in the +.I app_data +field with a pointer to the decrypted application data, +.I app_length +with the length of the +.I app_data +field, +.I time_sec +and +.I time_5ms +with the timestamps in the message, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. (The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). The +.I hash +field returns a value useful as input to the +.I krb_ck_repl +routine. + +The routine returns zero if ok, or a Kerberos error code. Modified messages +and old messages cause errors, but it is up to the caller to +check the time sequence of messages, and to check against recently replayed +messages using +.I krb_ck_repl +if so desired. +.PP +.I krb_mk_safe +creates an authenticated, but unencrypted message from any arbitrary +application data, +pointed to by +.I in +and +.I in_length +bytes long. +The private session key, pointed to by +.I key, +is used to seed the +.I quad_cksum() +checksum algorithm used as part of the authentication. +.I sender +and +.I receiver +point to the Internet address of the two parties. +This message does not provide privacy, but does protect (via detection) +against modifications, insertions or replays. The encapsulated message and +header are placed in the area pointed to by +.I out +and the routine returns the length of the output, or -1 indicating +an error. +The authentication provided by this routine is not as strong as that +provided by +.I krb_mk_priv +or by computing the checksum using +.I cbc_cksum +instead, both of which authenticate via DES. +.PP + +.I krb_rd_safe +authenticates a received +.I krb_mk_safe +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +The private session key, pointed to by +.I key, +is used to seed the quad_cksum() routine as part of the authentication. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h . +The routine fills in these +.I MSG_DAT +fields: +the +.I app_data +field with a pointer to the application data, +.I app_length +with the length of the +.I app_data +field, +.I time_sec +and +.I time_5ms +with the timestamps in the message, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. +(The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). The +.I hash +field returns a value useful as input to the +.I krb_ck_repl +routine. + +The routine returns zero if ok, or a Kerberos error code. Modified messages +and old messages cause errors, but it is up to the caller to +check the time sequence of messages, and to check against recently replayed +messages using +.I krb_ck_repl +if so desired. +.PP +.I krb_mk_err +constructs an application level error message that may be used along +with +.I krb_mk_priv +or +.I krb_mk_safe. +.I out +is a pointer to the output buffer, +.I code +is an application specific error code, and +.I string +is an application specific error string. + +.PP +.I krb_rd_err +unpacks a received +.I krb_mk_err +message. +.I in +points to the beginning of the received message, whose length +is specified in +.I in_length. +.I code +is a pointer to a value to be filled in with the error +value provided by the application. +.I msg_data +is a pointer to a +.I MSG_DAT +struct, defined in +.I krb.h . +The routine fills in these +.I MSG_DAT +fields: the +.I app_data +field with a pointer to the application error text, +.I app_length +with the length of the +.I app_data +field, and +.I swap +with a 1 if the byte order of the receiver is different than that of +the sender. (The application must still determine if it is appropriate +to byte-swap application data; the Kerberos protocol fields are already taken +care of). + +The routine returns zero if the error message has been successfully received, +or a Kerberos error code. +.PP +The +.I KTEXT +structure is used to pass around text of varying lengths. It consists +of a buffer for the data, and a length. krb_rd_req takes an argument of this +type containing the authenticator, and krb_mk_req returns the +authenticator in a structure of this type. KTEXT itself is really a +pointer to the structure. The actual structure is of type KTEXT_ST. +.PP +The +.I AUTH_DAT +structure is filled in by krb_rd_req. It must be allocated before +calling krb_rd_req, and a pointer to it is passed. The structure is +filled in with data obtained from Kerberos. +.I MSG_DAT +structure is filled in by either krb_rd_priv, krb_rd_safe, or +krb_rd_err. It must be allocated before the call and a pointer to it +is passed. The structure is +filled in with data obtained from Kerberos. +.PP +.SH FILES +/usr/include/krb.h +.br +/usr/lib/libkrb.a +.br +/usr/include/des.h +.br +/usr/lib/libdes.a +.br +/etc/aname +.br +/etc/srvtab +.br +/tmp/tkt[uid] +.SH "SEE ALSO" +kerberos(1), des_crypt(3) +.SH DIAGNOSTICS +.SH BUGS +The caller of +.I krb_rd_req, krb_rd_priv, and krb_rd_safe +must check time order and for replay attempts. +.I krb_ck_repl +is not implemented yet. +.SH AUTHORS +Clifford Neuman, MIT Project Athena +.br +Steve Miller, MIT Project Athena/Digital Equipment Corporation +.SH RESTRICTIONS +COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology diff --git a/kerberosIV/krb/klog.c b/kerberosIV/krb/klog.c new file mode 100644 index 00000000000..5e7ea6c7e50 --- /dev/null +++ b/kerberosIV/krb/klog.c @@ -0,0 +1,124 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/klog.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include + +#include + +static char *log_name = KRBLOG; +static int is_open; +static char logtxt[1000]; + +/* + * This file contains two logging routines: kset_logfile() + * to determine the file to which log entries should be written; + * and klog() to write log entries to the file. + */ + +/* + * klog() is used to add entries to the logfile (see kset_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format" string. + * + * The log file is opened and closed for each log entry. + * + * If the given log type "type" is unknown, or if the log file + * cannot be opened, no entry is made to the log file. + * + * The return value is always a pointer to the formatted log + * text string "logtxt". + */ + +char * +klog(type, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0) + int type; + char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a0; +{ + FILE *logfile; + time_t now; + char *month_sname(int n); + struct tm *tm; + static int logtype_array[NLOGTYPE] = {0,0}; + static int array_initialized; + + if (!(array_initialized++)) { + logtype_array[L_NET_ERR] = 1; + logtype_array[L_KRB_PERR] = 1; + logtype_array[L_KRB_PWARN] = 1; + logtype_array[L_APPL_REQ] = 1; + logtype_array[L_INI_REQ] = 1; + logtype_array[L_DEATH_REQ] = 1; + logtype_array[L_NTGT_INTK] = 1; + logtype_array[L_ERR_SEXP] = 1; + logtype_array[L_ERR_MKV] = 1; + logtype_array[L_ERR_NKY] = 1; + logtype_array[L_ERR_NUN] = 1; + logtype_array[L_ERR_UNK] = 1; + } + + (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + + if (!logtype_array[type]) + return(logtxt); + + if ((logfile = fopen(log_name,"a")) == NULL) + return(logtxt); + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,"%s\n",logtxt); + (void) fclose(logfile); + return(logtxt); +} + +/* + * kset_logfile() changes the name of the file to which + * messages are logged. If kset_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +void +kset_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} diff --git a/kerberosIV/krb/kname_parse.c b/kerberosIV/krb/kname_parse.c new file mode 100644 index 00000000000..33036ac19d0 --- /dev/null +++ b/kerberosIV/krb/kname_parse.c @@ -0,0 +1,262 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/kname_parse.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#define INSTANCE_DOTS_OK 0 + +/* max size of full name */ +#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ) + +#define NAME 0 /* which field are we in? */ +#define INST 1 +#define REALM 2 + +/* + * This file contains four routines for handling Kerberos names. + * + * kname_parse() breaks a Kerberos name into its name, instance, + * and realm components. + * + * k_isname(), k_isinst(), and k_isrealm() check a given string to see if + * it's a syntactically legitimate respective part of a Kerberos name, + * returning 1 if it is, 0 if it isn't. + * + * Definition of "syntactically legitimate" names is according to + * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying + * names", version dated 21 Dec 1987. + */ + +/* + * kname_parse() takes a Kerberos name "fullname" of the form: + * + * username[.instance][@realm] + * + * and returns the three components ("name", "instance", and "realm" + * in the example above) in the given arguments "np", "ip", and "rp". + * + * If successful, it returns KSUCCESS. If there was an error, + * KNAME_FMT is returned. + */ + +int +kname_parse(np, ip, rp, fullname) + char *np; + char *ip; + char *rp; + char *fullname; +{ + static char buf[FULL_SZ]; + char *rnext, *wnext; /* next char to read, write */ + register char c; + int backslash; + int field; + + backslash = 0; + rnext = buf; + wnext = np; + field = NAME; + + if (strlen(fullname) > FULL_SZ) + return KNAME_FMT; + (void) strcpy(buf, fullname); + + while ((c = *rnext++)) { + if (backslash) { + *wnext++ = c; + backslash = 0; + continue; + } + switch (c) { + case '\\': + backslash++; + break; + case '.': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *wnext = '\0'; + field = INST; + wnext = ip; + break; + case INST: +#if INSTANCE_DOTS_OK + *wnext++ = c; + break; +#else /* INSTANCE_DOTS_OK */ + return KNAME_FMT; +#endif /* INSTANCE_DOTS_OK */ + /* break; */ + case REALM: + *wnext++ = c; + break; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + case '@': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *ip = '\0'; + /* fall through */ + case INST: + *wnext = '\0'; + field = REALM; + wnext = rp; + break; + case REALM: + return KNAME_FMT; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + default: + *wnext++ = c; + } + } + *wnext = '\0'; + if ((strlen(np) > ANAME_SZ - 1) || + (strlen(ip) > INST_SZ - 1) || + (strlen(rp) > REALM_SZ - 1)) + return KNAME_FMT; + return KSUCCESS; +} + +/* + * k_isname() returns 1 if the given name is a syntactically legitimate + * Kerberos name; returns 0 if it's not. + */ + +int +k_isname(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > ANAME_SZ - 1) + return 0; + while ((c = *s++)) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + + +/* + * k_isinst() returns 1 if the given name is a syntactically legitimate + * Kerberos instance; returns 0 if it's not. + */ + +int +k_isinst(s) + char *s; +{ + register char c; + int backslash = 0; + + if (strlen(s) > INST_SZ - 1) + return 0; + while ((c = *s++)) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': +#if INSTANCE_DOTS_OK + break; +#else /* INSTANCE_DOTS_OK */ + return 0; +#endif /* INSTANCE_DOTS_OK */ + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + +/* + * k_isrealm() returns 1 if the given name is a syntactically legitimate + * Kerberos realm; returns 0 if it's not. + */ + +int +k_isrealm(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > REALM_SZ - 1) + return 0; + while ((c = *s++)) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '@': + return 0; + /* break; */ + } + } + return 1; +} diff --git a/kerberosIV/krb/kntoln.c b/kerberosIV/krb/kntoln.c new file mode 100644 index 00000000000..52aca33ee1b --- /dev/null +++ b/kerberosIV/krb/kntoln.c @@ -0,0 +1,74 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/kntoln.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * krb_kntoln converts an auth name into a local name by looking up + * the auth name in the /etc/aname file. The format of the aname + * file is: + * + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | anl | inl | rll | lnl | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * | 1by | 1by | 1by | 1by | name | instance | realm | lname | + * +-----+-----+-----+-----+------+----------+-------+-------+ + * + * If the /etc/aname file can not be opened it will set the + * local name to the auth name. Thus, in this case it performs as + * the identity function. + * + * The name instance and realm are passed to krb_kntoln through + * the AUTH_DAT structure (ad). + * + * Now here's what it *really* does: + * + * Given a Kerberos name in an AUTH_DAT structure, check that the + * instance is null, and that the realm is the same as the local + * realm, and return the principal's name in "lname". Return + * KSUCCESS if all goes well, otherwise KFAILURE. + */ + +#include "krb_locl.h" + +int +krb_kntoln(ad, lname) + AUTH_DAT *ad; + char *lname; +{ + static char lrealm[REALM_SZ] = ""; + + if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE)) + return(KFAILURE); + + if (strcmp(ad->pinst,"")) + return(KFAILURE); + if (strcmp(ad->prealm,lrealm)) + return(KFAILURE); + (void) strcpy(lname,ad->pname); + return(KSUCCESS); +} diff --git a/kerberosIV/krb/kparse.c b/kerberosIV/krb/kparse.c new file mode 100644 index 00000000000..1e23482a040 --- /dev/null +++ b/kerberosIV/krb/kparse.c @@ -0,0 +1,789 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/kparse.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * Purpose: + * This module was developed to parse the "~/.klogin" files for + * Kerberos-authenticated rlogin/rcp/rsh services. However, it is + * general purpose and can be used to parse any such parameter file. + * + * The parameter file should consist of one or more entries, with each + * entry on a separate line and consisting of zero or more + * "keyword=value" combinations. The keyword is case insensitive, but + * the value is not. Any string may be enclosed in quotes, and + * c-style "\" literals are supported. A comma may be used to + * separate the k/v combinations, and multiple commas are ignored. + * Whitespace (blank or tab) may be used freely and is ignored. + * + * Full error processing is available. When PS_BAD_KEYWORD or + * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg + * contains a meaningful error message. + * + * Keywords and their default values are programmed by an external + * table. + * + * Routines: + * fGetParameterSet() parse one line of the parameter file + * fGetKeywordValue() parse one "keyword=value" combo + * fGetToken() parse one token + * + * " <- emacs fix + */ + +#include "krb_locl.h" + +#include + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define MAXKEY 80 +#define MAXVALUE 80 + +int LineNbr=1; /* current line nbr in parameter file */ +char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX, + * or PS_BAD_KEYWORD is returned by + * fGetKeywordValue or fGetParameterSet */ + +int +fGetParameterSet(fp, parm, parmcount) + FILE *fp; + parmtable *parm; + int parmcount; +{ + int rc,i; + char keyword[MAXKEY]; + char value[MAXVALUE]; + + while (TRUE) { + rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE); + + switch (rc) { + + case KV_EOF: + return(PS_EOF); + + case KV_EOL: + return(PS_OKAY); + + case KV_SYNTAX: + return(PS_SYNTAX); + + case KV_OKAY: + /* + * got a reasonable keyword/value pair. Search the + * parameter table to see if we recognize the keyword; if + * not, return an error. If we DO recognize it, make sure + * it has not already been given. If not already given, + * save the value. + */ + for (i=0; i= parmcount) { + 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\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 \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 + +int swap_bytes; + +static int +pkt_clen(pkt) + KTEXT pkt; +{ + static unsigned short temp,temp2; + int clen = 0; + + /* Start of ticket list */ + unsigned char *ptr = pkt_a_realm(pkt) + 10 + + strlen((char *)pkt_a_realm(pkt)); + + /* Finally the length */ + bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */ + if (swap_bytes) { + /* assume a short is 2 bytes?? */ + swab((char *)&temp,(char *)&temp2,2); + temp = temp2; + } + + clen = (int) temp; + + if (krb_debug) + printf("Clen is %d\n",clen); + return(clen); +} + +/* + * decrypt_tkt(): Given user, instance, realm, passwd, key_proc + * and the cipher text sent from the KDC, decrypt the cipher text + * using the key returned by key_proc. + */ + +static int +decrypt_tkt(user, instance, realm, arg, key_proc, cipp) + char *user; + char *instance; + char *realm; + char *arg; + int (*key_proc)(); + KTEXT *cipp; +{ + KTEXT cip = *cipp; + des_cblock key; /* Key for decrypting cipher */ + des_key_schedule key_s; + +#ifndef NOENCRYPTION + /* Attempt to decrypt it */ +#endif + + /* generate a key */ + + { + register int rc; + rc = (*key_proc)(user,instance,realm,arg,key); + if (rc) + return(rc); + } + +#ifndef NOENCRYPTION + des_key_sched(&key,key_s); + des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)cip->dat, + (long) cip->length,key_s,&key,DES_DECRYPT); +#endif /* !NOENCRYPTION */ + /* Get rid of all traces of key */ + bzero((char *)key,sizeof(key)); + bzero((char *)key_s,sizeof(key_s)); + + return(0); +} + +/* + * krb_get_in_tkt() gets a ticket for a given principal to use a given + * service and stores the returned ticket and session key for future + * use. + * + * The "user", "instance", and "realm" arguments give the identity of + * the client who will use the ticket. The "service" and "sinstance" + * arguments give the identity of the server that the client wishes + * to use. (The realm of the server is the same as the Kerberos server + * to whom the request is sent.) The "life" argument indicates the + * desired lifetime of the ticket; the "key_proc" argument is a pointer + * to the routine used for getting the client's private key to decrypt + * the reply from Kerberos. The "decrypt_proc" argument is a pointer + * to the routine used to decrypt the reply from Kerberos; and "arg" + * is an argument to be passed on to the "key_proc" routine. + * + * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it + * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned + * by Kerberos, then the error code it contains is returned. Other + * error codes returned by this routine include INTK_PROT to indicate + * wrong protocol version, INTK_BADPW to indicate bad password (if + * decrypted ticket didn't make sense), INTK_ERR if the ticket was for + * the wrong server or the ticket store couldn't be initialized. + * + * The format of the message sent to Kerberos is as follows: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_KDC_REQUEST | message type + * HOST_BYTE_ORDER local byte order in lsb + * string user client's name + * string instance client's instance + * string realm client's realm + * 4 bytes tlocal.tv_sec timestamp in seconds + * 1 byte life desired lifetime + * string service service's name + * string sinstance service's instance + */ + +int +krb_get_in_tkt(user, instance, realm, service, sinstance, life, + key_proc, decrypt_proc, arg) + char *user; + char *instance; + char *realm; + char *service; + char *sinstance; + int life; + int (*key_proc)(); + int (*decrypt_proc)(); + char *arg; +{ + KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; /* Packet to KDC */ + KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; /* Returned packet */ + KTEXT_ST cip_st; + KTEXT cip = &cip_st; /* Returned Ciphertext */ + KTEXT_ST tkt_st; + KTEXT tkt = &tkt_st; /* Current ticket */ + des_cblock ses; /* Session key for tkt */ + int kvno; /* Kvno for session key */ + unsigned char *v = pkt->dat; /* Prot vers no */ + unsigned char *t = (pkt->dat+1); /* Prot msg type */ + + char s_name[SNAME_SZ]; + char s_instance[INST_SZ]; + char rlm[REALM_SZ]; + int lifetime; + int msg_byte_order; + int kerror; + unsigned long exp_date; + char *ptr; + + struct timeval t_local; + + unsigned long rep_err_code; + + unsigned long kdc_time; /* KDC time */ + + /* BUILD REQUEST PACKET */ + + /* Set up the fixed part of the packet */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_KDC_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Now for the variable info */ + (void) strcpy((char *)(pkt->dat+2),user); /* aname */ + pkt->length = 3 + strlen(user); + (void) strcpy((char *)(pkt->dat+pkt->length), + instance); /* instance */ + pkt->length += 1 + strlen(instance); + (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */ + pkt->length += 1 + strlen(realm); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + /* timestamp */ + bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4); + pkt->length += 4; + + *(pkt->dat+(pkt->length)++) = (char) life; + (void) strcpy((char *)(pkt->dat+pkt->length),service); + pkt->length += 1 + strlen(service); + (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); + pkt->length += 1 + strlen(sinstance); + + rpkt->length = 0; + + /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */ + + if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror); + + /* check packet version of the returned packet */ + if (pkt_version(rpkt) != KRB_PROT_VERSION) + return(INTK_PROT); + + /* Check byte order */ + msg_byte_order = pkt_msg_type(rpkt) & 1; + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + + switch (pkt_msg_type(rpkt) & ~1) { + case AUTH_MSG_KDC_REPLY: + break; + case AUTH_MSG_ERR_REPLY: + bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4); + if (swap_bytes) swap_u_long(rep_err_code); + return((int)rep_err_code); + default: + return(INTK_PROT); + } + + /* EXTRACT INFORMATION FROM RETURN PACKET */ + + /* get the principal's expiration date */ + bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date)); + if (swap_bytes) swap_u_long(exp_date); + + /* Extract the ciphertext */ + cip->length = pkt_clen(rpkt); /* let clen do the swap */ + + if ((cip->length < 0) || (cip->length > sizeof(cip->dat))) + return(INTK_ERR); /* no appropriate error code + currently defined for INTK_ */ + /* copy information from return packet into "cip" */ + bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length); + + /* Attempt to decrypt the reply. */ + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip); + + ptr = (char *) cip->dat; + + /* extract session key */ + bcopy(ptr,(char *)ses,8); + ptr += 8; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's name */ + (void) strcpy(s_name,ptr); + ptr += strlen(s_name) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's instance */ + (void) strcpy(s_instance,ptr); + ptr += strlen(s_instance) + 1; + + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + return(INTK_BADPW); + + /* extract server's realm */ + (void) strcpy(rlm,ptr); + ptr += strlen(rlm) + 1; + + /* extract ticket lifetime, server key version, ticket length */ + /* be sure to avoid sign extension on lifetime! */ + lifetime = (unsigned char) ptr[0]; + kvno = (unsigned char) ptr[1]; + tkt->length = (unsigned char) ptr[2]; + ptr += 3; + + if ((tkt->length < 0) || + ((tkt->length + (ptr - (char *) cip->dat)) > cip->length)) + return(INTK_BADPW); + + /* extract ticket itself */ + bcopy(ptr,(char *)(tkt->dat),tkt->length); + ptr += tkt->length; + + if (strcmp(s_name, service) || strcmp(s_instance, sinstance) || + strcmp(rlm, realm)) /* not what we asked for */ + return(INTK_ERR); /* we need a better code here XXX */ + + /* check KDC time stamp */ + bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(kdc_time); + + ptr += 4; + + (void) gettimeofday(&t_local,(struct timezone *) 0); + if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) { + return(RD_AP_TIME); /* XXX should probably be better + code */ + } + + /* initialize ticket cache */ + if (in_tkt(user,instance) != KSUCCESS) + return(INTK_ERR); + + /* stash ticket, session key, etc. for future use */ + if ((kerror = save_credentials(s_name, s_instance, rlm, ses, + lifetime, kvno, tkt, t_local.tv_sec))) + return(kerror); + + return(INTK_OK); +} diff --git a/kerberosIV/krb/krb_locl.h b/kerberosIV/krb/krb_locl.h new file mode 100644 index 00000000000..5b5d50bd5c0 --- /dev/null +++ b/kerberosIV/krb/krb_locl.h @@ -0,0 +1,40 @@ +/* $Id: krb_locl.h,v 1.1.1.1 1995/12/14 06:52:38 tholo Exp $ */ + +#ifndef __krb_locl_h +#define __krb_locl_h + +#include +#include "kerberosIV/site.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* --- */ + +/* Globals! */ +extern int krb_debug; +extern int krb_ap_req_debug; + +/* Utils */ +char *pkt_cipher __P((KTEXT)); + +int new_log __P((time_t, char *)); +char *klog (); + +char *month_sname __P((int)); +int fgetst __P((FILE *, char *, int)); + +#endif /* __krb_locl_h */ diff --git a/kerberosIV/krb/krb_realmofhost.3 b/kerberosIV/krb/krb_realmofhost.3 new file mode 100644 index 00000000000..d60e1c23ca4 --- /dev/null +++ b/kerberosIV/krb/krb_realmofhost.3 @@ -0,0 +1,162 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_realmofhost.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_realmofhost.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.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 +#include +#include +.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 +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 ). +.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 ) characters long. +.PP +.SH SEE ALSO +kerberos(3), krb.conf(5), krb.realms(5) +.SH FILES +.TP 20n +/etc/krb.realms +translation file for host-to-realm mapping. +.TP +/etc/krb.conf +local realm-name and realm/server configuration file. +.SH BUGS +The current convention for instance names is too limited; the full +domain name should be used. +.PP +.I krb_get_lrealm +currently only supports +.I n += 1. It should really consult the user's ticket cache to determine the +user's current realm, rather than consulting a file on the host. diff --git a/kerberosIV/krb/krb_sendauth.3 b/kerberosIV/krb/krb_sendauth.3 new file mode 100644 index 00000000000..512fa423af8 --- /dev/null +++ b/kerberosIV/krb/krb_sendauth.3 @@ -0,0 +1,349 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_sendauth.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_sendauth.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ +.\" Copyright 1988 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.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 +#include +#include +.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 ) +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 . diff --git a/kerberosIV/krb/krb_set_tkt_string.3 b/kerberosIV/krb/krb_set_tkt_string.3 new file mode 100644 index 00000000000..129169f7226 --- /dev/null +++ b/kerberosIV/krb/krb_set_tkt_string.3 @@ -0,0 +1,44 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.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 +.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 ) characters of the filename are +copied in for use as the cache file name. +.PP +This routine should be called during initialization, before other +Kerberos routines are called; otherwise the routines which fetch the +ticket cache file name may be called and return an undesired ticket file +name until this routine is called. +.SH FILES +.TP 20n +/tmp/tkt[uid] +default ticket file name, unless the environment variable KRBTKFILE is set. +[uid] denotes the user's uid, in decimal. +.SH SEE ALSO +kerberos(3), setenv(3) diff --git a/kerberosIV/krb/kuserok.3 b/kerberosIV/krb/kuserok.3 new file mode 100644 index 00000000000..4aa7d5b5a4a --- /dev/null +++ b/kerberosIV/krb/kuserok.3 @@ -0,0 +1,64 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/kuserok.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/kuserok.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kuserok \- Kerberos version of ruserok +.SH SYNOPSIS +.nf +.nj +.ft B +#include +.PP +.ft B +kuserok(kdata, localuser) +AUTH_DAT *auth_data; +char *localuser; +.fi +.ft R +.SH DESCRIPTION +.I kuserok +determines whether a Kerberos principal described by the structure +.I auth_data +is authorized to login as user +.I localuser +according to the authorization file +("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized, +1 (one) if not authorized. +.PP +If there is no account for +.I localuser +on the local machine, authorization is not granted. +If there is no authorization file, and the Kerberos principal described +by +.I auth_data +translates to +.I localuser +(using +.IR krb_kntoln (3)), +authorization is granted. +If the authorization file +can't be accessed, or the file is not owned by +.IR localuser, +authorization is denied. Otherwise, the file is searched for +a matching principal name, instance, and realm. If a match is found, +authorization is granted, else authorization is denied. +.PP +The file entries are in the format: +.nf +.in +5n + name.instance@realm +.in -5n +.fi +with one entry per line. +.SH SEE ALSO +kerberos(3), ruserok(3), krb_kntoln(3) +.SH FILES +.TP 20n +~\fIlocaluser\fR/.klogin +authorization list diff --git a/kerberosIV/krb/kuserok.c b/kerberosIV/krb/kuserok.c new file mode 100644 index 00000000000..fd888fcc72c --- /dev/null +++ b/kerberosIV/krb/kuserok.c @@ -0,0 +1,212 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/kuserok.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * kuserok: check if a kerberos principal has + * access to a local account + */ + +#include "krb_locl.h" + +#include +#include +#include +#include +#include + +#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 + +/* + * The parmtable defines the keywords we will recognize with their + * default values, and keeps a pointer to the found value. The found + * value should be filled in with strsave(), since FreeParameterSet() + * will release memory for all non-NULL found strings. + * +*** NOTE WELL! *** + * + * The table below is very nice, but we cannot hard-code a default for the + * realm: we have to get the realm via krb_get_lrealm(). Even though the + * default shows as "from krb_get_lrealm, below", it gets changed in + * kuserok to whatever krb_get_lrealm() tells us. That code assumes that + * the realm will be the entry number in the table below, so if you + * change the order of the entries below, you have to change the + * #definition of REALM_SCRIPT to reflect it. + */ +#define REALM_SUBSCRIPT 1 +parmtable kparm[] = { + +/* keyword default found value */ +{"user", "", (char *) NULL}, +{"realm", "see krb_get_lrealm, below", (char *) NULL}, +{"instance", "", (char *) NULL}, +}; +#define KPARMS kparm,PARMCOUNT(kparm) +#endif /* ATHENA_COMPAT */ + +int +kuserok(kdata, luser) + AUTH_DAT *kdata; + char *luser; +{ + struct stat sbuf; + struct passwd *pwd; + char pbuf[MAXPATHLEN]; + int isok = NOTOK, rc; + FILE *fp; + char kuser[MAX_USERNAME]; + char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; + char linebuf[BUFSIZ]; + char *newline; + int gobble; +#ifdef ATHENA_COMPAT + char local_realm[REALM_SZ]; +#endif /* ATHENA_COMPAT */ + + /* no account => no access */ + if ((pwd = getpwnam(luser)) == NULL) { + return(NOTOK); + } + (void) strcpy(pbuf, pwd->pw_dir); + (void) strcat(pbuf, "/.klogin"); + + if (access(pbuf, F_OK)) { /* not accessible */ + /* + * if he's trying to log in as himself, and there is no .klogin file, + * let him. To find out, call + * krb_kntoln to convert the triple in kdata to a name which we can + * string compare. + */ + if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) { + return(OK); + } + } + /* open ~/.klogin */ + if ((fp = fopen(pbuf, "r")) == NULL) { + return(NOTOK); + } + /* + * security: if the user does not own his own .klogin file, + * do not grant access + */ + if (fstat(fileno(fp), &sbuf)) { + fclose(fp); + return(NOTOK); + } + if (sbuf.st_uid != pwd->pw_uid) { + fclose(fp); + return(NOTOK); + } + +#ifdef ATHENA_COMPAT + /* Accept old-style .klogin files */ + + /* + * change the default realm from the hard-coded value to the + * accepted realm that Kerberos specifies. + */ + rc = krb_get_lrealm(local_realm, 1); + if (rc == KSUCCESS) + kparm[REALM_SUBSCRIPT].defvalue = local_realm; + else + return (rc); + + /* check each line */ + while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) { + switch (rc) { + case PS_BAD_KEYWORD: + case PS_SYNTAX: + while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n')); + break; + + case PS_OKAY: + isok = (ParmCompare(KPARMS, "user", kdata->pname) || + ParmCompare(KPARMS, "instance", kdata->pinst) || + ParmCompare(KPARMS, "realm", kdata->prealm)); + break; + + default: + break; + } + FreeParameterSet(kparm, PARMCOUNT(kparm)); + } + /* reset the stream for parsing new-style names, if necessary */ + rewind(fp); +#endif /* ATHENA_COMPAT */ + + /* check each line */ + while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) { + /* null-terminate the input string */ + linebuf[BUFSIZ-1] = '\0'; + newline = NULL; + /* nuke the newline if it exists */ + if ((newline = strchr(linebuf, '\n'))) + *newline = '\0'; + rc = kname_parse(principal, inst, realm, linebuf); + if (rc == KSUCCESS) { + isok = (strncmp(kdata->pname, principal, ANAME_SZ) || + strncmp(kdata->pinst, inst, INST_SZ) || + strncmp(kdata->prealm, realm, REALM_SZ)); + } + /* clean up the rest of the line if necessary */ + if (!newline) + while (((gobble = getc(fp)) != EOF) && gobble != '\n'); + } + fclose(fp); + return(isok); +} diff --git a/kerberosIV/krb/lifetime.c b/kerberosIV/krb/lifetime.c new file mode 100644 index 00000000000..e91d5b09e2e --- /dev/null +++ b/kerberosIV/krb/lifetime.c @@ -0,0 +1,234 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/lifetime.c,v $ + * + * $Locker: $ + */ + +/*************************************************************************** + * PRE-HISTORY + * + * Revision 2.1.2.2 91/11/08 00:35:25 mja + * Lower NEVERDATE to a positive value since time values are not + * handled properly by most of the rest of the system when + * negative; add krb_life_to_atime() and krb_atime_to_life(). + * [91/11/07 22:52:50 mja] + * + * Revision 2.1.2.1 91/07/09 22:50:42 mja + * Created. + * [91/01/30 jm36@ANDREW.CMU.EDU] + * + ***************************************************************************/ + +/* + * Ticket lifetime. This defines the table used to lookup lifetime + * for the fixed part of rande of the one byte lifetime field. Values + * less than 0x80 are intrpreted as the number of 5 minute intervals. + * Values from 0x80 to 0xBF should be looked up in this table. The + * value of 0x80 is the same using both methods: 10 and two-thirds + * hours . The lifetime of 0xBF is 30 days. The intervening values + * of have a fixed ratio of roughly 1.06914. The value 0xFF is + * defined to mean a ticket has no expiration time. This should be + * used advisedly since individual servers may impose defacto + * upperbounds on ticket lifetimes. + */ + +#include "krb_locl.h" + +#define TKTLIFENUMFIXED 64 +#define TKTLIFEMINFIXED 0x80 +#define TKTLIFEMAXFIXED 0xBF +#define TKTLIFENOEXPIRE 0xFF +#define MAXTKTLIFETIME (30*24*3600) /* 30 days */ +#ifndef NEVERDATE +#define NEVERDATE ((unsigned long)0x7fffffffL) +#endif + +static const int tkt_lifetimes[TKTLIFENUMFIXED] = { + 38400, /* 10.67 hours, 0.44 days */ + 41055, /* 11.40 hours, 0.48 days */ + 43894, /* 12.19 hours, 0.51 days */ + 46929, /* 13.04 hours, 0.54 days */ + 50174, /* 13.94 hours, 0.58 days */ + 53643, /* 14.90 hours, 0.62 days */ + 57352, /* 15.93 hours, 0.66 days */ + 61318, /* 17.03 hours, 0.71 days */ + 65558, /* 18.21 hours, 0.76 days */ + 70091, /* 19.47 hours, 0.81 days */ + 74937, /* 20.82 hours, 0.87 days */ + 80119, /* 22.26 hours, 0.93 days */ + 85658, /* 23.79 hours, 0.99 days */ + 91581, /* 25.44 hours, 1.06 days */ + 97914, /* 27.20 hours, 1.13 days */ + 104684, /* 29.08 hours, 1.21 days */ + 111922, /* 31.09 hours, 1.30 days */ + 119661, /* 33.24 hours, 1.38 days */ + 127935, /* 35.54 hours, 1.48 days */ + 136781, /* 37.99 hours, 1.58 days */ + 146239, /* 40.62 hours, 1.69 days */ + 156350, /* 43.43 hours, 1.81 days */ + 167161, /* 46.43 hours, 1.93 days */ + 178720, /* 49.64 hours, 2.07 days */ + 191077, /* 53.08 hours, 2.21 days */ + 204289, /* 56.75 hours, 2.36 days */ + 218415, /* 60.67 hours, 2.53 days */ + 233517, /* 64.87 hours, 2.70 days */ + 249664, /* 69.35 hours, 2.89 days */ + 266926, /* 74.15 hours, 3.09 days */ + 285383, /* 79.27 hours, 3.30 days */ + 305116, /* 84.75 hours, 3.53 days */ + 326213, /* 90.61 hours, 3.78 days */ + 348769, /* 96.88 hours, 4.04 days */ + 372885, /* 103.58 hours, 4.32 days */ + 398668, /* 110.74 hours, 4.61 days */ + 426234, /* 118.40 hours, 4.93 days */ + 455705, /* 126.58 hours, 5.27 days */ + 487215, /* 135.34 hours, 5.64 days */ + 520904, /* 144.70 hours, 6.03 days */ + 556921, /* 154.70 hours, 6.45 days */ + 595430, /* 165.40 hours, 6.89 days */ + 636601, /* 176.83 hours, 7.37 days */ + 680618, /* 189.06 hours, 7.88 days */ + 727680, /* 202.13 hours, 8.42 days */ + 777995, /* 216.11 hours, 9.00 days */ + 831789, /* 231.05 hours, 9.63 days */ + 889303, /* 247.03 hours, 10.29 days */ + 950794, /* 264.11 hours, 11.00 days */ + 1016537, /* 282.37 hours, 11.77 days */ + 1086825, /* 301.90 hours, 12.58 days */ + 1161973, /* 322.77 hours, 13.45 days */ + 1242318, /* 345.09 hours, 14.38 days */ + 1328218, /* 368.95 hours, 15.37 days */ + 1420057, /* 394.46 hours, 16.44 days */ + 1518247, /* 421.74 hours, 17.57 days */ + 1623226, /* 450.90 hours, 18.79 days */ + 1735464, /* 482.07 hours, 20.09 days */ + 1855462, /* 515.41 hours, 21.48 days */ + 1983758, /* 551.04 hours, 22.96 days */ + 2120925, /* 589.15 hours, 24.55 days */ + 2267576, /* 629.88 hours, 26.25 days */ + 2424367, /* 673.44 hours, 28.06 days */ + 2592000}; /* 720.00 hours, 30.00 days */ + +/* + * krb_life_to_time - takes a start time and a Kerberos standard + * lifetime char and returns the corresponding end time. There are + * four simple cases to be handled. The first is a life of 0xff, + * meaning no expiration, and results in an end time of 0xffffffff. + * The second is when life is less than the values covered by the + * table. In this case, the end time is the start time plus the + * number of 5 minute intervals specified by life. The third case + * returns start plus the MAXTKTLIFETIME if life is greater than + * TKTLIFEMAXFIXED. The last case, uses the life value (minus + * TKTLIFEMINFIXED) as an index into the table to extract the lifetime + * in seconds, which is added to start to produce the end time. + */ +u_int32_t +krb_life_to_time(start, life) + u_int32_t start; + int life; +{ + life = (unsigned char) life; + if (life == TKTLIFENOEXPIRE) return NEVERDATE; + if (life < TKTLIFEMINFIXED) return start + life*5*60; + if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME; + return start + tkt_lifetimes[life - TKTLIFEMINFIXED]; +} + +/* + * krb_time_to_life - takes start and end times for the ticket and + * returns a Kerberos standard lifetime char, possibily using the + * tkt_lifetimes table for lifetimes above 127*5 minutes. First, the + * special case of (end == NEVERDATE) is handled to mean no + * expiration. Then negative lifetimes and those greater than the + * maximum ticket lifetime are rejected. Then lifetimes less than the + * first table entry are handled by rounding the requested lifetime + * *up* to the next 5 minute interval. The final step is to search + * the table for the smallest entry *greater than or equal* to the + * requested entry. + */ +int +krb_time_to_life(start, end) + u_int32_t start; + u_int32_t end; +{ + long lifetime; + int i; + + if (end >= NEVERDATE) return TKTLIFENOEXPIRE; + lifetime = end - start; + if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0; + if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60); + for (i=0; i + +#include + +static char *log_name = KRBLOG; +static is_open; + +/* + * This file contains three logging routines: set_logfile() + * to determine the file that log entries should be written to; + * and log() and new_log() to write log entries to the file. + */ + +/* + * log() is used to add entries to the logfile (see set_logfile() + * below). Note that it is probably not portable since it makes + * assumptions about what the compiler will do when it is called + * with less than the correct number of arguments which is the + * way it is usually called. + * + * The log entry consists of a timestamp and the given arguments + * printed according to the given "format". + * + * The log file is opened and closed for each log entry. + * + * The return value is undefined. + */ + +/*VARARGS1 */ +void +log(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0) + char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a0; +{ + FILE *logfile; + time_t now; + struct tm *tm; + + if ((logfile = fopen(log_name,"a")) == NULL) + return; + + (void) time(&now); + tm = localtime(&now); + + fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); + fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + fprintf(logfile,"\n"); + (void) fclose(logfile); + return; +} + +/* + * set_logfile() changes the name of the file to which + * messages are logged. If set_logfile() is not called, + * the logfile defaults to KRBLOG, defined in "krb.h". + */ + +void +set_logfile(filename) + char *filename; +{ + log_name = filename; + is_open = 0; +} + +/* + * new_log() appends a log entry containing the give time "t" and the + * string "string" to the logfile (see set_logfile() above). The file + * is opened once and left open. The routine returns 1 on failure, 0 + * on success. + */ + +int +new_log(t, string) + time_t t; + char *string; +{ + static FILE *logfile; + + struct tm *tm; + + if (!is_open) { + if ((logfile = fopen(log_name,"a")) == NULL) return(1); + is_open = 1; + } + + if (t) { + tm = localtime(&t); + + fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday, + month_sname(tm->tm_mon + 1),tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec, string); + } + else { + fprintf(logfile,"\n%20s%s","",string); + } + + (void) fflush(logfile); + return(0); +} diff --git a/kerberosIV/krb/lsb_addr_comp.h b/kerberosIV/krb/lsb_addr_comp.h new file mode 100644 index 00000000000..2462be659ab --- /dev/null +++ b/kerberosIV/krb/lsb_addr_comp.h @@ -0,0 +1,54 @@ +/* + * $Source: /home/cvs/src/kerberosIV/krb/Attic/lsb_addr_comp.h,v $ + */ + +/* + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Comparison macros to emulate LSBFIRST comparison results of network + * byte-order quantities + */ + +#ifndef LSB_ADDR_COMP_DEFS +#define LSB_ADDR_COMP_DEFS + +#if BYTE_ORDER == BIG_ENDIAN + +#define u_char_comp(x,y) \ + (((x)>(y))?(1):(((x)==(y))?(0):(-1))) +/* This is gross, but... */ +#define lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y) +#define lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y) + +#define long_less_than(x,y) \ + (u_char_comp((x)[3],(y)[3])?u_char_comp((x)[3],(y)[3]): \ + (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \ + (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \ + (u_char_comp((x)[0],(y)[0]))))) +#define short_less_than(x,y) \ + (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \ + (u_char_comp((x)[0],(y)[0]))) + +#else /* !WORDS_BIGENDIAN */ + +#define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0)) +#define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0)) + +#endif /* !WORDS_BIGENDIAN */ + +#endif /* LSB_ADDR_COMP_DEFS */ diff --git a/kerberosIV/krb/mk_err.c b/kerberosIV/krb/mk_err.c new file mode 100644 index 00000000000..cc168c9c9e0 --- /dev/null +++ b/kerberosIV/krb/mk_err.c @@ -0,0 +1,77 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_err.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include + +/* + * This routine creates a general purpose error reply message. It + * doesn't use KTEXT because application protocol may have long + * messages, and may want this part of buffer contiguous to other + * stuff. + * + * The error reply is built in "p", using the error code "e" and + * error text "e_string" given. The length of the error reply is + * returned. + * + * The error reply is in the following format: + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_ERR message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte order + * 4 bytes e given error code + * string e_string given error text + */ + +int32_t +krb_mk_err(p, e, e_string) + u_char *p; /* Where to build error packet */ + int32_t e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *start; + + start = p; + + /* Create fixed part of packet */ + *p++ = (unsigned char) KRB_PROT_VERSION; + *p = (unsigned char) AUTH_MSG_APPL_ERR; + *p++ |= HOST_BYTE_ORDER; + + /* Add the basic info */ + bcopy((char *)&e,(char *)p,4); /* err code */ + p += sizeof(e); + (void) strcpy((char *)p,e_string); /* err text */ + p += strlen(e_string); + + /* And return the length */ + return p-start; +} diff --git a/kerberosIV/krb/mk_priv.c b/kerberosIV/krb/mk_priv.c new file mode 100644 index 00000000000..e527a184694 --- /dev/null +++ b/kerberosIV/krb/mk_priv.c @@ -0,0 +1,209 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_priv.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * This routine constructs a Kerberos 'private msg', i.e. + * cryptographically sealed with a private session key. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT. + * + * Note-- It's too bad that it did a long int compare on the RT before. + * + * Returns either < 0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + */ + +#include "krb_locl.h" + +#include +#include +#include + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t c_length; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes + * some user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address. +#ifndef NOENCRYTION + * The packet is encrypted by pcbc_encrypt(), using the given + * "key" and "schedule". +#endif + * The length of the resulting packet "out" is + * returned. + * + * It is similar to krb_mk_safe() except for the additional key + * schedule argument "schedule" and the fact that the data is encrypted + * rather than appended with a checksum. Also, the protocol version + * number is "private_msg_ver", defined in krb_rd_priv.c, rather than + * KRB_PROT_VERSION, defined in "krb.h". + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte private_msg_ver protocol version number + * 1 byte AUTH_MSG_PRIVATE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * 4 bytes c_length length of data +#ifndef NOENCRYPT + * we encrypt from here with pcbc_encrypt +#endif + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * 0<=n<=7 bytes pad to 8 byte multiple zeroes + */ + +int32_t +krb_mk_priv(in, out, length, schedule, key, sender, receiver) + u_char *in; /* application data */ + u_char *out; /* put msg here, leave room for + * header! breaks if in and out + * (header stuff) overlap */ + u_int32_t length; /* of in data */ + struct des_ks_struct *schedule; /* precomputed key schedule */ + des_cblock *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + static u_char *c_length_ptr; + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = private_msg_ver; + *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER; + + /* calculate cipher length */ + c_length_ptr = p; + p += sizeof(c_length); + + q = p; + + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + +#ifdef NOENCRYPTION + /* make all the stuff contiguous for checksum */ +#else + /* make all the stuff contiguous for checksum and encryption */ +#endif + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *)&sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok + * until 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + +#ifdef notdef + /* + * calculate the checksum of the length, address, sequence, and + * inp data + */ + cksum = des_quad_cksum(q,NULL,p-q,0,key); + if (krb_debug) + printf("\ncksum = %u",cksum); + /* stuff checksum */ + bcopy((char *) &cksum,(char *) p,sizeof(cksum)); + p += sizeof(cksum); +#endif + + /* + * All the data have been assembled, compute length + */ + + c_length = p - q; + c_length = ((c_length + sizeof(des_cblock) -1)/sizeof(des_cblock)) * + sizeof(des_cblock); + /* stuff the length */ + bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length)); + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)(p-q),schedule,key, DES_ENCRYPT); +#endif /* NOENCRYPTION */ + + return (q - out + c_length); /* resulting size */ +} diff --git a/kerberosIV/krb/mk_req.c b/kerberosIV/krb/mk_req.c new file mode 100644 index 00000000000..cabe872486d --- /dev/null +++ b/kerberosIV/krb/mk_req.c @@ -0,0 +1,207 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_req.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include + +static struct timeval tv_local = { 0, 0 }; +static int lifetime = 255; /* But no longer than TGT says. */ + +/* + * krb_mk_req takes a text structure in which an authenticator is to + * be built, the name of a service, an instance, a realm, + * and a checksum. It then retrieves a ticket for + * the desired service and creates an authenticator in the text + * structure passed as the first argument. krb_mk_req returns + * KSUCCESS on success and a Kerberos error code on failure. + * + * The peer procedure on the other end is krb_rd_req. When making + * any changes to this routine it is important to make corresponding + * changes to krb_rd_req. + * + * The authenticator consists of the following: + * + * authent->dat + * + * unsigned char KRB_PROT_VERSION protocol version no. + * unsigned char AUTH_MSG_APPL_REQUEST message type + * (least significant + * bit of above) HOST_BYTE_ORDER local byte ordering + * unsigned char kvno from ticket server's key version + * string realm server's realm + * unsigned char tl ticket length + * unsigned char idl request id length + * text ticket->dat ticket for server + * text req_id->dat request id + * + * The ticket information is retrieved from the ticket cache or + * fetched from Kerberos. The request id (called the "authenticator" + * in the papers on Kerberos) contains the following: + * + * req_id->dat + * + * string cr.pname {name, instance, and + * string cr.pinst realm of principal + * string myrealm making this request} + * 4 bytes checksum checksum argument given + * unsigned char tv_local.tf_usec time (milliseconds) + * 4 bytes tv_local.tv_sec time (seconds) + * + * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time, + * all rounded up to multiple of 8. + */ + +int +krb_mk_req(authent, service, instance, realm, checksum) + register KTEXT authent; /* Place to build the authenticator */ + char *service; /* Name of the service */ + char *instance; /* Service instance */ + char *realm; /* Authentication domain of service */ + int32_t checksum; /* Checksum of data (optional) */ +{ + static KTEXT_ST req_st; /* Temp storage for req id */ + register KTEXT req_id = &req_st; + unsigned char *v = authent->dat; /* Prot version number */ + unsigned char *t = (authent->dat+1); /* Message type */ + unsigned char *kv = (authent->dat+2); /* Key version no */ + unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */ + unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */ + CREDENTIALS cr; /* Credentials used by retr */ + register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */ + int retval; /* Returned by krb_get_cred */ + static des_key_schedule key_s; + char myrealm[REALM_SZ]; + + /* The fixed parts of the authenticator */ + *v = (unsigned char) KRB_PROT_VERSION; + *t = (unsigned char) AUTH_MSG_APPL_REQUEST; + *t |= HOST_BYTE_ORDER; + + /* Get the ticket and move it into the authenticator */ + if (krb_ap_req_debug) + printf("Realm: %s\n",realm); + /* + * Determine realm of these tickets. We will send this to the + * KDC from which we are requesting tickets so it knows what to + * with our session key. + */ + if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS) + return(retval); + + retval = krb_get_cred(service,instance,realm,&cr); + + if (retval == RET_NOTKT) { + if ((retval = get_ad_tkt(service,instance,realm,lifetime))) + return(retval); + if ((retval = krb_get_cred(service,instance,realm,&cr))) + return(retval); + } + + if (retval != KSUCCESS) return (retval); + + if (krb_ap_req_debug) + printf("%s %s %s %s %s\n", service, instance, realm, + cr.pname, cr.pinst); + *kv = (unsigned char) cr.kvno; + (void) strcpy((char *)(authent->dat+3),realm); + *tl = (unsigned char) ticket->length; + bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)), + ticket->length); + authent->length = 6 + strlen(realm) + ticket->length; + if (krb_ap_req_debug) + printf("Ticket->length = %d\n",ticket->length); + if (krb_ap_req_debug) + printf("Issue date: %d\n",cr.issue_date); + + /* Build request id */ + (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */ + req_id->length = strlen(cr.pname)+1; + /* Principal's instance */ + (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst); + req_id->length += strlen(cr.pinst)+1; + /* Authentication domain */ + (void) strcpy((char *)(req_id->dat+req_id->length),myrealm); + req_id->length += strlen(myrealm)+1; + /* Checksum */ + bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4); + req_id->length += 4; + + /* Fill in the times on the request id */ + (void) gettimeofday(&tv_local,(struct timezone *) 0); + *(req_id->dat+(req_id->length)++) = + (unsigned char) tv_local.tv_usec; + /* Time (coarse) */ + bcopy((char *)&(tv_local.tv_sec), + (char *)(req_id->dat+req_id->length), 4); + req_id->length += 4; + + /* Fill to a multiple of 8 bytes for DES */ + req_id->length = ((req_id->length+7)/8)*8; + +#ifndef NOENCRYPTION + des_key_sched(&cr.session,key_s); + des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat, + (long)req_id->length,key_s,&cr.session, DES_ENCRYPT); + bzero((char *) key_s, sizeof(key_s)); +#endif /* NOENCRYPTION */ + + /* Copy it into the authenticator */ + bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length), + req_id->length); + authent->length += req_id->length; + /* And set the id length */ + *idl = (unsigned char) req_id->length; + /* clean up */ + bzero((char *)req_id, sizeof(*req_id)); + + if (krb_ap_req_debug) + printf("Authent->length = %d\n",authent->length); + if (krb_ap_req_debug) + printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl); + + return(KSUCCESS); +} + +/* + * krb_set_lifetime sets the default lifetime for additional tickets + * obtained via krb_mk_req(). + * + * It returns the previous value of the default lifetime. + */ + +int +krb_set_lifetime(newval) + int newval; +{ + int olife = lifetime; + + lifetime = newval; + return(olife); +} diff --git a/kerberosIV/krb/mk_safe.c b/kerberosIV/krb/mk_safe.c new file mode 100644 index 00000000000..6d49fd80a35 --- /dev/null +++ b/kerberosIV/krb/mk_safe.c @@ -0,0 +1,177 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_safe.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * This routine constructs a Kerberos 'safe msg', i.e. authenticated + * using a private session key to seed a checksum. Msg is NOT + * encrypted. + * + * Note-- bcopy is used to avoid alignment problems on IBM RT + * + * Returns either <0 ===> error, or resulting size of message + * + * Steve Miller Project Athena MIT/DEC + */ + +#include "krb_locl.h" + +/* system include files */ +#include +#include +#include + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t cksum; +static des_cblock big_cksum[2]; +static struct timeval msg_time; +static u_char msg_time_5ms; +static long msg_time_sec; + +/* + * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some + * user data "in" of "length" bytes and creates a packet in "out" + * consisting of the user data, a timestamp, and the sender's network + * address, followed by a checksum computed on the above, using the + * given "key". The length of the resulting packet is returned. + * + * The "out" packet consists of: + * + * Size Variable Field + * ---- -------- ----- + * + * 1 byte KRB_PROT_VERSION protocol version number + * 1 byte AUTH_MSG_SAFE | message type plus local + * HOST_BYTE_ORDER byte order in low bit + * + * ===================== begin checksum ================================ + * + * 4 bytes length length of user data + * length in user data + * 1 byte msg_time_5ms timestamp milliseconds + * 4 bytes sender->sin.addr.s_addr sender's IP address + * + * 4 bytes msg_time_sec or timestamp seconds with + * -msg_time_sec direction in sign bit + * + * ======================= end checksum ================================ + * + * 16 bytes big_cksum quadratic checksum of + * above using "key" + */ + +int32_t +krb_mk_safe(in, out, length, key, sender, receiver) + u_char *in; /* application data */ + u_char *out; /* + * put msg here, leave room for header! + * breaks if in and out (header stuff) + * overlap + */ + u_int32_t length; /* of in data */ + des_cblock *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender address */ + struct sockaddr_in *receiver; /* receiver address */ +{ + register u_char *p,*q; + + /* + * get the current time to use instead of a sequence #, since + * process lifetime may be shorter than the lifetime of a session + * key. + */ + if (gettimeofday(&msg_time,(struct timezone *)0)) { + return -1; + } + msg_time_sec = (long) msg_time.tv_sec; + msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */ + + p = out; + + *p++ = KRB_PROT_VERSION; + *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER; + + q = p; /* start for checksum stuff */ + /* stuff input length */ + bcopy((char *)&length,(char *)p,sizeof(length)); + p += sizeof(length); + + /* make all the stuff contiguous for checksum */ + bcopy((char *)in,(char *)p,(int) length); + p += length; + + /* stuff time 5ms */ + bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms)); + p += sizeof(msg_time_5ms); + + /* stuff source address */ + bcopy((char *) &sender->sin_addr.s_addr,(char *)p, + sizeof(sender->sin_addr.s_addr)); + p += sizeof(sender->sin_addr.s_addr); + + /* + * direction bit is the sign bit of the timestamp. Ok until + * 2038?? + */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ + receiver->sin_addr.s_addr)==-1) + msg_time_sec = -msg_time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) + msg_time_sec = -msg_time_sec; + /* + * all that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* stuff time sec */ + bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec)); + p += sizeof(msg_time_sec); + +#ifdef NOENCRYPTION + cksum = 0; + bzero(big_cksum, sizeof(big_cksum)); +#else + cksum = des_quad_cksum((des_cblock *)q,big_cksum,p-q,2,key); +#endif + if (krb_debug) + printf("\ncksum = %u",(u_int) cksum); + + /* stuff checksum */ + bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum)); + p += sizeof(big_cksum); + + return ((long)(p - out)); /* resulting size */ + +} diff --git a/kerberosIV/krb/month_sname.c b/kerberosIV/krb/month_sname.c new file mode 100644 index 00000000000..55f5ea4d2ed --- /dev/null +++ b/kerberosIV/krb/month_sname.c @@ -0,0 +1,47 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/month_sname.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * Given an integer 1-12, month_sname() returns a string + * containing the first three letters of the corresponding + * month. Returns 0 if the argument is out of range. + */ + +char * +month_sname(n) + int n; +{ + static char *name[] = { + "Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec" + }; + return((n < 1 || n > 12) ? 0 : name [n-1]); +} diff --git a/kerberosIV/krb/netread.c b/kerberosIV/krb/netread.c new file mode 100644 index 00000000000..e362017f641 --- /dev/null +++ b/kerberosIV/krb/netread.c @@ -0,0 +1,63 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/netread.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * krb_net_read() reads from the file descriptor "fd" to the buffer + * "buf", until either 1) "len" bytes have been read or 2) cannot + * read anymore from "fd". It returns the number of bytes read + * or a read() error. (The calling interface is identical to + * read(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_read(fd, buf, len) + int fd; + register char *buf; + register int len; +{ + int cc, len2 = 0; + + do { + cc = read(fd, buf, len); + if (cc < 0) + return(cc); /* errno is already set */ + else if (cc == 0) { + return(len2); + } else { + buf += cc; + len2 += cc; + len -= cc; + } + } while (len > 0); + return(len2); +} diff --git a/kerberosIV/krb/netwrite.c b/kerberosIV/krb/netwrite.c new file mode 100644 index 00000000000..4c7146db6a6 --- /dev/null +++ b/kerberosIV/krb/netwrite.c @@ -0,0 +1,59 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/netwrite.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * krb_net_write() writes "len" bytes from "buf" to the file + * descriptor "fd". It returns the number of bytes written or + * a write() error. (The calling interface is identical to + * write(2).) + * + * XXX must not use non-blocking I/O + */ + +int +krb_net_write(fd, buf, len) + int fd; + register char *buf; + int len; +{ + int cc; + register int wrlen = len; + do { + cc = write(fd, buf, wrlen); + if (cc < 0) + return(cc); + else { + buf += cc; + wrlen -= cc; + } + } while (wrlen > 0); + return(len); +} diff --git a/kerberosIV/krb/one.c b/kerberosIV/krb/one.c new file mode 100644 index 00000000000..beff561ce62 --- /dev/null +++ b/kerberosIV/krb/one.c @@ -0,0 +1,35 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/one.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of M.I.T. not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior + permission. M.I.T. makes no representations about the suitability of + this software for any purpose. It is provided "as is" without express + or implied warranty. + + */ + +/* + * definition of variable set to 1. + * used in krb_conf.h to determine host byte order. + */ + +int krbONE = 1; diff --git a/kerberosIV/krb/pkt_cipher.c b/kerberosIV/krb/pkt_cipher.c new file mode 100644 index 00000000000..ecf90bd2be0 --- /dev/null +++ b/kerberosIV/krb/pkt_cipher.c @@ -0,0 +1,50 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/pkt_cipher.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine takes a reply packet from the Kerberos ticket-granting + * service and returns a pointer to the beginning of the ciphertext in it. + * + * See "prot.h" for packet format. + */ + +char * +pkt_cipher(packet) + KTEXT packet; +{ + unsigned char *ptr = pkt_a_realm(packet) + 6 + + strlen((char *)pkt_a_realm(packet)); + /* Skip a few more fields */ + ptr += 3 + 4; /* add 4 for exp_date */ + + /* And return the pointer */ + return((char*)ptr); +} diff --git a/kerberosIV/krb/pkt_clen.c b/kerberosIV/krb/pkt_clen.c new file mode 100644 index 00000000000..00ecc734df8 --- /dev/null +++ b/kerberosIV/krb/pkt_clen.c @@ -0,0 +1,68 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/pkt_clen.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#if defined(horrible_function_using_global_variable_had_to_be_inlined) + +#include "krb_locl.h" + +/* + * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of + * its ciphertext portion. The external variable "swap_bytes" is assumed + * to have been set to indicate whether or not the packet is in local + * byte order. pkt_clen() takes this into account when reading the + * ciphertext length out of the packet. + */ + +int +pkt_clen(pkt) + KTEXT pkt; +{ + static unsigned short temp,temp2; + int clen = 0; + + /* Start of ticket list */ + unsigned char *ptr = pkt_a_realm(pkt) + 10 + + strlen((char *)pkt_a_realm(pkt)); + + /* Finally the length */ + bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */ + if (swap_bytes) { + /* assume a short is 2 bytes?? */ + swab((char *)&temp,(char *)&temp2,2); + temp = temp2; + } + + clen = (int) temp; + + if (krb_debug) + printf("Clen is %d\n",clen); + return(clen); +} + +#endif /* defined(horrible_function_using_global_variable_had_to_be_inlined) */ diff --git a/kerberosIV/krb/rd_err.c b/kerberosIV/krb/rd_err.c new file mode 100644 index 00000000000..33c3cf0b529 --- /dev/null +++ b/kerberosIV/krb/rd_err.c @@ -0,0 +1,91 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_err.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * This routine dissects a a Kerberos 'safe msg', + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + */ + +#include "krb_locl.h" + +/* system include files */ +#include +#include +#include + +/* + * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length", + * return the error code from the message in "code" and the text in + * "m_data" as follows: + * + * m_data->app_data points to the error text + * m_data->app_length points to the length of the error text + * + * If all goes well, return RD_AP_OK. If the version number + * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR + * type message, return RD_AP_MSG_TYPE. + * + * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c + */ + +int +krb_rd_err(in, in_length, code, m_data) + u_char *in; /* pointer to the msg received */ + u_int32_t in_length; /* of in msg */ + int32_t *code; /* received error code */ + MSG_DAT *m_data; +{ + register u_char *p; + int swap_bytes = 0; + p = in; /* beginning of message */ + + if (*p++ != KRB_PROT_VERSION) + return(RD_AP_VERSION); + if (((*p) & ~1) != AUTH_MSG_APPL_ERR) + return(RD_AP_MSG_TYPE); + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* safely get code */ + bcopy((char *)p,(char *)code,sizeof(*code)); + if (swap_bytes) + swap_u_long(*code); + p += sizeof(*code); /* skip over */ + + m_data->app_data = p; /* we're now at the error text + * message */ + m_data->app_length = in_length; + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/kerberosIV/krb/rd_priv.c b/kerberosIV/krb/rd_priv.c new file mode 100644 index 00000000000..21c959e34c9 --- /dev/null +++ b/kerberosIV/krb/rd_priv.c @@ -0,0 +1,215 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_priv.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * This routine dissects a a Kerberos 'private msg', decrypting it, + * checking its integrity, and returning a pointer to the application + * data contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If + * the return value is RD_AP_TIME, then either the times are too far + * out of synch, OR the packet was modified. + * + * Steve Miller Project Athena MIT/DEC + */ + +#include "krb_locl.h" + +/* system include files */ +#include +#include +#include + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static u_int32_t c_length; +static int swap_bytes; +static struct timeval local_time; +static long delta_t; + +/* Global! */ +int private_msg_ver = KRB_PROT_VERSION; + +/* +#ifdef NOENCRPYTION + * krb_rd_priv() checks the integrity of an +#else + * krb_rd_priv() decrypts and checks the integrity of an +#endif + * AUTH_MSG_PRIVATE message. Given the message received, "in", + * the length of that message, "in_length", the key "schedule" + * and "key", and the network addresses of the + * "sender" and "receiver" of the message, krb_rd_safe() returns + * RD_AP_OK if the message is okay, otherwise some error code. + * + * The message data retrieved from "in" are returned in the structure + * "m_data". The pointer to the application data + * (m_data->app_data) refers back to the appropriate place in "in". + * + * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +int32_t +krb_rd_priv(in, in_length, schedule, key, sender, receiver, m_data) + u_char *in; /* pointer to the msg received */ + u_int32_t in_length; /* length of "in" msg */ + struct des_ks_struct *schedule; /* precomputed key schedule */ + des_cblock *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; + struct sockaddr_in *receiver; + MSG_DAT *m_data; /*various input/output data from msg */ +{ + register u_char *p,*q; + static u_int32_t src_addr; /* Can't send structs since no + * guarantees on size */ + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION && *(p-1) != 3) + return RD_AP_VERSION; + private_msg_ver = *(p-1); + if (((*p) & ~1) != AUTH_MSG_PRIVATE) + return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* get cipher length */ + bcopy((char *)p,(char *)&c_length,sizeof(c_length)); + if (swap_bytes) + swap_u_long(c_length); + p += sizeof(c_length); + /* check for rational length so we don't go comatose */ + if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length) + return RD_AP_MODIFIED; + + + q = p; /* mark start of encrypted stuff */ + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)c_length,schedule,key,DES_DECRYPT); +#endif + + /* safely get application data length */ + bcopy((char *) p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) + swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(c_length) + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ + > in_length) + return RD_AP_MODIFIED; + +#ifndef NOENCRYPTION + /* we're now at the decrypted application data */ +#endif + m_data->app_data = p; + + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *) p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *) p,(char *)&src_addr,sizeof(src_addr)); + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (!krb_equiv(src_addr, sender->sin_addr.s_addr)) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *) p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) swap_u_long(m_data->time_sec); + + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + /* + * all that for one tiny bit! + * Heaven help those that talk to themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec + - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) + return RD_AP_TIME; + if (krb_debug) + printf("\ndelta_t = %d", (int) delta_t); + + /* + * caller must check timestamps for proper order and + * replays, since server might have multiple clients + * each with its own timestamps and we don't assume + * tightly synchronized clocks. + */ + +#ifdef notdef + bcopy((char *) p,(char *)&cksum,sizeof(cksum)); + if (swap_bytes) swap_u_long(cksum) + /* + * calculate the checksum of the length, sequence, + * and input data, on the sending byte order!! + */ + calc_cksum = des_quad_cksum(q,NULL,p-q,0,key); + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + calc_cksum, cksum); + if (cksum != calc_cksum) + return RD_AP_MODIFIED; +#endif + return RD_AP_OK; /* OK == 0 */ +} diff --git a/kerberosIV/krb/rd_req.c b/kerberosIV/krb/rd_req.c new file mode 100644 index 00000000000..4d281461a87 --- /dev/null +++ b/kerberosIV/krb/rd_req.c @@ -0,0 +1,344 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_req.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include + +static struct timeval t_local = { 0, 0 }; + +/* + * Keep the following information around for subsequent calls + * to this routine by the same server using the same key. + */ + +static des_key_schedule serv_key; /* Key sched to decrypt ticket */ +static des_cblock ky; /* Initialization vector */ +static int st_kvno; /* version number for this key */ +static char st_rlm[REALM_SZ]; /* server's realm */ +static char st_nam[ANAME_SZ]; /* service name */ +static char st_inst[INST_SZ]; /* server's instance */ + +/* + * This file contains two functions. krb_set_key() takes a DES + * key or password string and returns a DES key (either the original + * key, or the password converted into a DES key) and a key schedule + * for it. + * + * krb_rd_req() reads an authentication request and returns information + * about the identity of the requestor, or an indication that the + * identity information was not authentic. + */ + +/* + * krb_set_key() takes as its first argument either a DES key or a + * password string. The "cvt" argument indicates how the first + * argument "key" is to be interpreted: if "cvt" is null, "key" is + * taken to be a DES key; if "cvt" is non-null, "key" is taken to + * be a password string, and is converted into a DES key using + * string_to_key(). In either case, the resulting key is returned + * in the external static variable "ky". A key schedule is + * generated for "ky" and returned in the external static variable + * "serv_key". + * + * This routine returns the return value of des_key_sched. + * + * krb_set_key() needs to be in the same .o file as krb_rd_req() so that + * the key set by krb_set_key() is available in private storage for + * krb_rd_req(). + */ + +int +krb_set_key(key, cvt) + char *key; + int cvt; +{ +#ifdef NOENCRYPTION + bzero(ky, sizeof(ky)); + return KSUCCESS; +#else /* Encrypt */ + if (cvt) + des_string_to_key(key,&ky); + else + bcopy(key,(char *)ky,8); + return(des_key_sched(&ky,serv_key)); +#endif /* NOENCRYPTION */ +} + + +/* + * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or + * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), + * checks its integrity and returns a judgement as to the requestor's + * identity. + * + * The "authent" argument is a pointer to the received message. + * The "service" and "instance" arguments name the receiving server, + * and are used to get the service's ticket to decrypt the ticket + * in the message, and to compare against the server name inside the + * ticket. "from_addr" is the network address of the host from which + * the message was received; this is checked against the network + * address in the ticket. If "from_addr" is zero, the check is not + * performed. "ad" is an AUTH_DAT structure which is + * filled in with information about the sender's identity according + * to the authenticator and ticket sent in the message. Finally, + * "fn" contains the name of the file containing the server's key. + * (If "fn" is NULL, the server's key is assumed to have been set + * by krb_set_key(). If "fn" is the null string ("") the default + * file KEYFILE, defined in "krb.h", is used.) + * + * krb_rd_req() returns RD_AP_OK if the authentication information + * was genuine, or one of the following error codes (defined in + * "krb.h"): + * + * RD_AP_VERSION - wrong protocol version number + * RD_AP_MSG_TYPE - wrong message type + * RD_AP_UNDEC - couldn't decipher the message + * RD_AP_INCON - inconsistencies found + * RD_AP_BADD - wrong network address + * RD_AP_TIME - client time (in authenticator) + * too far off server time + * RD_AP_NYV - Kerberos time (in ticket) too + * far off server time + * RD_AP_EXP - ticket expired + * + * For the message format, see krb_mk_req(). + * + * Mutual authentication is not implemented. + */ + +int +krb_rd_req(authent, service, instance, from_addr, ad, fn) + register KTEXT authent; /* The received message */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int32_t from_addr; /* Net address of originating host */ + AUTH_DAT *ad; /* Structure to be filled in */ + char *fn; /* Filename to get keys from */ +{ + static KTEXT_ST ticket; /* Temp storage for ticket */ + static KTEXT tkt = &ticket; + static KTEXT_ST req_id_st; /* Temp storage for authenticator */ + register KTEXT req_id = &req_id_st; + + char realm[REALM_SZ]; /* Realm of issuing kerberos */ + static des_key_schedule seskey_sched; /* Key sched for session key */ + unsigned char skey[KKEY_SZ]; /* Session key from ticket */ + char sname[SNAME_SZ]; /* Service name from ticket */ + char iname[INST_SZ]; /* Instance name from ticket */ + char r_aname[ANAME_SZ]; /* Client name from authenticator */ + char r_inst[INST_SZ]; /* Client instance from authenticator */ + char r_realm[REALM_SZ]; /* Client realm from authenticator */ + unsigned int r_time_ms; /* Fine time from authenticator */ + unsigned long r_time_sec; /* Coarse time from authenticator */ + register char *ptr; /* For stepping through */ + unsigned long delta_t; /* Time in authenticator - local time */ + long tkt_age; /* Age of ticket */ + static int swap_bytes; /* Need to swap bytes? */ + static int mutual; /* Mutual authentication requested? */ + static unsigned char s_kvno;/* Version number of the server's key + * Kerberos used to encrypt ticket */ + int status; + + if (authent->length <= 0) + return(RD_AP_MODIFIED); + + ptr = (char *) authent->dat; + + /* get msg version, type and byte order, and server key version */ + + /* check version */ + if (KRB_PROT_VERSION != (unsigned int) *ptr++) + return(RD_AP_VERSION); + + /* byte order */ + swap_bytes = 0; + if ((*ptr & 1) != HOST_BYTE_ORDER) + swap_bytes++; + + /* check msg type */ + mutual = 0; + switch (*ptr++ & ~1) { + case AUTH_MSG_APPL_REQUEST: + break; + case AUTH_MSG_APPL_REQUEST_MUTUAL: + mutual++; + break; + default: + return(RD_AP_MSG_TYPE); + } + +#ifdef lint + /* XXX mutual is set but not used; why??? */ + /* this is a crock to get lint to shut up */ + if (mutual) + mutual = 0; +#endif /* lint */ + s_kvno = *ptr++; /* get server key version */ + (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */ + ptr += strlen(ptr) + 1; /* skip the realm "hint" */ + + /* + * If "fn" is NULL, key info should already be set; don't + * bother with ticket file. Otherwise, check to see if we + * already have key info for the given server and key version + * (saved in the static st_* variables). If not, go get it + * from the ticket file. If "fn" is the null string, use the + * default ticket file. + */ + if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) || + strcmp(st_rlm,realm) || (st_kvno != s_kvno))) { + if (*fn == 0) fn = KEYFILE; + st_kvno = s_kvno; +#ifndef NOENCRYPTION + if (read_service_key(service,instance,realm,(int) s_kvno, + fn,(char *)skey)) + return(RD_AP_UNDEC); + if ((status = krb_set_key((char *)skey,0))) + return(status); +#endif /* !NOENCRYPTION */ + (void) strcpy(st_rlm,realm); + (void) strcpy(st_nam,service); + (void) strcpy(st_inst,instance); + } + + /* Get ticket from authenticator */ + tkt->length = (int) *ptr++; + if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr+1,(char *)(tkt->dat),tkt->length); + + if (krb_ap_req_debug) + log("ticket->length: %d",tkt->length); + +#ifndef NOENCRYPTION + /* Decrypt and take apart ticket */ +#endif + + if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, + &(ad->address),ad->session, &(ad->life), + &(ad->time_sec),sname,iname,&ky,serv_key)) + return(RD_AP_UNDEC); + + if (krb_ap_req_debug) { + log("Ticket Contents."); + log(" Aname: %s.%s",ad->pname, + ((int)*(ad->prealm) ? ad->prealm : "Athena")); + log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname); + } + + /* Extract the authenticator */ + req_id->length = (int) *(ptr++); + if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) > + authent->length) + return(RD_AP_MODIFIED); + bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length); + +#ifndef NOENCRYPTION + /* And decrypt it with the session key from the ticket */ + if (krb_ap_req_debug) log("About to decrypt authenticator"); + des_key_sched(&ad->session,seskey_sched); + des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat, + (long) req_id->length, seskey_sched,&ad->session,DES_DECRYPT); + if (krb_ap_req_debug) log("Done."); +#endif /* NOENCRYPTION */ + +#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); + + ptr = (char *) req_id->dat; + (void) strcpy(r_aname,ptr); /* Authentication name */ + ptr += strlen(r_aname)+1; + check_ptr(); + (void) strcpy(r_inst,ptr); /* Authentication instance */ + ptr += strlen(r_inst)+1; + check_ptr(); + (void) strcpy(r_realm,ptr); /* Authentication name */ + ptr += strlen(r_realm)+1; + check_ptr(); + bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */ + ptr += 4; + check_ptr(); + if (swap_bytes) swap_u_long(ad->checksum); + r_time_ms = *(ptr++); /* Time (fine) */ +#ifdef lint + /* XXX r_time_ms is set but not used. why??? */ + /* this is a crock to get lint to shut up */ + if (r_time_ms) + r_time_ms = 0; +#endif /* lint */ + check_ptr(); + /* assume sizeof(r_time_sec) == 4 ?? */ + bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */ + if (swap_bytes) swap_u_long(r_time_sec); + + /* Check for authenticity of the request */ + if (krb_ap_req_debug) + log("Pname: %s %s",ad->pname,r_aname); + if (strcmp(ad->pname,r_aname) != 0) + return(RD_AP_INCON); + if (strcmp(ad->pinst,r_inst) != 0) + return(RD_AP_INCON); + if (krb_ap_req_debug) + log("Realm: %s %s",ad->prealm,r_realm); + if ((strcmp(ad->prealm,r_realm) != 0)) + return(RD_AP_INCON); + + if (krb_ap_req_debug) + log("Address: %d %d",ad->address,from_addr); + if (from_addr && (!krb_equiv(ad->address, from_addr))) + return(RD_AP_BADD); + + (void) gettimeofday(&t_local,(struct timezone *) 0); + delta_t = abs((int)(t_local.tv_sec - r_time_sec)); + if (delta_t > CLOCK_SKEW) { + if (krb_ap_req_debug) + log("Time out of range: %d - %d = %d", + t_local.tv_sec,r_time_sec,delta_t); + return(RD_AP_TIME); + } + + /* Now check for expiration of ticket */ + + tkt_age = t_local.tv_sec - ad->time_sec; + if (krb_ap_req_debug) + log("Time: %d Issue Date: %d Diff: %d Life %x", + t_local.tv_sec,ad->time_sec,tkt_age,ad->life); + + if (t_local.tv_sec < ad->time_sec) { + if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW) + return(RD_AP_NYV); + } + else if (t_local.tv_sec > krb_life_to_time(ad->time_sec, ad->life)) + return(RD_AP_EXP); + + /* All seems OK */ + ad->reply.length = 0; + + return(RD_AP_OK); +} diff --git a/kerberosIV/krb/rd_safe.c b/kerberosIV/krb/rd_safe.c new file mode 100644 index 00000000000..aeb829a8887 --- /dev/null +++ b/kerberosIV/krb/rd_safe.c @@ -0,0 +1,189 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_safe.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +/* + * This routine dissects a a Kerberos 'safe msg', checking its + * integrity, and returning a pointer to the application data + * contained and its length. + * + * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...) + * + * Steve Miller Project Athena MIT/DEC + */ + +#include "krb_locl.h" + +/* system include files */ +#include +#include +#include + +/* application include files */ +#include "lsb_addr_comp.h" + +/* static storage */ +static des_cblock calc_cksum[2]; +static des_cblock big_cksum[2]; +static int swap_bytes; +static struct timeval local_time; +static u_int32_t delta_t; + +/* + * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message. + * Given the message received, "in", the length of that message, + * "in_length", the "key" to compute the checksum with, and the + * network addresses of the "sender" and "receiver" of the message, + * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise + * some error code. + * + * The message data retrieved from "in" is returned in the structure + * "m_data". The pointer to the application data (m_data->app_data) + * refers back to the appropriate place in "in". + * + * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE + * message. The structure containing the extracted message + * information, MSG_DAT, is defined in "krb.h". + */ + +int32_t +krb_rd_safe(in, in_length, key, sender, receiver, m_data) + u_char *in; /* pointer to the msg received */ + u_int32_t in_length; /* length of "in" msg */ + des_cblock *key; /* encryption key for seed and ivec */ + struct sockaddr_in *sender; /* sender's address */ + struct sockaddr_in *receiver; /* receiver's address -- me */ + MSG_DAT *m_data; /* where to put message information */ +{ + register u_char *p,*q; + static u_int32_t src_addr; /* Can't send structs since no + * guarantees on size */ + /* Be very conservative */ + if (sizeof(src_addr) != sizeof(struct in_addr)) { + fprintf(stderr,"\n\ +krb_rd_safe protocol err sizeof(src_addr) != sizeof(struct in_addr)"); + exit(-1); + } + + if (gettimeofday(&local_time,(struct timezone *)0)) + return -1; + + p = in; /* beginning of message */ + swap_bytes = 0; + + if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION; + if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE; + if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++; + + q = p; /* mark start of cksum stuff */ + + /* safely get length */ + bcopy((char *)p,(char *)&(m_data->app_length), + sizeof(m_data->app_length)); + if (swap_bytes) swap_u_long(m_data->app_length); + p += sizeof(m_data->app_length); /* skip over */ + + if (m_data->app_length + sizeof(in_length) + + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + + sizeof(big_cksum) + sizeof(src_addr) + + VERSION_SZ + MSG_TYPE_SZ > in_length) + return(RD_AP_MODIFIED); + + m_data->app_data = p; /* we're now at the application data */ + + /* skip app data */ + p += m_data->app_length; + + /* safely get time_5ms */ + bcopy((char *)p, (char *)&(m_data->time_5ms), + sizeof(m_data->time_5ms)); + + /* don't need to swap-- one byte for now */ + p += sizeof(m_data->time_5ms); + + /* safely get src address */ + bcopy((char *)p,(char *)&src_addr,sizeof(src_addr)); + + /* don't swap, net order always */ + p += sizeof(src_addr); + + if (!krb_equiv(src_addr, sender->sin_addr.s_addr)) + return RD_AP_MODIFIED; + + /* safely get time_sec */ + bcopy((char *)p, (char *)&(m_data->time_sec), + sizeof(m_data->time_sec)); + if (swap_bytes) + swap_u_long(m_data->time_sec); + p += sizeof(m_data->time_sec); + + /* check direction bit is the sign bit */ + /* For compatibility with broken old code, compares are done in VAX + byte order (LSBFIRST) */ + if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + else if (lsb_net_ulong_less(sender->sin_addr.s_addr, + receiver->sin_addr.s_addr)==0) + if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) + /* src < recv */ + m_data->time_sec = - m_data->time_sec; + + /* + * All that for one tiny bit! Heaven help those that talk to + * themselves. + */ + + /* check the time integrity of the msg */ + delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec)); + if (delta_t > CLOCK_SKEW) return RD_AP_TIME; + + /* + * caller must check timestamps for proper order and replays, since + * server might have multiple clients each with its own timestamps + * and we don't assume tightly synchronized clocks. + */ + + bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum)); + if (swap_bytes) swap_u_16(big_cksum); + +#ifdef NOENCRYPTION + bzero(calc_cksum, sizeof(calc_cksum)); +#else + des_quad_cksum((des_cblock *)q,calc_cksum,p-q,2,key); +#endif + + if (krb_debug) + printf("\ncalc_cksum = %u, received cksum = %u", + (u_int) calc_cksum[0], (u_int) big_cksum[0]); + if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum))) + return(RD_AP_MODIFIED); + + return(RD_AP_OK); /* OK == 0 */ +} diff --git a/kerberosIV/krb/read_service_key.c b/kerberosIV/krb/read_service_key.c new file mode 100644 index 00000000000..8c2a8f299c6 --- /dev/null +++ b/kerberosIV/krb/read_service_key.c @@ -0,0 +1,133 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/read_service_key.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * The private keys for servers on a given host are stored in a + * "srvtab" file (typically "/etc/srvtab"). This routine extracts + * a given server's key from the file. + * + * read_service_key() takes the server's name ("service"), "instance", + * and "realm" and a key version number "kvno", and looks in the given + * "file" for the corresponding entry, and if found, returns the entry's + * key field in "key". + * + * If "instance" contains the string "*", then it will match + * any instance, and the chosen instance will be copied to that + * string. For this reason it is important that the there is enough + * space beyond the "*" to receive the entry. + * + * If "kvno" is 0, it is treated as a wild card and the first + * matching entry regardless of the "vno" field is returned. + * + * This routine returns KSUCCESS on success, otherwise KFAILURE. + * + * The format of each "srvtab" entry is as follows: + * + * Size Variable Field in file + * ---- -------- ------------- + * string serv server name + * string inst server instance + * string realm server realm + * 1 byte vno server key version # + * 8 bytes key server's key + * ... ... ... + */ + + +/*ARGSUSED */ +int +read_service_key(service, instance, realm, kvno, file, key) + char *service; /* Service Name */ + char *instance; /* Instance name or "*" */ + char *realm; /* Realm */ + int kvno; /* Key version number */ + char *file; /* Filename */ + char *key; /* Pointer to key to be filled in */ +{ + char serv[SNAME_SZ]; + char inst[INST_SZ]; + char rlm[REALM_SZ]; + unsigned char vno; /* Key version number */ + int wcard; + + int stab, open(const char *, int, ...); + + if ((stab = open(file, 0, 0)) < 0) + return(KFAILURE); + + wcard = (instance[0] == '*') && (instance[1] == '\0'); + + while (getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */ + (void) getst(stab,inst,INST_SZ); /* Instance */ + (void) getst(stab,rlm,REALM_SZ); /* Realm */ + /* Vers number */ + if (read(stab,(char *)&vno,1) != 1) { + close(stab); + return(KFAILURE); + } + /* Key */ + if (read(stab,key,8) != 8) { + close(stab); + return(KFAILURE); + } + /* Is this the right service */ + if (strcmp(serv,service)) + continue; + /* How about instance */ + if (!wcard && strcmp(inst,instance)) + continue; + if (wcard) + (void) strncpy(instance,inst,INST_SZ); + /* Is this the right realm */ +#ifdef ATHENA_COMPAT + /* XXX For backward compatibility: if keyfile says "Athena" + and caller wants "ATHENA.MIT.EDU", call it a match */ + if (strcmp(rlm,realm) && + (strcmp(rlm,"Athena") || + strcmp(realm,"ATHENA.MIT.EDU"))) + continue; +#else /* ! ATHENA_COMPAT */ + if (strcmp(rlm,realm)) + continue; +#endif /* ATHENA_COMPAT */ + + /* How about the key version number */ + if (kvno && kvno != (int) vno) + continue; + + (void) close(stab); + return(KSUCCESS); + } + + /* Can't find the requested service */ + (void) close(stab); + return(KFAILURE); +} diff --git a/kerberosIV/krb/recvauth.c b/kerberosIV/krb/recvauth.c new file mode 100644 index 00000000000..3a5949e05d4 --- /dev/null +++ b/kerberosIV/krb/recvauth.c @@ -0,0 +1,295 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/recvauth.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_sendauth.c + * be sure to support old versions of krb_sendauth! + */ +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN + chars */ + +/* + * krb_recvauth() reads (and optionally responds to) a message sent + * using krb_sendauth(). The "options" argument is a bit-field of + * selected options (see "sendauth.c" for options description). + * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL + * (mutual authentication requested). The "fd" argument supplies + * a file descriptor to read from (and write to, if mutual authenti- + * cation is requested). + * + * Part of the received message will be a Kerberos ticket sent by the + * client; this is read into the "ticket" argument. The "service" and + * "instance" arguments supply the server's Kerberos name. If the + * "instance" argument is the string "*", it is treated as a wild card + * and filled in during the krb_rd_req() call (see read_service_key()). + * + * The "faddr" and "laddr" give the sending (client) and receiving + * (local server) network addresses. ("laddr" may be left NULL unless + * mutual authentication is requested, in which case it must be set.) + * + * The authentication information extracted from the message is returned + * in "kdata". The "filename" argument indicates the file where the + * server's key can be found. (It is passed on to krb_rd_req().) If + * left null, the default "/etc/srvtab" will be used. + * + * If mutual authentication is requested, the session key schedule must + * be computed in order to reply; this schedule is returned in the + * "schedule" argument. A string containing the application version + * number from the received message is returned in "version", which + * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. + * + * See krb_sendauth() for the format of the received client message. + * + * This routine supports another client format, for backward + * compatibility, consisting of: + * + * Size Variable Field + * ---- -------- ----- + * + * string tmp_buf, tkt_len length of ticket, in + * ascii + * + * char ' ' (space char) separator + * + * tkt_len ticket->dat the ticket + * + * This old-style version does not support mutual authentication. + * + * krb_recvauth() first reads the protocol version string from the + * given file descriptor. If it doesn't match the current protocol + * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In + * that case, the string of characters up to the first space is read + * and interpreted as the ticket length, then the ticket is read. + * + * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() + * next reads the application protocol version string. Then the + * ticket length and ticket itself are read. + * + * The ticket is decrypted and checked by the call to krb_rd_req(). + * If no mutual authentication is required, the result of the + * krb_rd_req() call is retured by this routine. If mutual authenti- + * cation is required, a message in the following format is returned + * on "fd": + * + * Size Variable Field + * ---- -------- ----- + * + * 4 bytes tkt_len length of ticket or -1 + * if error occurred + * + * priv_len tmp_buf "private" message created + * by krb_mk_priv() which + * contains the incremented + * checksum sent by the client + * encrypted in the session + * key. (This field is not + * present in case of error.) + * + * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some + * other error code is returned. + */ + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif /* max */ + +int +krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, + filename, schedule, version) + int32_t options; /* bit-pattern of options */ + int fd; /* file descr. to read from */ + KTEXT ticket; /* storage for client's ticket */ + char *service; /* service expected */ + char *instance; /* inst expected (may be filled in) */ + struct sockaddr_in *faddr; /* address of foreign host on fd */ + struct sockaddr_in *laddr; /* local address */ + AUTH_DAT *kdata; /* kerberos data (returned) */ + char *filename; /* name of file with service keys */ + struct des_ks_struct *schedule; /* key schedule (return) */ + char *version; /* version string (filled in) */ +{ + + int i, cc, old_vers = 0; + char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ + char *cp; + int rem; + long tkt_len, priv_len; + u_int32_t cksum; + u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)]; + + /* read the protocol version number */ + if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + krb_vers[KRB_SENDAUTH_VLEN] = '\0'; + + /* check version string */ + if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) { + /* Assume the old version of sendkerberosdata: send ascii + length, ' ', and ticket. */ + if (options & KOPT_DO_MUTUAL) + return(KFAILURE); /* XXX can't do old style with mutual auth */ + old_vers = 1; + + /* copy what we have read into tmp_buf */ + (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN); + + /* search for space, and make it a null */ + for (i = 0; i < KRB_SENDAUTH_VLEN; i++) + if (tmp_buf[i]== ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + + if (i == KRB_SENDAUTH_VLEN) + /* didn't find the space, keep reading to find it */ + for (; i<20; i++) { + if (read(fd, (char *)&tmp_buf[i], 1) != 1) { + return(KFAILURE); + } + if (tmp_buf[i] == ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + } + + tkt_len = (long) atoi((char *) tmp_buf); + + /* sanity check the length */ + if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN)) + return(KFAILURE); + + if (i < KRB_SENDAUTH_VLEN) { + /* since we already got the space, and part of the ticket, + we read fewer bytes to get the rest of the ticket */ + if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), + (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + return(errno); + } else { + if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != + (int) tkt_len) + return(errno); + } + ticket->length = tkt_len; + /* copy the ticket into the struct */ + (void) bcopy(cp, (char *) ticket->dat, ticket->length); + + } else { + /* read the application version string */ + if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + version[KRB_SENDAUTH_VLEN] = '\0'; + + /* get the length of the ticket */ + if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + + /* sanity check */ + ticket->length = ntohl((unsigned long)tkt_len); + if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) { + if (options & KOPT_DO_MUTUAL) { + rem = KFAILURE; + goto mutual_fail; + } else + return(KFAILURE); /* XXX there may still be junk on the fd? */ + } + + /* read the ticket */ + if (krb_net_read(fd, (char *) ticket->dat, ticket->length) + != ticket->length) + return(errno); + } + /* + * now have the ticket. decrypt it to get the authenticated + * data. + */ + rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr, + kdata,filename); + + if (old_vers) return(rem); /* XXX can't do mutual with old client */ + + /* if we are doing mutual auth, compose a response */ + if (options & KOPT_DO_MUTUAL) { + if (rem != KSUCCESS) + /* the krb_rd_req failed */ + goto mutual_fail; + + /* add one to the (formerly) sealed checksum, and re-seal it + for return to the client */ + cksum = kdata->checksum + 1; + cksum = htonl(cksum); +#ifndef NOENCRYPTION + des_key_sched(&kdata->session,schedule); +#endif + priv_len = krb_mk_priv((unsigned char *)&cksum, + tmp_buf, + (unsigned long) sizeof(cksum), + schedule, + &kdata->session, + laddr, + faddr); + if (priv_len < 0) { + /* re-sealing failed; notify the client */ + rem = KFAILURE; /* XXX */ +mutual_fail: + priv_len = -1; + tkt_len = htonl((unsigned long) priv_len); + /* a length of -1 is interpreted as an authentication + failure by the client */ + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + return(rem); + } else { + /* re-sealing succeeded, send the private message */ + tkt_len = htonl((unsigned long)priv_len); + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len)) + != (int) priv_len) + return(cc); + } + } + return(rem); +} diff --git a/kerberosIV/krb/save_credentials.c b/kerberosIV/krb/save_credentials.c new file mode 100644 index 00000000000..780f4fc3b8c --- /dev/null +++ b/kerberosIV/krb/save_credentials.c @@ -0,0 +1,67 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/save_credentials.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +/* + * This routine takes a ticket and associated info and calls + * tf_save_cred() to store them in the ticket cache. The peer + * routine for extracting a ticket and associated info from the + * ticket cache is krb_get_cred(). When changes are made to + * this routine, the corresponding changes should be made + * in krb_get_cred() as well. + * + * Returns KSUCCESS if all goes well, otherwise an error returned + * by the tf_init() or tf_save_cred() routines. + */ + +int +save_credentials(service, instance, realm, session, lifetime, kvno, + ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + unsigned char *session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + int32_t issue_date; /* The issue time */ +{ + int tf_status; /* return values of the tf_util calls */ + + /* Open and lock the ticket file for writing */ + if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS) + return(tf_status); + + /* Save credentials by appending to the ticket file */ + tf_status = tf_save_cred(service, instance, realm, session, + lifetime, kvno, ticket, issue_date); + (void) tf_close(); + return (tf_status); +} diff --git a/kerberosIV/krb/send_to_kdc.c b/kerberosIV/krb/send_to_kdc.c new file mode 100644 index 00000000000..a680819382c --- /dev/null +++ b/kerberosIV/krb/send_to_kdc.c @@ -0,0 +1,324 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/send_to_kdc.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include +#include +#include +#include + +#define S_AD_SZ sizeof(struct sockaddr_in) + +static int krb_udp_port = 0; + +/* CLIENT_KRB_TIMEOUT indicates the time to wait before + * retrying a server. It's defined in "krb.h". + */ +static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0}; +static char *prog = "send_to_kdc"; +static send_recv(KTEXT pkt, KTEXT rpkt, int f, struct sockaddr_in *_to, struct hostent *addrs); + +/* + * This file contains two routines, send_to_kdc() and send_recv(). + * send_recv() is a static routine used by send_to_kdc(). + */ + +/* + * send_to_kdc() sends a message to the Kerberos authentication + * server(s) in the given realm and returns the reply message. + * The "pkt" argument points to the message to be sent to Kerberos; + * the "rpkt" argument will be filled in with Kerberos' reply. + * The "realm" argument indicates the realm of the Kerberos server(s) + * to transact with. If the realm is null, the local realm is used. + * + * If more than one Kerberos server is known for a given realm, + * different servers will be queried until one of them replies. + * Several attempts (retries) are made for each server before + * giving up entirely. + * + * If an answer was received from a Kerberos host, KSUCCESS is + * returned. The following errors can be returned: + * + * SKDC_CANT - can't get local realm + * - can't find "kerberos" in /etc/services database + * - can't open socket + * - can't bind socket + * - all ports in use + * - couldn't find any Kerberos host + * + * SKDC_RETRY - couldn't get an answer from any Kerberos server, + * after several retries + */ + +int +send_to_kdc(pkt, rpkt, realm) + KTEXT pkt; + KTEXT rpkt; + char *realm; +{ + int i, f; + int no_host; /* was a kerberos host found? */ + int retry; + int n_hosts; + int retval; + struct sockaddr_in to; + struct hostent *host, *hostlist; + char *cp; + char krbhst[MAX_HSTNM]; + char lrealm[REALM_SZ]; + + /* + * If "realm" is non-null, use that, otherwise get the + * local realm. + */ + if (realm) + (void) strcpy(lrealm, realm); + else + if (krb_get_lrealm(lrealm,1)) { + if (krb_debug) + fprintf(stderr, "%s: can't get local realm\n", prog); + return(SKDC_CANT); + } + if (krb_debug) + printf("lrealm is %s\n", lrealm); + if (krb_udp_port == 0) { + register struct servent *sp; + if ((sp = getservbyname("kerberos","udp")) == 0) { + if (krb_debug) + fprintf(stderr, "%s: Can't get kerberos/udp service\n", + prog); + krb_udp_port = 750; /* Was return(SKDC_CANT); */ + } + else + krb_udp_port = sp->s_port; + if (krb_debug) + printf("krb_udp_port is %d\n", krb_udp_port); + } + bzero((char *)&to, S_AD_SZ); + hostlist = (struct hostent *) malloc(sizeof(struct hostent)); + if (!hostlist) + return (/*errno */SKDC_CANT); + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if (krb_debug) + fprintf(stderr,"%s: Can't open socket\n", prog); + return(SKDC_CANT); + } + /* from now on, exit through rtn label for cleanup */ + + no_host = 1; + /* get an initial allocation */ + n_hosts = 0; + bzero((char *)&hostlist[n_hosts], sizeof(struct hostent)); + for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { + if (krb_debug) { + printf("Getting host entry for %s...",krbhst); + (void) fflush(stdout); + } + host = gethostbyname(krbhst); + if (krb_debug) { + printf("%s.\n", + host ? "Got it" : "Didn't get it"); + (void) fflush(stdout); + } + if (!host) + continue; + no_host = 0; /* found at least one */ + n_hosts++; + /* preserve host network address to check later + * (would be better to preserve *all* addresses, + * take care of that later) + */ + hostlist = (struct hostent *) + realloc((char *)hostlist, + (unsigned) + sizeof(struct hostent)*(n_hosts+1)); + if (!hostlist) + return /*errno */SKDC_CANT; + bcopy((char *)host, (char *)&hostlist[n_hosts-1], + sizeof(struct hostent)); + host = &hostlist[n_hosts-1]; + cp = malloc((unsigned)host->h_length); + if (!cp) { + retval = /*errno */SKDC_CANT; + goto rtn; + } + bcopy((char *)host->h_addr, cp, host->h_length); +/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2 + (or worse) only return one name ... */ +#if defined(h_addr) + host->h_addr_list = (char **)malloc(2*sizeof(char *)); + if (!host->h_addr_list) { + retval = /*errno */SKDC_CANT; + goto rtn; + } + host->h_addr_list[1] = NULL; +#endif /* defined(h_addr) */ + host->h_addr = cp; + bzero((char *)&hostlist[n_hosts], + sizeof(struct hostent)); + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + to.sin_port = krb_udp_port; + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + if (krb_debug) { + printf("Timeout, error, or wrong descriptor\n"); + (void) fflush(stdout); + } + } + if (no_host) { + if (krb_debug) + fprintf(stderr, "%s: can't find any Kerberos host.\n", + prog); + retval = SKDC_CANT; + goto rtn; + } + /* retry each host in sequence */ + for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { + for (host = hostlist; host->h_name != (char *)NULL; host++) { + to.sin_family = host->h_addrtype; + bcopy(host->h_addr, (char *)&to.sin_addr, + host->h_length); + if (send_recv(pkt, rpkt, f, &to, hostlist)) { + retval = KSUCCESS; + goto rtn; + } + } + } + retval = SKDC_RETRY; +rtn: + (void) close(f); + if (hostlist) { + register struct hostent *hp; + for (hp = hostlist; hp->h_name; hp++) +#if defined(h_addr) + if (hp->h_addr_list) { +#endif /* defined(h_addr) */ + if (hp->h_addr) + free(hp->h_addr); +#if defined(h_addr) + free((char *)hp->h_addr_list); + } +#endif /* defined(h_addr) */ + free((char *)hostlist); + } + return(retval); +} + +/* + * try to send out and receive message. + * return 1 on success, 0 on failure + */ + +static int +send_recv(pkt, rpkt, f, _to, addrs) + KTEXT pkt; + KTEXT rpkt; + int f; + struct sockaddr_in *_to; + struct hostent *addrs; +{ + fd_set readfds; + register struct hostent *hp; + struct sockaddr_in from; + int sin_size; + int numsent; + + if (krb_debug) { + if (_to->sin_family == AF_INET) + printf("Sending message to %s...", + inet_ntoa(_to->sin_addr)); + else + printf("Sending message..."); + (void) fflush(stdout); + } + if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0, + (struct sockaddr *)_to, + S_AD_SZ)) != pkt->length) { + if (krb_debug) + printf("sent only %d/%d\n",numsent, pkt->length); + return 0; + } + if (krb_debug) { + printf("Sent\nWaiting for reply..."); + (void) fflush(stdout); + } + FD_ZERO(&readfds); + FD_SET(f, &readfds); + errno = 0; + /* select - either recv is ready, or timeout */ + /* see if timeout or error or wrong descriptor */ + if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1 + || !FD_ISSET(f, &readfds)) { + if (krb_debug) { + long rfds; + bcopy(&readfds, &rfds, sizeof(rfds)); + fprintf(stderr, "select failed: readfds=%lx", + rfds); + perror(""); + } + return 0; + } + sin_size = sizeof(from); + if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0, + (struct sockaddr *)&from, &sin_size) + < 0) { + if (krb_debug) + perror("recvfrom"); + return 0; + } + if (krb_debug) { + printf("received packet from %s\n", inet_ntoa(from.sin_addr)); + fflush(stdout); + } + for (hp = addrs; hp->h_name != (char *)NULL; hp++) { + if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr, + hp->h_length)) { + if (krb_debug) { + printf("Received it\n"); + (void) fflush(stdout); + } + return 1; + } + if (krb_debug) + fprintf(stderr, + "packet not from %lx\n", + (long)hp->h_addr); + } + if (krb_debug) + fprintf(stderr, "%s: received packet from wrong host! (%x)\n", + "send_to_kdc(send_rcv)", (int)from.sin_addr.s_addr); + return 0; +} diff --git a/kerberosIV/krb/sendauth.c b/kerberosIV/krb/sendauth.c new file mode 100644 index 00000000000..3aa157df14e --- /dev/null +++ b/kerberosIV/krb/sendauth.c @@ -0,0 +1,269 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/sendauth.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_recvauth.c + */ +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */ + + +/* + * This file contains two routines: krb_sendauth() and krb_sendsrv(). + * + * krb_sendauth() transmits a ticket over a file descriptor for a + * desired service, instance, and realm, doing mutual authentication + * with the server if desired. + * + * krb_sendsvc() sends a service name to a remote knetd server. + */ + +/* + * The first argument to krb_sendauth() contains a bitfield of + * options (the options are defined in "krb.h"): + * + * KOPT_DONT_CANON Don't canonicalize instance as a hostname. + * (If this option is not chosen, krb_get_phost() + * is called to canonicalize it.) + * + * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. + * A ticket must be supplied in the "ticket" + * argument. + * (If this option is not chosen, and there + * is no ticket for the given server in the + * ticket cache, one will be fetched using + * krb_mk_req() and returned in "ticket".) + * + * KOPT_DO_MUTUAL Do mutual authentication, requiring that the + * receiving server return the checksum+1 encrypted + * in the session key. The mutual authentication + * is done using krb_mk_priv() on the other side + * (see "recvauth.c") and krb_rd_priv() on this + * side. + * + * The "fd" argument is a file descriptor to write to the remote + * server on. The "ticket" argument is used to store the new ticket + * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is + * chosen, the ticket must be supplied in the "ticket" argument. + * The "service", "inst", and "realm" arguments identify the ticket. + * If "realm" is null, the local realm is used. + * + * The following arguments are only needed if the KOPT_DO_MUTUAL option + * is chosen: + * + * The "checksum" argument is a number that the server will add 1 to + * to authenticate itself back to the client; the "msg_data" argument + * holds the returned mutual-authentication message from the server + * (i.e., the checksum+1); the "cred" structure is used to hold the + * session key of the server, extracted from the ticket file, for use + * in decrypting the mutual authentication message from the server; + * and "schedule" holds the key schedule for that decryption. The + * the local and server addresses are given in "laddr" and "faddr". + * + * The application protocol version number (of up to KRB_SENDAUTH_VLEN + * characters) is passed in "version". + * + * If all goes well, KSUCCESS is returned, otherwise some error code. + * + * The format of the message sent to the server is: + * + * Size Variable Field + * ---- -------- ----- + * + * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol + * bytes version number + * + * KRB_SENDAUTH_VLEN version application protocol + * bytes version number + * + * 4 bytes ticket->length length of ticket + * + * ticket->length ticket->dat ticket itself + */ + +/* + * XXX: Note that krb_rd_priv() is coded in such a way that + * "msg_data->app_data" will be pointing into "priv_buf", which + * will disappear when krb_sendauth() returns. + */ + +int +krb_sendauth(options, fd, ticket, service, inst, realm, checksum, + msg_data, cred, schedule, laddr, faddr, version) + int32_t options; /* bit-pattern of options */ + int fd; /* file descriptor to write onto */ + KTEXT ticket; /* where to put ticket (return); or + * supplied in case of KOPT_DONT_MK_REQ */ + char *service; /* service name, instance, realm */ + char *inst; /* checksum to include in request */ + char *realm; /* mutual auth MSG_DAT (return) */ + u_int32_t checksum; /* credentials (return) */ + MSG_DAT *msg_data; /* key schedule (return) */ + CREDENTIALS *cred; /* local address */ + struct des_ks_struct *schedule; + struct sockaddr_in *faddr; /* address of foreign host on fd */ + struct sockaddr_in *laddr; + char *version; /* version string */ +{ + int rem, i, cc; + char srv_inst[INST_SZ]; + char krb_realm[REALM_SZ]; + char buf[BUFSIZ]; + u_int32_t tkt_len; + u_char priv_buf[1024]; + u_int32_t cksum; + + rem=KSUCCESS; + + /* get current realm if not passed in */ + if (!realm) { + rem = krb_get_lrealm(krb_realm,1); + if (rem != KSUCCESS) + return(rem); + realm = krb_realm; + } + + /* copy instance into local storage, canonicalizing if desired */ + if (options & KOPT_DONT_CANON) + (void) strncpy(srv_inst, inst, INST_SZ); + else + (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ); + + /* get the ticket if desired */ + if (!(options & KOPT_DONT_MK_REQ)) { + rem = krb_mk_req(ticket, service, srv_inst, realm, checksum); + if (rem != KSUCCESS) + return(rem); + } + +#ifdef ATHENA_COMPAT + /* this is only for compatibility with old servers */ + if (options & KOPT_DO_OLDSTYLE) { + (void) sprintf(buf,"%d ",ticket->length); + (void) write(fd, buf, strlen(buf)); + (void) write(fd, (char *) ticket->dat, ticket->length); + return(rem); + } +#endif /* ATHENA_COMPAT */ + /* if mutual auth, get credentials so we have service session + keys for decryption below */ + if (options & KOPT_DO_MUTUAL) + if ((cc = krb_get_cred(service, srv_inst, realm, cred))) + return(cc); + + /* zero the buffer */ + (void) bzero(buf, BUFSIZ); + + /* insert version strings */ + (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN); + (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN); + + /* increment past vers strings */ + i = 2*KRB_SENDAUTH_VLEN; + + /* put ticket length into buffer */ + tkt_len = htonl(ticket->length); + (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len)); + i += sizeof(tkt_len); + + /* put ticket into buffer */ + (void) bcopy((char *) ticket->dat, buf+i, ticket->length); + i += ticket->length; + + /* write the request to the server */ + if ((cc = krb_net_write(fd, buf, i)) != i) + return(cc); + + /* mutual authentication, if desired */ + if (options & KOPT_DO_MUTUAL) { + /* get the length of the reply */ + if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + tkt_len = ntohl(tkt_len); + + /* if the length is negative, the server failed to recognize us. */ + if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf))) + return(KFAILURE); /* XXX */ + /* read the reply... */ + if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len) + return(errno); + + /* ...and decrypt it */ +#ifndef NOENCRYPTION + des_key_sched(&cred->session,schedule); +#endif + if ((cc = krb_rd_priv(priv_buf, tkt_len, schedule, + &cred->session, faddr, laddr, msg_data))) + return(cc); + + /* fetch the (modified) checksum */ + (void) bcopy((char *)msg_data->app_data, (char *)&cksum, + sizeof(cksum)); + cksum = ntohl(cksum); + + /* if it doesn't match, fail */ + if (cksum != checksum + 1) + return(KFAILURE); /* XXX */ + } + return(KSUCCESS); +} + +#ifdef ATHENA_COMPAT +/* + * krb_sendsvc + */ + +int +krb_sendsvc(fd, service) + int fd; + char *service; +{ + /* write the service name length and then the service name to + the fd */ + u_int32_t serv_length; + int cc; + + serv_length = htonl(strlen(service)); + if ((cc = krb_net_write(fd, (char *) &serv_length, + sizeof(serv_length))) + != sizeof(serv_length)) + return(cc); + if ((cc = krb_net_write(fd, service, strlen(service))) + != strlen(service)) + return(cc); + return(KSUCCESS); +} +#endif /* ATHENA_COMPAT */ diff --git a/kerberosIV/krb/shlib_version b/kerberosIV/krb/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/krb/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/krb/str2key.c b/kerberosIV/krb/str2key.c new file mode 100644 index 00000000000..471bc5e4c23 --- /dev/null +++ b/kerberosIV/krb/str2key.c @@ -0,0 +1,129 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/str2key.c,v $ + * + * $Locker: $ + */ + +/* + * This defines the Andrew string_to_key function. It accepts a password + * string as input and converts its via a one-way encryption algorithm to a DES + * encryption key. It is compatible with the original Andrew authentication + * service password database. + */ + +#include "krb_locl.h" + +/* +EXPORT void afs_string_to_key(char *passwd, char *cell, des_cblock *key); +*/ + +static void +mklower(s) + char *s; +{ + for (; *s; s++) + if ('A' <= *s && *s <= 'Z') + *s = *s - 'A' + 'a'; +} + +/* + * Short passwords, i.e 8 characters or less. + */ +static void +afs_cmu_StringToKey (str, cell, key) + char *str; + char *cell; + des_cblock *key; +{ + char password[8+1]; /* crypt is limited to 8 chars anyway */ + int i; + int passlen; + + bzero (key, sizeof(key)); + bzero(password, sizeof(password)); + + strncpy (password, cell, 8); + passlen = strlen (str); + if (passlen > 8) passlen = 8; + + for (i=0; i sizeof(password)) passlen = sizeof(password); + + bcopy ("kerberos", &ivec, 8); + bcopy ("kerberos", &temp_key, 8); + des_fixup_key_parity (&temp_key); + des_key_sched (&temp_key, schedule); + des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec); + + bcopy (&ivec, &temp_key, 8); + des_fixup_key_parity (&temp_key); + des_key_sched (&temp_key, schedule); + des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec); + + des_fixup_key_parity (key); +} + +#undef REALM_SZ +#define REALM_SZ 41 + +void +afs_string_to_key(str, cell, key) + char *str; + char *cell; + des_cblock *key; +{ + char realm[REALM_SZ]; + (void)strcpy(realm, cell); + (void)mklower(realm); + + if (strlen(str) > 8) + afs_transarc_StringToKey (str, realm, key); + else + afs_cmu_StringToKey (str, realm, key); +} diff --git a/kerberosIV/krb/tf_util.3 b/kerberosIV/krb/tf_util.3 new file mode 100644 index 00000000000..0f19e5394ae --- /dev/null +++ b/kerberosIV/krb/tf_util.3 @@ -0,0 +1,152 @@ +.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/tf_util.3,v $ +.\" $Author: tholo $ +.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/tf_util.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.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 +.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 ): +.nf +.sp +.in +4 + char service[ANAME_SZ] + char instance[INST_SZ] + char realm[REALM_SZ] + des_cblock session + int lifetime + int kvno + KTEXT_ST ticket_st + long issue_date +.in -4 +.sp +.fi +.PP +.I tf_init +must be called before the other ticket file +routines. +It takes the name of the ticket file to use, +and a read/write flag as arguments. +It tries to open the ticket file, checks the mode and if +everything is okay, locks the file. If it's opened for +reading, the lock is shared. If it's opened for writing, +the lock is exclusive. +KSUCCESS is returned if all went well, otherwise one of the +following: +.nf +.sp +NO_TKT_FIL - file wasn't there +TKT_FIL_ACC - file was in wrong mode, etc. +TKT_FIL_LCK - couldn't lock the file, even after a retry +.sp +.fi +.PP +The +.I tf_get_pname +reads the principal's name from a ticket file. +It should only be called after tf_init has been called. The +principal's name is filled into the +.I pname +parameter. If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If the principal's name was null, or EOF was encountered, or the +name was longer than ANAME_SZ, TKT_FIL_FMT is returned. +.PP +The +.I tf_get_pinst +reads the principal's instance from a ticket file. +It should only be called after tf_init and tf_get_pname +have been called. +The principal's instance is filled into the +.I pinst +parameter. +If all goes +well, KSUCCESS is returned. +If tf_init wasn't called, TKT_FIL_INI +is returned. +If EOF was encountered, or the +name was longer than INST_SZ, TKT_FIL_FMT is returned. +Note that, unlike the principal name, the instance name may be null. +.PP +The +.I tf_get_cred +routine reads a CREDENTIALS record from a ticket file and +fills in the given structure. +It should only be called after +tf_init, tf_get_pname, and tf_get_pinst have been called. +If all goes well, KSUCCESS is returned. Possible error codes +are: +.nf +.sp +TKT_FIL_INI - tf_init wasn't called first +TKT_FIL_FMT - bad format +EOF - end of file encountered +.sp +.fi +.PP +.I tf_close +closes the ticket file and releases the lock on it. +.SH "SEE ALSO" +krb(3) +.SH DIAGNOSTICS +.SH BUGS +The ticket file routines have to be called in a certain order. +.SH AUTHORS +Jennifer Steiner, MIT Project Athena +.br +Bill Bryant, MIT Project Athena +.SH RESTRICTIONS +Copyright 1987 Massachusetts Institute of Technology diff --git a/kerberosIV/krb/tf_util.c b/kerberosIV/krb/tf_util.c new file mode 100644 index 00000000000..d1442428f43 --- /dev/null +++ b/kerberosIV/krb/tf_util.c @@ -0,0 +1,590 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/tf_util.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include +#include + +#ifdef TKT_SHMEM +#include +#include +#include +#endif /* TKT_SHMEM */ + +#define TOO_BIG -1 +#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before + * retry if ticket file is + * locked */ + +#ifdef TKT_SHMEM +static char *krb_shm_addr = 0; +static char *tmp_shm_addr = 0; +static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0}; +#endif /* TKT_SHMEM */ + +/* + * fd must be initialized to something that won't ever occur as a real + * file descriptor. Since open(2) returns only non-negative numbers as + * valid file descriptors, and tf_init always stuffs the return value + * from open in here even if it is an error flag, we must + * a. Initialize fd to a negative number, to indicate that it is + * not initially valid. + * b. When checking for a valid fd, assume that negative values + * are invalid (ie. when deciding whether tf_init has been + * called.) + * c. In tf_close, be sure it gets reinitialized to a negative + * number. + */ +static fd = -1; +static curpos; /* Position in tfbfr */ +static lastpos; /* End of tfbfr */ +static char tfbfr[BUFSIZ]; /* Buffer for ticket data */ + +static tf_gets(register char *s, int n), tf_read(register char *s, register int n); + +/* + * This file contains routines for manipulating the ticket cache file. + * + * The ticket file is in the following format: + * + * principal's name (null-terminated string) + * principal's instance (null-terminated string) + * CREDENTIAL_1 + * CREDENTIAL_2 + * ... + * CREDENTIAL_n + * EOF + * + * Where "CREDENTIAL_x" consists of the following fixed-length + * fields from the CREDENTIALS structure (see "krb.h"): + * + * char service[ANAME_SZ] + * char instance[INST_SZ] + * char realm[REALM_SZ] + * C_Block session + * int lifetime + * int kvno + * KTEXT_ST ticket_st + * u_int32_t issue_date + * + * Short description of routines: + * + * tf_init() opens the ticket file and locks it. + * + * tf_get_pname() returns the principal's name. + * + * tf_get_pinst() returns the principal's instance (may be null). + * + * tf_get_cred() returns the next CREDENTIALS record. + * + * tf_save_cred() appends a new CREDENTIAL record to the ticket file. + * + * tf_close() closes the ticket file and releases the lock. + * + * tf_gets() returns the next null-terminated string. It's an internal + * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred(). + * + * tf_read() reads a given number of bytes. It's an internal routine + * used by tf_get_cred(). + */ + +/* + * tf_init() should be called before the other ticket file routines. + * It takes the name of the ticket file to use, "tf_name", and a + * read/write flag "rw" as arguments. + * + * It tries to open the ticket file, checks the mode, and if everything + * is okay, locks the file. If it's opened for reading, the lock is + * shared. If it's opened for writing, the lock is exclusive. + * + * Returns KSUCCESS if all went well, otherwise one of the following: + * + * NO_TKT_FIL - file wasn't there + * TKT_FIL_ACC - file was in wrong mode, etc. + * TKT_FIL_LCK - couldn't lock the file, even after a retry + */ + +int +tf_init(tf_name, rw) + char *tf_name; + int rw; +{ + int wflag; + uid_t me, getuid(void); + struct stat stat_buf; +#ifdef TKT_SHMEM + char shmidname[MaxPathLen]; + FILE *sfp; + int shmid; +#endif + + switch (rw) { + case R_TKT_FIL: + wflag = 0; + break; + case W_TKT_FIL: + wflag = 1; + break; + default: + if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n"); + return TKT_FIL_ACC; + } + if (lstat(tf_name, &stat_buf) < 0) + switch (errno) { + case ENOENT: + return NO_TKT_FIL; + default: + return TKT_FIL_ACC; + } + me = getuid(); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#ifdef TKT_SHMEM + (void) strcpy(shmidname, tf_name); + (void) strcat(shmidname, ".shm"); + if (stat(shmidname,&stat_buf) < 0) + return(TKT_FIL_ACC); + if ((stat_buf.st_uid != me && me != 0) || + ((stat_buf.st_mode & S_IFMT) != S_IFREG)) + return TKT_FIL_ACC; +#endif /* TKT_SHMEM */ + + /* + * If "wflag" is set, open the ticket file in append-writeonly mode + * and lock the ticket file in exclusive mode. If unable to lock + * the file, sleep and try again. If we fail again, return with the + * proper error message. + */ + + curpos = sizeof(tfbfr); + +#ifdef TKT_SHMEM + sfp = fopen(shmidname, "r"); /* only need read/write on the + actual tickets */ + if (sfp == 0) + return TKT_FIL_ACC; + shmid = -1; + { + char buf[BUFSIZ]; + int val; /* useful for debugging fscanf */ + /* We provide our own buffer here since some STDIO libraries + barf on unbuffered input with fscanf() */ + + setbuf(sfp, buf); + if ((val = fscanf(sfp,"%d",&shmid)) != 1) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + if (shmid < 0) { + (void) fclose(sfp); + return TKT_FIL_ACC; + } + (void) fclose(sfp); + } + /* + * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and + * attach the same segment twice so we need this check. + */ + if (!krb_shm_addr) { + if ((krb_shm_addr = shmat(shmid,0,0)) == -1){ + if (krb_debug) + fprintf(stderr, + "cannot attach shared memory for segment %d\n", + shmid); + krb_shm_addr = 0; /* reset so we catch further errors */ + return TKT_FIL_ACC; + } + } + tmp_shm_addr = krb_shm_addr; +#endif /* TKT_SHMEM */ + + if (wflag) { + fd = open(tf_name, O_RDWR, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; + } + /* + * Otherwise "wflag" is not set and the ticket file should be opened + * for read-only operations and locked for shared access. + */ + + fd = open(tf_name, O_RDONLY, 0600); + if (fd < 0) { + return TKT_FIL_ACC; + } + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + sleep(TF_LCK_RETRY); + if (flock(fd, LOCK_SH | LOCK_NB) < 0) { + (void) close(fd); + fd = -1; + return TKT_FIL_LCK; + } + } + return KSUCCESS; +} + +/* + * tf_get_pname() reads the principal's name from the ticket file. It + * should only be called after tf_init() has been called. The + * principal's name is filled into the "p" parameter. If all goes well, + * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is + * returned. If the name was null, or EOF was encountered, or the name + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. + */ + +int +tf_get_pname(p) + char *p; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pname called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */ + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_pinst() reads the principal's instance from a ticket file. + * It should only be called after tf_init() and tf_get_pname() have been + * called. The instance is filled into the "inst" parameter. If all + * goes well, KSUCCESS is returned. If tf_init() wasn't called, + * TKT_FIL_INI is returned. If EOF was encountered, or the instance + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the + * instance may be null. + */ + +int +tf_get_pinst(inst) + char *inst; +{ + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_pinst called before tf_init.\n"); + return TKT_FIL_INI; + } + if (tf_gets(inst, INST_SZ) < 1) + return TKT_FIL_FMT; + return KSUCCESS; +} + +/* + * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills + * in the given structure "c". It should only be called after tf_init(), + * tf_get_pname(), and tf_get_pinst() have been called. If all goes well, + * KSUCCESS is returned. Possible error codes are: + * + * TKT_FIL_INI - tf_init wasn't called first + * TKT_FIL_FMT - bad format + * EOF - end of file encountered + */ + +int +tf_get_cred(c) + CREDENTIALS *c; +{ + KTEXT ticket = &c->ticket_st; /* pointer to ticket */ + int k_errno; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_get_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1) + switch (k_errno) { + case TOO_BIG: + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2) + switch (k_errno) { + case TOO_BIG: + case 1: /* can't be just a null */ + tf_close(); + return TKT_FIL_FMT; + case 0: + return EOF; + } + if ( + tf_read((char *) (c->session), DES_KEY_SZ) < 1 || + tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 || + tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 || + tf_read((char *) &(ticket->length), sizeof(ticket->length)) + < 1 || + /* don't try to read a silly amount into ticket->dat */ + ticket->length > MAX_KTXT_LEN || + tf_read((char *) (ticket->dat), ticket->length) < 1 || + tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1 + ) { + tf_close(); + return TKT_FIL_FMT; + } +#ifdef TKT_SHMEM + bcopy(tmp_shm_addr,c->session,KEY_SZ); + tmp_shm_addr += KEY_SZ; +#endif /* TKT_SHMEM */ + return KSUCCESS; +} + +/* + * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is + * not a valid file descriptor, it just returns. It also clears the + * buffer used to read tickets. + * + * The return value is not defined. + */ + +void +tf_close() +{ + if (!(fd < 0)) { +#ifdef TKT_SHMEM + if (shmdt(krb_shm_addr)) { + /* what kind of error? */ + if (krb_debug) + fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno); + } else { + krb_shm_addr = 0; + } +#endif /* TKT_SHMEM */ + (void) flock(fd, LOCK_UN); + (void) close(fd); + fd = -1; /* see declaration of fd above */ + } + bzero(tfbfr, sizeof(tfbfr)); +} + +/* + * tf_gets() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until either it has read "n" characters, + * or until it reads a null byte. When finished, what has been read exists + * in "s". If it encounters EOF or an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read (including null terminator) + * when all goes well + * + * 0 end of file or read error + * + * TOO_BIG if "count" characters are read and no null is + * encountered. This is an indication that the ticket + * file is seriously ill. + */ + +static int +tf_gets(s, n) + register char *s; + int n; +{ + register count; + + if (fd < 0) { + if (krb_debug) + fprintf(stderr, "tf_gets called before tf_init.\n"); + return TKT_FIL_INI; + } + for (count = n - 1; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s = tfbfr[curpos++]; + if (*s++ == '\0') + return (n - count); + } + tf_close(); + return TOO_BIG; +} + +/* + * tf_read() is an internal routine. It takes a string "s" and a count + * "n", and reads from the file until "n" bytes have been read. When + * finished, what has been read exists in "s". If it encounters EOF or + * an error, it closes the ticket file. + * + * Possible return values are: + * + * n the number of bytes read when all goes well + * + * 0 on end of file or read error + */ + +static int +tf_read(s, n) + register char *s; + register int n; +{ + register count; + + for (count = n; count > 0; --count) { + if (curpos >= sizeof(tfbfr)) { + lastpos = read(fd, tfbfr, sizeof(tfbfr)); + curpos = 0; + } + if (curpos == lastpos) { + tf_close(); + return 0; + } + *s++ = tfbfr[curpos++]; + } + return n; +} + +char *tkt_string(void); + +/* + * tf_save_cred() appends an incoming ticket to the end of the ticket + * file. You must call tf_init() before calling tf_save_cred(). + * + * The "service", "instance", and "realm" arguments specify the + * server's name; "session" contains the session key to be used with + * the ticket; "kvno" is the server key version number in which the + * ticket is encrypted, "ticket" contains the actual ticket, and + * "issue_date" is the time the ticket was requested (local host's time). + * + * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't + * called previously, and KFAILURE for anything else that went wrong. + */ + +int +tf_save_cred(service, instance, realm, session, + lifetime, kvno, ticket, issue_date) + char *service; /* Service name */ + char *instance; /* Instance */ + char *realm; /* Auth domain */ + unsigned char *session; /* Session key */ + int lifetime; /* Lifetime */ + int kvno; /* Key version number */ + KTEXT ticket; /* The ticket itself */ + u_int32_t issue_date; /* The issue time */ +{ + + off_t lseek(int, off_t, int); + int count; /* count for write */ +#ifdef TKT_SHMEM + int *skey_check; +#endif /* TKT_SHMEM */ + + if (fd < 0) { /* fd is ticket file as set by tf_init */ + if (krb_debug) + fprintf(stderr, "tf_save_cred called before tf_init.\n"); + return TKT_FIL_INI; + } + /* Find the end of the ticket file */ + (void) lseek(fd, 0L, 2); +#ifdef TKT_SHMEM + /* scan to end of existing keys: pick first 'empty' slot. + we assume that no real keys will be completely zero (it's a weak + key under DES) */ + + skey_check = (int *) krb_shm_addr; + + while (*skey_check && *(skey_check+1)) + skey_check += 2; + tmp_shm_addr = (char *)skey_check; +#endif /* TKT_SHMEM */ + + /* Write the ticket and associated data */ + /* Service */ + count = strlen(service) + 1; + if (write(fd, service, count) != count) + goto bad; + /* Instance */ + count = strlen(instance) + 1; + if (write(fd, instance, count) != count) + goto bad; + /* Realm */ + count = strlen(realm) + 1; + if (write(fd, realm, count) != count) + goto bad; + /* Session key */ +#ifdef TKT_SHMEM + bcopy(session,tmp_shm_addr,8); + tmp_shm_addr+=8; + if (write(fd,krb_dummy_skey,8) != 8) + goto bad; +#else /* ! TKT_SHMEM */ + if (write(fd, (char *) session, 8) != 8) + goto bad; +#endif /* TKT_SHMEM */ + /* Lifetime */ + if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int)) + goto bad; + /* Key vno */ + if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int)) + goto bad; + /* Tkt length */ + if (write(fd, (char *) &(ticket->length), sizeof(int)) != + sizeof(int)) + goto bad; + /* Ticket */ + count = ticket->length; + if (write(fd, (char *) (ticket->dat), count) != count) + goto bad; + /* Issue date */ + if (write(fd, (char *) &issue_date, sizeof(issue_date)) + != sizeof(issue_date)) + goto bad; + + /* Actually, we should check each write for success */ + return (KSUCCESS); +bad: + return (KFAILURE); +} diff --git a/kerberosIV/krb/tkt_string.c b/kerberosIV/krb/tkt_string.c new file mode 100644 index 00000000000..74e50cfa192 --- /dev/null +++ b/kerberosIV/krb/tkt_string.c @@ -0,0 +1,91 @@ +/* + * This software may now be redistributed outside the US. + * + * $Source: /home/cvs/src/kerberosIV/krb/Attic/tkt_string.c,v $ + * + * $Locker: $ + */ + +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +#include +#include + +/* + * This routine is used to generate the name of the file that holds + * the user's cache of server tickets and associated session keys. + * + * If it is set, krb_ticket_string contains the ticket file name. + * Otherwise, the filename is constructed as follows: + * + * If it is set, the environment variable "KRBTKFILE" will be used as + * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and + * the user's uid are concatenated to produce the ticket file name + * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket + * file name is returned. + */ + +static char krb_ticket_string[MAXPATHLEN] = ""; + +char * +tkt_string() +{ + char *env; + uid_t getuid(void); + + if (!*krb_ticket_string) { + if ((env = getenv("KRBTKFILE"))) { + (void) strncpy(krb_ticket_string, env, + sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + } else { + /* 32 bits of signed integer will always fit in 11 characters + (including the sign), so no need to worry about overflow */ + (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,(int)getuid()); + } + } + return krb_ticket_string; +} + +/* + * This routine is used to set the name of the file that holds the user's + * cache of server tickets and associated session keys. + * + * The value passed in is copied into local storage. + * + * NOTE: This routine should be called during initialization, before other + * Kerberos routines are called; otherwise tkt_string() above may be called + * and return an undesired ticket file name until this routine is called. + */ + +void +krb_set_tkt_string(val) + char *val; +{ + + (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1); + krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0'; + + return; +} diff --git a/kerberosIV/ksrvtgt/Makefile b/kerberosIV/ksrvtgt/Makefile new file mode 100644 index 00000000000..82979931cdb --- /dev/null +++ b/kerberosIV/ksrvtgt/Makefile @@ -0,0 +1,10 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $ + +PROG= ksrvtgt +CFLAGS+=-DKERBEROS +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkrb -ldes +BINDIR= /usr/bin + +.include diff --git a/kerberosIV/ksrvtgt/ksrvtgt.1 b/kerberosIV/ksrvtgt/ksrvtgt.1 new file mode 100644 index 00000000000..89c8cf07e47 --- /dev/null +++ b/kerberosIV/ksrvtgt/ksrvtgt.1 @@ -0,0 +1,50 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: ksrvtgt.1,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $ +.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/kerberosIV/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/kerberosIV/krb.conf +to get the name of the local realm. +.TP +/tmp/tkt[uid] +The default ticket file. +.TP +/etc/kerberosIV/srvtab +The default service key file. +.SH SEE ALSO +kerberos(1), kinit(1), kdestroy(1) diff --git a/kerberosIV/ksrvtgt/ksrvtgt.c b/kerberosIV/ksrvtgt/ksrvtgt.c new file mode 100644 index 00000000000..f552fd38cae --- /dev/null +++ b/kerberosIV/ksrvtgt/ksrvtgt.c @@ -0,0 +1,59 @@ +/* $Id: ksrvtgt.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $ */ + +/*- + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Get a ticket-granting-ticket given a service key file (srvtab) + * The lifetime is the shortest allowed [1 five-minute interval] + */ + +#include +#include +#include +#include +#include + +const char rcsid[] = + "$Id: ksrvtgt.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $"; + +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, 1) != KSUCCESS) + exit(1); + + 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/kerberosIV/ksrvutil/Makefile b/kerberosIV/ksrvutil/Makefile new file mode 100644 index 00000000000..4d3510203fe --- /dev/null +++ b/kerberosIV/ksrvutil/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ + +PROG= ksrvutil +.if exists(${.CURDIR}/../kadm/obj) +CFLAGS+=-I${.CURDIR}/../kadm/obj +.else +CFLAGS+=-I${.CURDIR}/../kadm +.endif +.if exists(${.CURDIR}/../krb/obj) +CFLAGS+=-I${.CURDIR}/../krb/obj +.else +CFLAGS+=-I${.CURDIR}/../krb +.endif +.if exists(${.CURDIR}/../ss/obj) +CFLAGS+=-I${.CURDIR}/../ss/obj +.else +CFLAGS+=-I${.CURDIR}/../ss +.endif +LDADD+= -lkadm -lkrb -ldes -lcom_err +DPADD+= ${LIBKADM} ${LIBKRB} ${LIBDES} ${LIBCOM_ERR} +MAN= ksrvutil.8 + +.include diff --git a/kerberosIV/ksrvutil/ksrvutil.8 b/kerberosIV/ksrvutil/ksrvutil.8 new file mode 100644 index 00000000000..5bc22dfd445 --- /dev/null +++ b/kerberosIV/ksrvutil/ksrvutil.8 @@ -0,0 +1,92 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: ksrvutil.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ +.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/kerberosIV/ksrvutil/ksrvutil.c b/kerberosIV/ksrvutil/ksrvutil.c new file mode 100644 index 00000000000..96dfb4174e0 --- /dev/null +++ b/kerberosIV/ksrvutil/ksrvutil.c @@ -0,0 +1,624 @@ +/* $Id: ksrvutil.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ */ + +/*- + * 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. + */ + +/* + * list and update contents of srvtab files + */ + +/* + * ksrvutil + * list and update the contents of srvtab files + */ + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#include +#include + +#ifdef NOENCRYPTION +#define read_long_pw_string placebo_read_pw_string +#else /* NOENCRYPTION */ +#define read_long_pw_string des_read_pw_string +#endif /* NOENCRYPTION */ + +#define SRVTAB_MODE 0600 /* rw------- */ +#define PAD " " +#define VNO_HEADER "Version" +#define VNO_FORMAT "%4d " +#define KEY_HEADER " Key " /* 17 characters long */ +#define PRINC_HEADER " Principal\n" +#define PRINC_FORMAT "%s" + +static unsigned short +get_mode(char *filename) +{ + struct stat statbuf; + unsigned short mode; + + (void) bzero((char *)&statbuf, sizeof(statbuf)); + + if (stat(filename, &statbuf) < 0) + mode = SRVTAB_MODE; + else + mode = statbuf.st_mode; + + return(mode); +} + +static void +copy_keyfile(char *progname, char *keyfile, char *backup_keyfile) +{ + int keyfile_fd; + int backup_keyfile_fd; + int keyfile_mode; + char buf[BUFSIZ]; /* for copying keyfiles */ + int rcount; /* for copying keyfiles */ + int try_again; + + (void) bzero((char *)buf, sizeof(buf)); + + do { + try_again = FALSE; + if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) { + if (errno != ENOENT) { + (void)fprintf(stderr, "%s: Unable to read %s: %s\n", progname, + keyfile, strerror(errno)); + exit(1); + } + else { + try_again = TRUE; + if ((keyfile_fd = + open(keyfile, + O_WRONLY | O_TRUNC | O_CREAT, SRVTAB_MODE)) < 0) { + (void) fprintf(stderr, "%s: Unable to create %s: %s\n", + progname, keyfile, strerror(errno)); + exit(1); + } + else + if (close(keyfile_fd) < 0) { + (void) fprintf(stderr, "%s: Failure closing %s: %s\n", + progname, keyfile, strerror(errno)); + exit(1); + } + } + } + } while(try_again); + + keyfile_mode = get_mode(keyfile); + + if ((backup_keyfile_fd = + open(backup_keyfile, O_WRONLY | O_TRUNC | O_CREAT, + keyfile_mode)) < 0) { + (void) fprintf(stderr, "%s: Unable to write %s: %s\n", progname, + backup_keyfile, strerror(errno)); + exit(1); + } + do { + if ((rcount = read(keyfile_fd, (char *)buf, sizeof(buf))) < 0) { + (void) fprintf(stderr, "%s: Error reading %s: %s\n", progname, + keyfile, strerror(errno)); + exit(1); + } + if (rcount && (write(backup_keyfile_fd, buf, rcount) != rcount)) { + (void) fprintf(stderr, "%s: Error writing %s: %s\n", progname, + backup_keyfile, strerror(errno)); + exit(1); + } + } while (rcount); + if (close(backup_keyfile_fd) < 0) { + (void) fprintf(stderr, "%s: Error closing %s: %s\n", progname, + backup_keyfile, strerror(errno)); + exit(1); + } + if (close(keyfile_fd) < 0) { + (void) fprintf(stderr, "%s: Error closing %s: %s\n", progname, + keyfile, strerror(errno)); + exit(1); + } +} + +static void +leave(char *str, int x) +{ + if (str) + (void) fprintf(stderr, "%s\n", str); + (void) dest_tkt(); + exit(x); +} + +static void +safe_read_stdin(char *prompt, char *buf, int size) +{ + (void) printf(prompt); + (void) fflush(stdout); + (void) bzero(buf, size); + if (read(0, buf, size - 1) < 0) { + (void) fprintf(stderr, "Failure reading from stdin: %s\n", + strerror(errno)); + leave((char *)NULL, 1); + } + fflush(stdin); + buf[strlen(buf)-1] = 0; +} + + +static void +safe_write(char *progname, char *filename, int fd, char *buf, int len) +{ + if (write(fd, buf, len) != len) { + (void) fprintf(stderr, "%s: Failure writing to %s: %s\n", progname, + filename, strerror(errno)); + (void) close(fd); + leave("In progress srvtab in this file.", 1); + } +} + +static int +yn(char *string) +{ + char ynbuf[5]; + + (void) printf("%s (y,n) [y] ", string); + for (;;) { + safe_read_stdin("", ynbuf, sizeof(ynbuf)); + + if ((ynbuf[0] == 'n') || (ynbuf[0] == 'N')) + return(0); + else if ((ynbuf[0] == 'y') || (ynbuf[0] == 'Y') || (ynbuf[0] == 0)) + return(1); + else { + (void) printf("Please enter 'y' or 'n': "); + fflush(stdout); + } + } +} + +static void +append_srvtab(char *progname, char *filename, int fd, char *sname, char *sinst, char *srealm, unsigned char key_vno, unsigned char *key) +{ + /* Add one to append null */ + safe_write(progname, filename, fd, sname, strlen(sname) + 1); + safe_write(progname, filename, fd, sinst, strlen(sinst) + 1); + safe_write(progname, filename, fd, srealm, strlen(srealm) + 1); + safe_write(progname, filename, fd, (char *)&key_vno, 1); + safe_write(progname, filename, fd, (char *)key, sizeof(des_cblock)); + (void) fsync(fd); +} + +static void +print_key(unsigned char *key) +{ + int i; + + for (i = 0; i < 4; i++) + (void) printf("%02x", key[i]); + (void) printf(" "); + for (i = 4; i < 8; i++) + (void) printf("%02x", key[i]); +} + +static void +print_name(char *name, char *inst, char *realm) +{ + (void) printf("%s%s%s%s%s", name, inst[0] ? "." : "", inst, + realm[0] ? "@" : "", realm); +} + +static int +get_svc_new_key(unsigned char *new_key, char *sname, char *sinst, char *srealm, char *keyfile) +{ + int status = KADM_SUCCESS; + + if (((status = krb_get_svc_in_tkt(sname, sinst, srealm, PWSERV_NAME, + KADM_SINST, 1, keyfile)) == KSUCCESS) && + ((status = kadm_init_link("changepw", KRB_MASTER, srealm)) == + KADM_SUCCESS)) { +#ifdef NOENCRYPTION + (void) bzero((char *) new_key, sizeof(des_cblock)); + new_key[0] = (unsigned char) 1; +#else /* NOENCRYPTION */ + (void) des_new_random_key((des_cblock*)&new_key); +#endif /* NOENCRYPTION */ + return(KADM_SUCCESS); + } + + return(status); +} + +static void +get_key_from_password(des_cblock (*key)) +{ + char password[MAX_KPW_LEN]; /* storage for the password */ + + if (read_long_pw_string(password, sizeof(password)-1, "Password: ", 1)) + leave("Error reading password.", 1); + +#ifdef NOENCRYPTION + (void) bzero((char *) key, sizeof(des_cblock)); + key[0] = (unsigned char) 1; +#else /* NOENCRYPTION */ + (void) des_string_to_key(password, key); +#endif /* NOENCRYPTION */ + (void) bzero((char *)password, sizeof(password)); +} + +static void +usage(void) +{ + (void) fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] "); + (void) fprintf(stderr, "{list | change | add | get}\n"); + (void) fprintf(stderr, " -i causes the program to ask for "); + (void) fprintf(stderr, "confirmation before changing keys.\n"); + (void) fprintf(stderr, " -k causes the key to printed for list or "); + (void) fprintf(stderr, "change.\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + char sname[ANAME_SZ]; /* name of service */ + char sinst[INST_SZ]; /* instance of service */ + char srealm[REALM_SZ]; /* realm of service */ + unsigned char key_vno; /* key version number */ + int status; /* general purpose error status */ + des_cblock new_key; + des_cblock old_key; + char change_tkt[MAXPATHLEN]; /* Ticket to use for key change */ + char keyfile[MAXPATHLEN]; /* Original keyfile */ + char work_keyfile[MAXPATHLEN]; /* Working copy of keyfile */ + char backup_keyfile[MAXPATHLEN]; /* Backup copy of keyfile */ + unsigned short keyfile_mode; /* Protections on keyfile */ + int work_keyfile_fd = -1; /* Initialize so that */ + int backup_keyfile_fd = -1; /* compiler doesn't complain */ + char local_realm[REALM_SZ]; /* local kerberos realm */ + int i; + int interactive = FALSE; + int list = FALSE; + int change = FALSE; + int add = FALSE; + int get = FALSE; + int key = FALSE; /* do we show keys? */ + int arg_entered = FALSE; + int change_this_key = FALSE; + char databuf[BUFSIZ]; + int first_printed = FALSE; /* have we printed the first item? */ + + (void) bzero((char *)sname, sizeof(sname)); + (void) bzero((char *)sinst, sizeof(sinst)); + (void) bzero((char *)srealm, sizeof(srealm)); + + (void) bzero((char *)change_tkt, sizeof(change_tkt)); + (void) bzero((char *)keyfile, sizeof(keyfile)); + (void) bzero((char *)work_keyfile, sizeof(work_keyfile)); + (void) bzero((char *)backup_keyfile, sizeof(backup_keyfile)); + (void) bzero((char *)local_realm, sizeof(local_realm)); + + (void) sprintf(change_tkt, "/tmp/tkt_ksrvutil.%d", (int)getpid()); + krb_set_tkt_string(change_tkt); + + /* This is used only as a default for adding keys */ + if (krb_get_lrealm(local_realm, 1) != KSUCCESS) + (void) strcpy(local_realm, KRB_REALM); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-i") == 0) + interactive++; + else if (strcmp(argv[i], "-k") == 0) + key++; + else if (strcmp(argv[i], "list") == 0) { + if (arg_entered) + usage(); + else { + arg_entered++; + list++; + } + } + else if (strcmp(argv[i], "change") == 0) { + if (arg_entered) + usage(); + else { + arg_entered++; + change++; + } + } + else if (strcmp(argv[i], "add") == 0) { + if (arg_entered) + usage(); + else { + arg_entered++; + add++; + } + } + else if (strcmp(argv[i], "get") == 0) { + if (arg_entered) + usage(); + else { + arg_entered++; + get++; + } + } + else if (strcmp(argv[i], "-f") == 0) { + if (++i == argc) + usage(); + else + (void) strcpy(keyfile, argv[i]); + } + else + usage(); + } + + if (!arg_entered) + usage(); + + if (!keyfile[0]) + (void) strcpy(keyfile, KEYFILE); + + (void) strcpy(work_keyfile, keyfile); + (void) strcpy(backup_keyfile, keyfile); + + if (change || add || get) { + (void) strcat(work_keyfile, ".work"); + (void) strcat(backup_keyfile, ".old"); + + copy_keyfile(argv[0], keyfile, backup_keyfile); + } + + if (add || get) + copy_keyfile(argv[0], backup_keyfile, work_keyfile); + + keyfile_mode = get_mode(keyfile); + + if (change || list) { + if ((backup_keyfile_fd = open(backup_keyfile, O_RDONLY, 0)) < 0) { + (void) fprintf(stderr, "%s: Unable to read %s: %s\n", argv[0], + backup_keyfile, strerror(errno)); + exit(1); + } + } + + if (change) { + if ((work_keyfile_fd = + open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC, + SRVTAB_MODE)) < 0) { + (void) fprintf(stderr, "%s: Unable to write %s: %s\n", argv[0], + work_keyfile, strerror(errno)); + exit(1); + } + } + else if (add || get) { + if ((work_keyfile_fd = + open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0) { + (void) fprintf(stderr, "%s: Unable to open %s for append: %s\n", + argv[0], work_keyfile, strerror(errno)); + exit(1); + } + } + + if (change || list) { + while ((getst(backup_keyfile_fd, sname, SNAME_SZ) > 0) && + (getst(backup_keyfile_fd, sinst, INST_SZ) > 0) && + (getst(backup_keyfile_fd, srealm, REALM_SZ) > 0) && + (read(backup_keyfile_fd, &key_vno, 1) > 0) && + (read(backup_keyfile_fd,(char *)old_key,sizeof(old_key)) > 0)) { + if (list) { + if (!first_printed) { + (void) printf(VNO_HEADER); + (void) printf(PAD); + if (key) { + (void) printf(KEY_HEADER); + (void) printf(PAD); + } + (void) printf(PRINC_HEADER); + first_printed = 1; + } + (void) printf(VNO_FORMAT, key_vno); + (void) printf(PAD); + if (key) { + print_key(old_key); + (void) printf(PAD); + } + print_name(sname, sinst, srealm); + (void) printf("\n"); + } + else if (change) { + (void) printf("\nPrincipal: "); + print_name(sname, sinst, srealm); + (void) printf("; version %d\n", key_vno); + if (interactive) + change_this_key = yn("Change this key?"); + else if (change) + change_this_key = 1; + else + change_this_key = 0; + + if (change_this_key) + (void) printf("Changing to version %d.\n", key_vno + 1); + else if (change) + (void) printf("Not changing this key.\n"); + + if (change_this_key) { + /* Initialize non shared random sequence old key. */ + des_init_random_number_generator(&old_key); + + /* + * Pick a new key and determine whether or not + * it is safe to change + */ + if ((status = + get_svc_new_key(new_key, sname, sinst, + srealm, keyfile)) == KADM_SUCCESS) + key_vno++; + else { + (void) bcopy(old_key, new_key, sizeof(new_key)); + (void) fprintf(stderr, "%s: Key NOT changed: %s\n", + argv[0], krb_err_txt[status]); + change_this_key = FALSE; + } + } + else + (void) bcopy(old_key, new_key, sizeof(new_key)); + append_srvtab(argv[0], work_keyfile, work_keyfile_fd, + sname, sinst, srealm, key_vno, new_key); + if (key && change_this_key) { + (void) printf("Old key: "); + print_key(old_key); + (void) printf("; new key: "); + print_key(new_key); + (void) printf("\n"); + } + if (change_this_key) { + if ((status = kadm_change_pw(new_key)) == KADM_SUCCESS) { + (void) printf("Key changed.\n"); + (void) dest_tkt(); + } + else { + com_err(argv[0], status, + " attempting to change password."); + (void) dest_tkt(); + /* XXX This knows the format of a keyfile */ + if (lseek(work_keyfile_fd, -9, SEEK_CUR) >= 0) { + key_vno--; + safe_write(argv[0], work_keyfile, + work_keyfile_fd, (char *)&key_vno, 1); + safe_write(argv[0], work_keyfile, work_keyfile_fd, + (char *)old_key, sizeof(des_cblock)); + (void) fsync(work_keyfile_fd); + (void) fprintf(stderr,"Key NOT changed.\n"); + } + else { + (void)fprintf(stderr, + "%s: Unable to revert keyfile: %s\n", + argv[0], strerror(errno)); + leave("", 1); + } + } + } + } + bzero((char *)old_key, sizeof(des_cblock)); + bzero((char *)new_key, sizeof(des_cblock)); + } + } + else if (add) { + do { + do { + safe_read_stdin("Name: ", databuf, sizeof(databuf)); + (void) strncpy(sname, databuf, sizeof(sname) - 1); + safe_read_stdin("Instance: ", databuf, sizeof(databuf)); + (void) strncpy(sinst, databuf, sizeof(sinst) - 1); + safe_read_stdin("Realm: ", databuf, sizeof(databuf)); + (void) strncpy(srealm, databuf, sizeof(srealm) - 1); + safe_read_stdin("Version number: ", databuf, sizeof(databuf)); + key_vno = atoi(databuf); + if (!srealm[0]) + (void) strcpy(srealm, local_realm); + (void) printf("New principal: "); + print_name(sname, sinst, srealm); + (void) printf("; version %d\n", key_vno); + } while (!yn("Is this correct?")); + get_key_from_password(&new_key); + if (key) { + (void) printf("Key: "); + print_key(new_key); + (void) printf("\n"); + } + append_srvtab(argv[0], work_keyfile, work_keyfile_fd, + sname, sinst, srealm, key_vno, new_key); + (void) printf("Key successfully added.\n"); + } while (yn("Would you like to add another key?")); + } + else if (get) { + ksrvutil_get(); + } + + if (change || list) + if (close(backup_keyfile_fd) < 0) { + (void) fprintf(stderr, "%s: Failure closing %s: %s\n", + argv[0], backup_keyfile, strerror(errno)); + (void) fprintf(stderr, "continuing...\n"); + } + + if (change || add || get) { + if (close(work_keyfile_fd) < 0) { + (void) fprintf(stderr, "%s: Failure closing %s: %s\n", + argv[0], work_keyfile, strerror(errno)); + exit(1); + } + if (rename(work_keyfile, keyfile) < 0) { + (void) fprintf(stderr, "%s: Failure renaming %s to %s: %s\n", + argv[0], work_keyfile, keyfile, + strerror(errno)); + exit(1); + } + (void) chmod(backup_keyfile, keyfile_mode); + (void) chmod(keyfile, keyfile_mode); + (void) printf("Old keyfile in %s.\n", backup_keyfile); + } + + exit(0); +} + +ksrvutil_get() +{ + char sname[ANAME_SZ]; /* name of service */ + char sinst[INST_SZ]; /* instance of service */ + char srealm[REALM_SZ]; /* realm of service */ + char databuf[BUFSIZ]; + char local_realm[REALM_SZ]; /* local kerberos realm */ + char local_hostname[100]; + + if (krb_get_lrealm(local_realm, 1) != KSUCCESS) + strcpy(local_realm, KRB_REALM); + gethostname(local_hostname, sizeof(local_hostname)); + strcpy(local_hostname, krb_get_phost(local_hostname)); + do { + do { + safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf)); + if (databuf[0]) + strncpy(sname, databuf, sizeof(sname) - 1); + else + strcpy(sname, "rcmd"); + + safe_read_stdin("Instance [hostname]: ", databuf, sizeof(databuf)); + if (databuf[0]) + strncpy(sinst, databuf, sizeof(sinst) - 1); + else + strcpy(sinst, local_hostname); + + safe_read_stdin("Realm [localrealm]: ", databuf, sizeof(databuf)); + if (databuf[0]) + strncpy(srealm, databuf, sizeof(srealm) - 1); + else + strcpy(srealm, local_realm); + + printf("New principal: "); + print_name(sname, sinst, srealm); + } while (!yn("Is this correct?")); + printf("NOT adding anything!!! Key successfully added.\n"); + } while (yn("Would you like to add another key?")); +} diff --git a/kerberosIV/kstash/Makefile b/kerberosIV/kstash/Makefile new file mode 100644 index 00000000000..6d26029de4d --- /dev/null +++ b/kerberosIV/kstash/Makefile @@ -0,0 +1,9 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ + +PROG= kstash +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= kstash.8 + +.include diff --git a/kerberosIV/kstash/kstash.8 b/kerberosIV/kstash/kstash.8 new file mode 100644 index 00000000000..60a46fec2ce --- /dev/null +++ b/kerberosIV/kstash/kstash.8 @@ -0,0 +1,40 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kstash.8,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ +.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/kerberosIV/kstash/kstash.c b/kerberosIV/kstash/kstash.c new file mode 100644 index 00000000000..c9c2df9d880 --- /dev/null +++ b/kerberosIV/kstash/kstash.c @@ -0,0 +1,73 @@ +/* $Id: kstash.c,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include + +/* change this later, but krblib_dbm needs it for now */ +char *progname; + +static des_cblock master_key; +static des_key_schedule master_key_schedule; +static int kfile; + +static void +clear_secrets(void) +{ + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(master_key, sizeof(master_key)); +} + +int +main(int argc, char **argv) +{ + long n; + if ((n = kerb_init())) { + fprintf(stderr, "Kerberos db and cache init failed = %ld\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(); + exit(0); +} diff --git a/kerberosIV/make_keypair/Makefile b/kerberosIV/make_keypair/Makefile new file mode 100644 index 00000000000..a6de8e3def1 --- /dev/null +++ b/kerberosIV/make_keypair/Makefile @@ -0,0 +1,10 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ + +PROG= make_keypair +MAN= make_keypair.8 +CFLAGS+=-DKERBEROS -I${.CURDIR}/../register +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes + +.include diff --git a/kerberosIV/make_keypair/make_keypair.8 b/kerberosIV/make_keypair/make_keypair.8 new file mode 100644 index 00000000000..6b394174db6 --- /dev/null +++ b/kerberosIV/make_keypair/make_keypair.8 @@ -0,0 +1,88 @@ +.\" 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. +.\" +.\" from @(#)make_keypair.8 8.2 (Berkeley) 12/11/93 +.\" $Id: make_keypair.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ +.\" +.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/kerberosIV/make_keypair/make_keypair.c b/kerberosIV/make_keypair/make_keypair.c new file mode 100644 index 00000000000..d2dc1242eb7 --- /dev/null +++ b/kerberosIV/make_keypair/make_keypair.c @@ -0,0 +1,132 @@ +/* $Id: make_keypair.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $ */ + +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pathnames.h" +#include "register_proto.h" + +extern void herror(); +void make_key(), usage(); + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + char *addr; + int i; + struct sockaddr_in sin; + + 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/kerberosIV/man/Makefile b/kerberosIV/man/Makefile new file mode 100644 index 00000000000..57197dc7179 --- /dev/null +++ b/kerberosIV/man/Makefile @@ -0,0 +1,6 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ + +MAN= kerberos.1 krb.conf.5 krb.equiv.5 krb.realms.5 + +.include diff --git a/kerberosIV/man/kerberos.1 b/kerberosIV/man/kerberos.1 new file mode 100644 index 00000000000..55be3878e12 --- /dev/null +++ b/kerberosIV/man/kerberos.1 @@ -0,0 +1,258 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: kerberos.1,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ +.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/kerberosIV/man/krb.conf.5 b/kerberosIV/man/krb.conf.5 new file mode 100644 index 00000000000..97a53652159 --- /dev/null +++ b/kerberosIV/man/krb.conf.5 @@ -0,0 +1,31 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: krb.conf.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ +.TH KRB.CONF 5 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +/etc/kerberosIV/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/kerberosIV/man/krb.equiv.5 b/kerberosIV/man/krb.equiv.5 new file mode 100644 index 00000000000..edc438b1409 --- /dev/null +++ b/kerberosIV/man/krb.equiv.5 @@ -0,0 +1,25 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: krb.equiv.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ +.TH KRB.EQUIV 5 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +/etc/kerberosIV/krb.equiv \- Kerberos equivalent hosts file +.SH DESCRIPTION +.I krb.equiv +contains a list of IP address pairs that is to be considered being +the same host for Kerberos purposes. +.PP +.I krb.equiv +contains one pair of IP addresses per line. +For example: +.nf +.in +1i +130.237.223.3 192.16.126.3 # alv alv1 +130.237.223.4 192.16.126.4 # byse byse1 +130.237.228.152 192.16.126.9 # topsy topsy1 +.in -1i +.SH SEE ALSO +krb.conf(5), krb.realms(5), krb_equiv(3) diff --git a/kerberosIV/man/krb.realms.5 b/kerberosIV/man/krb.realms.5 new file mode 100644 index 00000000000..ebd7966c115 --- /dev/null +++ b/kerberosIV/man/krb.realms.5 @@ -0,0 +1,38 @@ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file . +.\" +.\" $Id: krb.realms.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ +.TH KRB.REALMS 5 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +/etc/kerberosIV/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/kerberosIV/mk_cmds/Makefile b/kerberosIV/mk_cmds/Makefile new file mode 100644 index 00000000000..bce94a0bcaa --- /dev/null +++ b/kerberosIV/mk_cmds/Makefile @@ -0,0 +1,16 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ + +PROG= mk_cmds +SRCS= mk_cmds.c options.c utils.c ct.c cmd_tbl.c +CFLAGS+=-I. -I${.CURDIR}/../ss +LFLAGS= -l +LDADD+= -ll +DPADD+= ${LIBL} +CLEANFILES+= y.tab.c y.tab.h lex.yy.c cmd_tbl.c ct.c +BINDIR= /usr/bin +NOMAN= noman + +# don't install -- only needed during build of kerberos (so far) +install: + +.include diff --git a/kerberosIV/mk_cmds/cmd_tbl.l b/kerberosIV/mk_cmds/cmd_tbl.l new file mode 100644 index 00000000000..1880864c031 --- /dev/null +++ b/kerberosIV/mk_cmds/cmd_tbl.l @@ -0,0 +1,112 @@ +%{ +/* $Id: cmd_tbl.l,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ +%} + +N [0-9] +PC [^\"] +AN [A-Z_a-z0-9] + +%{ +unsigned lineno = 1; + +static l_command_table(), l_request(), l_unimplemented(), l_end(), + l_quoted_string(), l_string(); +%} + +%% + +%{ +/* emptied */ +%} + +command_table return l_command_table(); +request return l_request(); +unimplemented return l_unimplemented(); +end return l_end(); + +[\t ] ; + +\n ++lineno; + +\"{PC}*\" return l_quoted_string(); + +{AN}* return l_string(); + +#.*\n ++lineno; + +. return (*yytext); + +%% + +/* + * User-subroutines section. + * + * Have to put all this stuff here so that the include file + * from YACC output can be included, since LEX doesn't allow + * an include file before the code it generates for the above + * rules. + */ + +#include +#include "y.tab.h" +/* #include "copyright.h" */ + +extern char *last_token, *ds(); + +static l_command_table() +{ + last_token = "command_table"; + return COMMAND_TABLE; +} + +static l_request() +{ + last_token = "request"; + return REQUEST; +} + +static l_unimplemented() +{ + last_token = "unimplemented"; + return UNIMPLEMENTED; +} + +static l_end() +{ + last_token = "end"; + return END; +} + +static l_quoted_string() +{ + register char *p; + yylval.dynstr = ds(yytext+1); + if (p=strrchr(yylval.dynstr, '"')) + *p='\0'; + last_token = ds(yylval.dynstr); + return STRING; +} + +static l_string() +{ + yylval.dynstr = ds(yytext); + last_token = ds(yylval.dynstr); + return STRING; +} diff --git a/kerberosIV/mk_cmds/ct.y b/kerberosIV/mk_cmds/ct.y new file mode 100644 index 00000000000..f8b8c93a532 --- /dev/null +++ b/kerberosIV/mk_cmds/ct.y @@ -0,0 +1,92 @@ +%{ +/* $Id: ct.y,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include + +char *str_concat3(), *ds(), *generate_rqte(), *quote(); +long flag_value(); +char *last_token = (char *)NULL; +FILE *output_file; +long gensym_n = 0; +%} + +%union { + char *dynstr; + long flags; +} + +%token COMMAND_TABLE REQUEST UNKNOWN UNIMPLEMENTED END +%token STRING +%token FLAGNAME +%type namelist header request_list +%type request_entry +%type flag_list options +%left OPTIONS +%{ +#define NO_SS_ERR_H +#include +%} +%start command_table +%% +command_table : header request_list END ';' + { write_ct($1, $2); } + ; + +header : COMMAND_TABLE STRING ';' + { $$ = $2; } + ; + +request_list : request_list request_entry + { $$ = str_concat3($1, $2, ""); } + | + { $$ = ""; } + ; + +request_entry : REQUEST STRING ',' STRING ',' namelist ',' options ';' + { $$ = generate_rqte($2, quote($4), $6, $8); } + | REQUEST STRING ',' STRING ',' namelist ';' + { $$ = generate_rqte($2, quote($4), $6, 0); } + | UNKNOWN namelist ';' + { $$ = generate_rqte("ss_unknown_request", + (char *)NULL, $2, 0); } + | UNIMPLEMENTED STRING ',' STRING ',' namelist ';' + { $$ = generate_rqte("ss_unimplemented", quote($4), $6, 3); } + ; + +options : '(' flag_list ')' + { $$ = $2; } + | '(' ')' + { $$ = 0; } + ; + +flag_list : flag_list ',' STRING + { $$ = $1 | flag_val($3); } + | STRING + { $$ = flag_val($1); } + ; + +namelist: STRING + { $$ = quote(ds($1)); } + | namelist ',' STRING + { $$ = str_concat3($1, quote($3), ",\n "); } + ; + +%% diff --git a/kerberosIV/mk_cmds/mk_cmds.c b/kerberosIV/mk_cmds/mk_cmds.c new file mode 100644 index 00000000000..b9a114b1a57 --- /dev/null +++ b/kerberosIV/mk_cmds/mk_cmds.c @@ -0,0 +1,106 @@ +/* $Id: mk_cmds.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include +#include +#ifndef NPOSIX +#include +#else +#include +#endif +#include "mk_cmds_defs.h" + +static const char copyright[] = + "Copyright 1987 by MIT Student Information Processing Board"; + +extern pointer malloc PROTOTYPE((unsigned)); +extern char *last_token; +extern FILE *output_file; + +extern FILE *yyin, *yyout; +extern unsigned lineno; + +main(argc, argv) + int argc; + char **argv; +{ + char c_file[MAXPATHLEN]; + int result; + char *path, *p; + + if (argc != 2) { + fputs("Usage: ", stderr); + fputs(argv[0], stderr); + fputs("cmdtbl.ct\n", stderr); + exit(1); + } + + path = malloc(strlen(argv[1])+4); /* extra space to add ".ct" */ + strcpy(path, argv[1]); + p = strrchr(path, '/'); + if (p == (char *)NULL) + p = path; + else + p++; + p = strrchr(p, '.'); + if (p == (char *)NULL || strcmp(p, ".ct")) + strcat(path, ".ct"); + yyin = fopen(path, "r"); + if (!yyin) { + perror(path); + exit(1); + } + + p = strrchr(path, '.'); + *p = '\0'; + strcpy(c_file, path); + strcat(c_file, ".c"); + *p = '.'; + + output_file = fopen(c_file, "w+"); + if (!output_file) { + perror(c_file); + exit(1); + } + + fputs("/* ", output_file); /* emacs fix -> */ + fputs(c_file, output_file); + fputs(" - automatically generated from ", output_file); + fputs(path, output_file); + fputs(" */\n", output_file); + fputs("#include \n\n", output_file); + fputs("#ifndef __STDC__\n#define const\n#endif\n\n", output_file); + /* parse it */ + result = yyparse(); + /* put file descriptors back where they belong */ + fclose(yyin); /* bye bye input file */ + fclose(output_file); /* bye bye output file */ + + return result; +} + +yyerror(s) + char *s; +{ + fputs(s, stderr); + fprintf(stderr, "\nLine %d; last token was '%s'\n", + lineno, last_token); +} diff --git a/kerberosIV/mk_cmds/mk_cmds_defs.h b/kerberosIV/mk_cmds/mk_cmds_defs.h new file mode 100644 index 00000000000..8e9df969065 --- /dev/null +++ b/kerberosIV/mk_cmds/mk_cmds_defs.h @@ -0,0 +1,40 @@ +/* $Id: mk_cmds_defs.h,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +#include +#include + +#ifdef __STDC__ + +#define PROTOTYPE(p) p +typedef void * pointer; + +#else + +#define const +#define volatile +#define PROTOTYPE(p) () +typedef char * pointer; + +#endif /* not __STDC__ */ + +#if defined(__GNUC__) +#define LOCAL_ALLOC(x) __builtin_alloca(x) +#define LOCAL_FREE(x) +#else +#if defined(vax) +#define LOCAL_ALLOC(x) alloca(x) +#define LOCAL_FREE(x) +extern pointer alloca PROTOTYPE((unsigned)); +#else +#if defined(__HIGHC__) /* Barf! */ +pragma on(alloca); +#define LOCAL_ALLOC(x) alloca(x) +#define LOCAL_FREE(x) +extern pointer alloca PROTOTYPE((unsigned)); +#else +/* no alloca? */ +#define LOCAL_ALLOC(x) malloc(x) +#define LOCAL_FREE(x) free(x) +#endif +#endif +#endif /* LOCAL_ALLOC stuff */ diff --git a/kerberosIV/mk_cmds/options.c b/kerberosIV/mk_cmds/options.c new file mode 100644 index 00000000000..d3d9af041ad --- /dev/null +++ b/kerberosIV/mk_cmds/options.c @@ -0,0 +1,46 @@ +/* $Id: options.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#define NO_SS_ERR_H +#include + +struct option { + char *text; + long value; +}; + +static struct option options[] = { + { "dont_list", SS_OPT_DONT_LIST }, + { "^list", SS_OPT_DONT_LIST }, + { "dont_summarize", SS_OPT_DONT_SUMMARIZE }, + { "^summarize", SS_OPT_DONT_SUMMARIZE }, + { (char *)NULL, 0 } +}; + +long +flag_val(string) + register char *string; +{ + register struct option *opt; + for (opt = options; opt->text; opt++) + if (!strcmp(opt->text, string)) + return(opt->value); + return(0); +} diff --git a/kerberosIV/mk_cmds/utils.c b/kerberosIV/mk_cmds/utils.c new file mode 100644 index 00000000000..c15d33bbf5e --- /dev/null +++ b/kerberosIV/mk_cmds/utils.c @@ -0,0 +1,142 @@ +/* $Id: utils.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by MIT Student Information Processing Board + * + * For copyright information, see copyright.h. + */ + +#include +#ifndef NPOSIX +#include +#else +#include +#define memcpy(a, b, c) bcopy(b, a, c) +#endif +#define NO_SS_ERR_H +#include "ss_internal.h" /* includes stdio and string */ + +extern FILE *output_file; +char *gensym(), *str_concat3(), *quote(), *ds(); +extern long gensym_n; + +void write_ct(hdr, rql) + char const *hdr, *rql; +{ + char *sym; + sym = gensym("ssu"); + fputs("static ss_request_entry ", output_file); + fputs(sym, output_file); + fputs("[] = {\n", output_file); + fputs(rql, output_file); + fputs(" { 0, 0, 0, 0 }\n", output_file); + fputs("};\n\nss_request_table ", output_file); + fputs(hdr, output_file); + fprintf(output_file, " = { %d, ", SS_RQT_TBL_V2); + fputs(sym, output_file); + fputs(" };\n", output_file); +} + +char * generate_cmds_string(cmds) + char const *cmds; +{ + char * var_name = gensym("ssu"); + fputs("static char const * const ", output_file); + fputs(var_name, output_file); + fputs("[] = {\n", output_file); + fputs(cmds, output_file); + fputs(",\n (char const *)0\n};\n", output_file); + return(var_name); +} + +void generate_function_definition(func) + char const *func; +{ + fputs("extern void ", output_file); + fputs(func, output_file); + fputs(" __P((int, const char * const *, int, void *));\n", output_file); +} + +char * generate_rqte(func_name, info_string, cmds, options) + char const *func_name; + char const *info_string; + char const *cmds; + int options; +{ + int size; + char *string, *var_name, numbuf[16]; + var_name = generate_cmds_string(cmds); + generate_function_definition(func_name); + size = 6; /* " { " */ + size += strlen(var_name)+7; /* "quux, " */ + size += strlen(func_name)+7; /* "foo, " */ + size += strlen(info_string)+9; /* "\"Info!\", " */ + sprintf(numbuf, "%d", options); + size += strlen(numbuf); + size += 4; /* " }," + NL */ + string = malloc(size * sizeof(char *)); + strcpy(string, " { "); + strcat(string, var_name); + strcat(string, ",\n "); + strcat(string, func_name); + strcat(string, ",\n "); + strcat(string, info_string); + strcat(string, ",\n "); + strcat(string, numbuf); + strcat(string, " },\n"); + return(string); +} + +char * +gensym(name) + char *name; +{ + char *symbol; + + symbol = malloc((strlen(name)+6) * sizeof(char)); + gensym_n++; + sprintf(symbol, "%s%05ld", name, gensym_n); + return(symbol); +} + +/* concatenate three strings and return the result */ +char *str_concat3(a, b, c) + register char *a, *b, *c; +{ + char *result; + int size_a = strlen(a); + int size_b = strlen(b); + int size_c = strlen(c); + + result = malloc((size_a + size_b + size_c + 2)*sizeof(char)); + strcpy(result, a); + strcpy(&result[size_a], c); + strcpy(&result[size_a+size_c], b); + return(result); +} + +/* return copy of string enclosed in double-quotes */ +char *quote(string) + register char *string; +{ + register char *result; + int len; + len = strlen(string)+1; + result = malloc(len+2); + result[0] = '"'; + memcpy(&result[1], string, len-1); + result[len] = '"'; + result[len+1] = '\0'; + return(result); +} + +/* make duplicate of string and return pointer */ +char *ds(s) + register char *s; +{ + register int len = strlen(s) + 1; + register char *new; + new = malloc(len); + memcpy(new, s, len); + return(new); +} diff --git a/kerberosIV/register/Makefile b/kerberosIV/register/Makefile new file mode 100644 index 00000000000..bdec3a0a40a --- /dev/null +++ b/kerberosIV/register/Makefile @@ -0,0 +1,14 @@ +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ + +PROG= register +SRCS= register.c des_rw.c +.PATH: ${.CURDIR}/../../usr.bin/rlogin +CFLAGS+=-DKERBEROS +DPADD+= ${LIBKRB} ${LIBCRYPT} ${LIBDES} +LDADD+= -lkrb -lcrypt -ldes +BINDIR= /usr/bin +BINOWN= root +BINMODE=4555 + +.include diff --git a/kerberosIV/register/pathnames.h b/kerberosIV/register/pathnames.h new file mode 100644 index 00000000000..a71d6282566 --- /dev/null +++ b/kerberosIV/register/pathnames.h @@ -0,0 +1,40 @@ +/* $Id: pathnames.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +/*- + * 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. + * + * from @(#)pathnames.h 8.1 (Berkeley) 6/1/93 + */ + +#define SERVER_KEYDIR "/etc/kerberosIV/register_keys" +#define CLIENT_KEYFILE "/etc/kerberosIV/.update.key" +#define _PATH_KPASSWD "/usr/bin/passwd" diff --git a/kerberosIV/register/register.1 b/kerberosIV/register/register.1 new file mode 100644 index 00000000000..cdb5226ddd3 --- /dev/null +++ b/kerberosIV/register/register.1 @@ -0,0 +1,64 @@ +.\" 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. +.\" +.\" from @(#)register.1 8.1 (Berkeley) 6/1/93 +.\" $Id: register.1,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ +.\" +.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/kerberosIV/register/register.c b/kerberosIV/register/register.c new file mode 100644 index 00000000000..3104f3ea986 --- /dev/null +++ b/kerberosIV/register/register.c @@ -0,0 +1,316 @@ +/* $Id: register.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ */ + +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(" 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/kerberosIV/register/register_proto.h b/kerberosIV/register/register_proto.h new file mode 100644 index 00000000000..d5cb094f843 --- /dev/null +++ b/kerberosIV/register/register_proto.h @@ -0,0 +1,44 @@ +/*- + * 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. + * + * from @(#)register_proto.h 8.1 (Berkeley) 6/1/93 + * $Id: register_proto.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $ + */ + +#define APPEND_DB 0x01 +#define ABORT 0x02 + +#define GOTKEY_MSG "GOTKEY" + +struct keyfile_data { + C_Block kf_key; +}; diff --git a/kerberosIV/registerd/Makefile b/kerberosIV/registerd/Makefile new file mode 100644 index 00000000000..2019ed5e733 --- /dev/null +++ b/kerberosIV/registerd/Makefile @@ -0,0 +1,16 @@ +# Copyright (c) 1990 The Regents of the University of California. +# All rights reserved. +# +# from @(#)Makefile 8.1 (Berkeley) 6/1/93 +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ + +PROG= registerd +SRCS= registerd.c des_rw.c +.PATH: ${.CURDIR}/../../usr.bin/rlogin +CFLAGS+=-DKERBEROS -I${.CURDIR}/../register +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes +MAN= registerd.8 +BINDIR= /usr/libexec + +.include diff --git a/kerberosIV/registerd/registerd.8 b/kerberosIV/registerd/registerd.8 new file mode 100644 index 00000000000..c53a0b596e7 --- /dev/null +++ b/kerberosIV/registerd/registerd.8 @@ -0,0 +1,70 @@ +.\" 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. +.\" +.\" from @(#)registerd.8 8.2 (Berkeley) 12/11/93 +.\" $Id: registerd.8,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ +.\" +.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/kerberosIV/registerd/registerd.c b/kerberosIV/registerd/registerd.c new file mode 100644 index 00000000000..a1f3fcc3315 --- /dev/null +++ b/kerberosIV/registerd/registerd.c @@ -0,0 +1,347 @@ +/* $Id: registerd.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $ */ + +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 sina; + 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(sina); + if (getpeername(0, (struct sockaddr *) &sina, &sval) < 0) { + syslog(LOG_ERR, "getpeername: %m"); + exit(1); + } + + /* get encryption key */ + + (void) sprintf(keyfile, "%s%s%s", + SERVER_KEYDIR, + CLIENT_KEYFILE, + inet_ntoa(sina.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(&sina); + 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/kerberosIV/ss/Makefile b/kerberosIV/ss/Makefile new file mode 100644 index 00000000000..c778fe66192 --- /dev/null +++ b/kerberosIV/ss/Makefile @@ -0,0 +1,34 @@ +# $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ + +LIB= ss +SRCS= ss_err.c data.c error.c execute_cmd.c help.c invocation.c list_rqs.c \ + listen.c pager.c parse.c prompt.c request_tbl.c requests.c \ + std_rqs.c +CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../com_err +LDADD+= ${COM_ERR} +CLEANFILES+= ss_err.c ss_err.h std_rqs.c ss + +ss_err.h ss_err.c: ${.CURDIR}/ss_err.et + test -e ss_err.et || ln -s ${.CURDIR}/ss_err.et . + ${COMPILE_ET} ss_err.et + -test -h ss_err.et && rm ss_err.et + +std_rqs.c: ${.CURDIR}/std_rqs.ct + test -e std_rqs.ct || ln -s ${.CURDIR}/std_rqs.ct . + ${MK_CMDS} std_rqs.ct + -test -h std_rqs.ct && rm std_rqs.ct + +beforeinstall: + -cd ${.OBJDIR}; \ + if [ -f ss_err.h ]; then \ + cmp -s ss_err.h ${DESTDIR}/usr/include/ss/ss_err.h || \ + install -c -o ${BINOWN} -g ${BINGRP} -m 444 ss_err.h \ + ${DESTDIR}/usr/include/ss; \ + else \ + true; \ + fi + +beforedepend: + ln -s . ss + +.include diff --git a/kerberosIV/ss/data.c b/kerberosIV/ss/data.c new file mode 100644 index 00000000000..bba1b58cc72 --- /dev/null +++ b/kerberosIV/ss/data.c @@ -0,0 +1,27 @@ +/* $Id: data.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include "ss_internal.h" + +const static char copyright[] = + "Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology"; + +ss_data **_ss_table = (ss_data **)NULL; +char *_ss_pager_name = (char *)NULL; diff --git a/kerberosIV/ss/error.c b/kerberosIV/ss/error.c new file mode 100644 index 00000000000..0a6352a0ae6 --- /dev/null +++ b/kerberosIV/ss/error.c @@ -0,0 +1,114 @@ +/* $Id: error.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include + +/* + * Our standalone dpANS environment on the RT doesn't include any + * header files. + */ +#if defined(__STDC__) && !defined(ibm032) +#include +#define STDARG +#else +#include +#define ss_error ss_error_external +#endif + +#include +#include "ss_internal.h" + +#undef ss_error + +char * +ss_name(sci_idx) + int sci_idx; +{ + register char *ret_val; + register ss_data *infop; + + infop = ss_info(sci_idx); + if (infop->current_request == (char const *)NULL) { + ret_val = malloc((unsigned) + (strlen(infop->subsystem_name)+1) + * sizeof(char)); + if (ret_val == (char *)NULL) + return((char *)NULL); + strcpy(ret_val, infop->subsystem_name); + return(ret_val); + } + else { + register char *cp; + register char const *cp1; + ret_val = malloc((unsigned)sizeof(char) * + (strlen(infop->subsystem_name)+ + strlen(infop->current_request)+ + 4)); + cp = ret_val; + cp1 = infop->subsystem_name; + while (*cp1) + *cp++ = *cp1++; + *cp++ = ' '; + *cp++ = '('; + cp1 = infop->current_request; + while (*cp1) + *cp++ = *cp1++; + *cp++ = ')'; + *cp = '\0'; + return(ret_val); + } +} + +#ifdef STDARG +void +ss_error (int sci_idx, long code, const char * fmt, ...) +#else +void +ss_error (va_alist) + va_dcl +#endif +{ + register char *whoami; + va_list pvar; +#ifndef STDARG + int sci_idx; + long code; + char * fmt; + va_start (pvar); + sci_idx = va_arg (pvar, int); + code = va_arg (pvar, long); + fmt = va_arg (pvar, char *); +#else + va_start (pvar, fmt); +#endif + whoami = ss_name (sci_idx); + com_err_va (whoami, code, fmt, pvar); + free (whoami); + va_end(pvar); +} + +void +ss_perror (sci_idx, code, msg) /* for compatibility */ + int sci_idx; + long code; + char const *msg; +{ + ss_error (sci_idx, code, "%s", msg); +} diff --git a/kerberosIV/ss/execute_cmd.c b/kerberosIV/ss/execute_cmd.c new file mode 100644 index 00000000000..13230c84d73 --- /dev/null +++ b/kerberosIV/ss/execute_cmd.c @@ -0,0 +1,241 @@ +/* $Id: execute_cmd.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include + +#include "ss_internal.h" + +#ifndef lint +static char const rcsid[] = + "$Id: execute_cmd.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $"; +#endif + +/* + * get_request(tbl, idx) + * + * Function: + * Gets the idx'th request from the request table pointed to + * by tbl. + * Arguments: + * tbl (ss_request_table *) + * pointer to request table + * idx (int) + * index into table + * Returns: + * (ss_request_entry *) + * pointer to request table entry + * Notes: + * Has been replaced by a macro. + */ + +#ifdef __SABER__ +/* sigh. saber won't deal with pointer-to-const-struct */ +static struct _ss_request_entry * +get_request (tbl, idx) + ss_request_table * tbl; + int idx; +{ + struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl; + struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests; + return e + idx; +} +#else +#define get_request(tbl,idx) ((tbl) -> requests + (idx)) +#endif + +/* + * check_request_table(rqtbl, argc, argv, sci_idx) + * + * Function: + * If the command string in argv[0] is in the request table, execute + * the commands and return error code 0. Otherwise, return error + * code ss_et_command_not_found. + * Arguments: + * rqtbl (ss_request_table *) + * pointer to request table + * argc (int) + * number of elements in argv[] + * argv (char *[]) + * argument string array + * sci_idx (int) + * ss-internal index for subsystem control info structure + * Returns: + * (int) + * zero if command found, ss_et_command_not_found otherwise + * Notes: + */ + +static int +check_request_table (rqtbl, argc, argv, sci_idx) + register ss_request_table *rqtbl; + int argc; + char *argv[]; + int sci_idx; +{ +#ifdef __SABER__ + struct _ss_request_entry *request; +#else + register ss_request_entry *request; +#endif + register ss_data *info; + register char const * const * name; + char *string = argv[0]; + int i; + + info = ss_info(sci_idx); + info->argc = argc; + info->argv = argv; + for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { + for (name = request->command_names; *name; name++) + if (!strcmp(*name, string)) { + info->current_request = request->command_names[0]; + (request->function)(argc, (const char *const *) argv, + sci_idx,info->info_ptr); + info->current_request = (char *)NULL; + return(0); + } + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * really_execute_command(sci_idx, argc, argv) + * + * Function: + * Fills in the argc, argv values in the subsystem entry and + * call the appropriate routine. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argc (int) + * number of arguments in argument list + * argv (char **[]) + * pointer to parsed argument list (may be reallocated + * on abbrev expansion) + * + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +static int +really_execute_command (sci_idx, argc, argv) + int sci_idx; + int argc; + char **argv[]; +{ + register ss_request_table **rqtbl; + register ss_data *info; + + info = ss_info(sci_idx); + + for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { + if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) + return(0); + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * ss_execute_command(sci_idx, argv) + * + * Function: + * Executes a parsed command list within the subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argv (char *[]) + * parsed argument list + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +int +ss_execute_command(sci_idx, argv) + int sci_idx; + register char *argv[]; +{ + register int i, argc; + char **argp; + + argc = 0; + for (argp = argv; *argp; argp++) + argc++; + argp = (char **)malloc((argc+1)*sizeof(char *)); + for (i = 0; i <= argc; i++) + argp[i] = argv[i]; + i = really_execute_command(sci_idx, argc, &argp); + free(argp); + return(i); +} + +/* + * ss_execute_line(sci_idx, line_ptr) + * + * Function: + * Parses and executes a command line within a subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * line_ptr (char *) + * Pointer to command line to be parsed. + * Returns: + * (int) + * Error code. + * Notes: + */ + +int +ss_execute_line (sci_idx, line_ptr) + int sci_idx; + char *line_ptr; +{ + char **argv; + int argc; + int retval; + + /* flush leading whitespace */ + while (line_ptr[0] == ' ' || line_ptr[0] == '\t') + line_ptr++; + + /* check if it should be sent to operating system for execution */ + if (*line_ptr == '!') { + if (ss_info(sci_idx)->flags.escape_disabled) + return SS_ET_ESCAPE_DISABLED; + else { + line_ptr++; + system(line_ptr); + return 0; + } + } + + /* parse it */ + argv = ss_parse(sci_idx, line_ptr, &argc); + if (argc == 0) + return 0; + + /* look it up in the request tables, execute if found */ + retval = really_execute_command (sci_idx, argc, &argv); + free(argv); + return(retval); +} diff --git a/kerberosIV/ss/help.c b/kerberosIV/ss/help.c new file mode 100644 index 00000000000..64d94f0e0d5 --- /dev/null +++ b/kerberosIV/ss/help.c @@ -0,0 +1,171 @@ +/* $Id: help.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include +#include +#include +#include +#ifndef NPOSIX +#include +#endif +#include +#include "ss_internal.h" + +extern int errno; + +void +ss_help (argc, argv, sci_idx, info_ptr) + int argc; + char const * const *argv; + int sci_idx; + pointer info_ptr; +{ + char buffer[MAXPATHLEN]; + char const *request_name; + int code; + int fd, child; + register int idx; + register ss_data *info; + + request_name = ss_current_request(sci_idx, &code); + if (code != 0) { + ss_perror(sci_idx, code, ""); + return; /* no ss_abort_line, if invalid invocation */ + } + if (argc == 1) { + ss_list_requests(argc, argv, sci_idx, info_ptr); + return; + } + else if (argc != 2) { + /* should do something better than this */ + sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n", + request_name, request_name); + ss_perror(sci_idx, 0, buffer); + return; + } + info = ss_info(sci_idx); + if (info->info_dirs == (char **)NULL) { + ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL); + return; + } + if (info->info_dirs[0] == (char *)NULL) { + ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL); + return; + } + for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) { + (void) strcpy(buffer, info->info_dirs[idx]); + (void) strcat(buffer, "/"); + (void) strcat(buffer, argv[1]); + (void) strcat(buffer, ".info"); + if ((fd = open(&buffer[0], O_RDONLY, 0)) >= 0) goto got_it; + } + if ((fd = open(&buffer[0], O_RDONLY, 0)) < 0) { + char buf[MAXPATHLEN]; + strcpy(buf, "No info found for "); + strcat(buf, argv[1]); + ss_perror(sci_idx, 0, buf); + return; + } +got_it: + switch (child = fork()) { + case -1: + ss_perror(sci_idx, errno, "Can't fork for pager"); + return; + case 0: + (void) dup2(fd, 0); /* put file on stdin */ + ss_page_stdin(); + default: + (void) close(fd); /* what can we do if it fails? */ +#ifndef NPOSIX + while (wait((int *)0) != child) ; /* do nothing if wrong pid */ +#else + while (wait((union wait *)0) != child) ; /* do nothing if wrong pid */ +#endif + } +} + +#include +#ifdef NPOSIX +#include +#else +#include +#endif /* NPOSIX */ + +void +ss_add_info_dir(sci_idx, info_dir, code_ptr) + int sci_idx; + char *info_dir; + int *code_ptr; +{ + register ss_data *info; + DIR *d; + int n_dirs; + register char **dirs; + + info = ss_info(sci_idx); + if (info_dir == NULL && *info_dir) { + *code_ptr = SS_ET_NO_INFO_DIR; + return; + } + if ((d = opendir(info_dir)) == (DIR *)NULL) { + *code_ptr = errno; + return; + } + closedir(d); + dirs = info->info_dirs; + for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++) + ; /* get number of non-NULL dir entries */ + dirs = (char **)realloc((char *)dirs, + (unsigned)(n_dirs + 2)*sizeof(char *)); + if (dirs == (char **)NULL) { + info->info_dirs = (char **)NULL; + *code_ptr = errno; + return; + } + info->info_dirs = dirs; + dirs[n_dirs + 1] = (char *)NULL; + dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1); + strcpy(dirs[n_dirs], info_dir); + *code_ptr = 0; +} + +void +ss_delete_info_dir(sci_idx, info_dir, code_ptr) + int sci_idx; + char *info_dir; + int *code_ptr; +{ + register char **i_d; + register char **info_dirs; + + info_dirs = ss_info(sci_idx)->info_dirs; + for (i_d = info_dirs; *i_d; i_d++) { + if (!strcmp(*i_d, info_dir)) { + while (*i_d) { + *i_d = *(i_d+1); + i_d++; + } + *code_ptr = 0; + return; + } + } + *code_ptr = SS_ET_NO_INFO_DIR; +} diff --git a/kerberosIV/ss/invocation.c b/kerberosIV/ss/invocation.c new file mode 100644 index 00000000000..55caa5f2449 --- /dev/null +++ b/kerberosIV/ss/invocation.c @@ -0,0 +1,97 @@ +/* $Id: invocation.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include "ss_internal.h" +#define size sizeof(ss_data *) + +#ifndef lint +static char const rcsid[] = + "$Id: invocation.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $"; +#endif + +int +ss_create_invocation(subsystem_name, version_string, info_ptr, + request_table_ptr, code_ptr) + char *subsystem_name, *version_string; + char *info_ptr; + ss_request_table *request_table_ptr; + int *code_ptr; +{ + register int sci_idx; + register ss_data *new_table; + register ss_data **table; + + *code_ptr = 0; + table = _ss_table; + new_table = (ss_data *) malloc(sizeof(ss_data)); + + if (table == (ss_data **) NULL) { + table = (ss_data **) malloc(2 * size); + table[0] = table[1] = (ss_data *)NULL; + } + initialize_ss_error_table (); + + for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++) + ; + table = (ss_data **) realloc((char *)table, + ((unsigned)sci_idx+2)*size); + table[sci_idx+1] = (ss_data *) NULL; + table[sci_idx] = new_table; + + new_table->subsystem_name = subsystem_name; + new_table->subsystem_version = version_string; + new_table->argv = (char **)NULL; + new_table->current_request = (char *)NULL; + new_table->info_dirs = (char **)malloc(sizeof(char *)); + *new_table->info_dirs = (char *)NULL; + new_table->info_ptr = info_ptr; + new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4); + strcpy(new_table->prompt, subsystem_name); + strcat(new_table->prompt, ": "); +#ifdef silly + new_table->abbrev_info = ss_abbrev_initialize("/etc/passwd", code_ptr); +#else + new_table->abbrev_info = NULL; +#endif + new_table->flags.escape_disabled = 0; + new_table->flags.abbrevs_disabled = 0; + new_table->rqt_tables = + (ss_request_table **) calloc(2, sizeof(ss_request_table *)); + *(new_table->rqt_tables) = request_table_ptr; + *(new_table->rqt_tables+1) = (ss_request_table *) NULL; + _ss_table = table; + return(sci_idx); +} + +void +ss_delete_invocation(sci_idx) + int sci_idx; +{ + register ss_data *t; + int ignored_code; + + t = ss_info(sci_idx); + free(t->prompt); + free((char *)t->rqt_tables); + while(t->info_dirs[0] != (char *)NULL) + ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code); + free((char *)t->info_dirs); + free((char *)t); +} diff --git a/kerberosIV/ss/list_rqs.c b/kerberosIV/ss/list_rqs.c new file mode 100644 index 00000000000..27f701328f2 --- /dev/null +++ b/kerberosIV/ss/list_rqs.c @@ -0,0 +1,124 @@ +/* $Id: list_rqs.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include "ss_internal.h" +#include +#include +#include +#include + +#ifdef lint /* "lint returns a value which is sometimes ignored" */ +#define DONT_USE(x) x=x; +#else /* !lint */ +#define DONT_USE(x) ; +#endif /* lint */ + +static char const twentyfive_spaces[26] = + " "; +static char const NL[2] = "\n"; + +int +ss_list_requests(argc, argv, sci_idx, info_ptr) + int argc; + char **argv; + int sci_idx; + pointer info_ptr; +{ + register ss_request_entry *entry; + register char const * const *name; + register int spacing; + register ss_request_table **table; + + char buffer[BUFSIZ]; + FILE *output; + int fd; +#ifndef NPOSIX + struct sigaction nsig, osig; + sigset_t nmask, omask; + int waitb; +#else + int (*func)(); + int mask; + union wait waitb; +#endif + + DONT_USE(argc); + DONT_USE(argv); + +#ifndef NPOSIX + sigemptyset(&nmask); + sigaddset(&nmask, SIGINT); + sigprocmask(SIG_BLOCK, &nmask, &omask); + + nsig.sa_handler = SIG_IGN; + sigemptyset(&nsig.sa_mask); + nsig.sa_flags = 0; + sigaction(SIGINT, &nsig, &osig); +#else + mask = sigblock(sigmask(SIGINT)); + func = signal(SIGINT, SIG_IGN); +#endif + fd = ss_pager_create(); + output = fdopen(fd, "w"); +#ifndef NPOSIX + sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); +#else + sigsetmask(mask); +#endif + + fprintf (output, "Available %s requests:\n\n", + ss_info (sci_idx) -> subsystem_name); + + for (table = ss_info(sci_idx)->rqt_tables; *table; table++) { + entry = (*table)->requests; + for (; entry->command_names; entry++) { + spacing = -2; + buffer[0] = '\0'; + if (entry->flags & SS_OPT_DONT_LIST) + continue; + for (name = entry->command_names; *name; name++) { + register int len = strlen(*name); + strncat(buffer, *name, len); + spacing += len + 2; + if (name[1]) { + strcat(buffer, ", "); + } + } + if (spacing > 23) { + strcat(buffer, NL); + fputs(buffer, output); + spacing = 0; + buffer[0] = '\0'; + } + strncat(buffer, twentyfive_spaces, 25-spacing); + strcat(buffer, entry->info_string); + strcat(buffer, NL); + fputs(buffer, output); + } + } + fclose(output); +#ifndef NO_FORK + wait(&waitb); +#endif +#ifndef NPOSIX + sigaction(SIGINT, &osig, (struct sigaction *)0); +#else + (void) signal(SIGINT, func); +#endif +} diff --git a/kerberosIV/ss/listen.c b/kerberosIV/ss/listen.c new file mode 100644 index 00000000000..5e24f7f99d2 --- /dev/null +++ b/kerberosIV/ss/listen.c @@ -0,0 +1,216 @@ +/* $Id: listen.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Listener loop for subsystem library libss.a. + */ + +#include "ss_internal.h" +#include +#ifndef NPOSIX +#include +#else +#include +#define memcpy(a, b, c) bcopy(b, a, c) +#endif +#include +#include +#include +#ifdef BSD +#include +#endif + +#ifndef lint +static char const rcs_id[] = + "$Id: listen.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $"; +#endif + +#ifndef NPOSIX +#define sigtype void +#else +#define sigtype int +#endif + +static ss_data *current_info; +static jmp_buf listen_jmpb; + +static sigtype +print_prompt() +{ +#ifdef BSD + /* put input into a reasonable mode */ + struct sgttyb ttyb; + if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) { + if (ttyb.sg_flags & (CBREAK|RAW)) { + ttyb.sg_flags &= ~(CBREAK|RAW); + (void) ioctl(0, TIOCSETP, &ttyb); + } + } +#endif + (void) fputs(current_info->prompt, stdout); + (void) fflush(stdout); +} + +static sigtype +listen_int_handler() +{ + putc('\n', stdout); + longjmp(listen_jmpb, 1); +} + +static sigtype print_prompt(); + +int +ss_listen (sci_idx) + int sci_idx; +{ + register char *cp; + register ss_data *info; + char input[BUFSIZ]; + char expanded_input[BUFSIZ]; + char buffer[BUFSIZ]; + char *end = buffer; + int code; + jmp_buf old_jmpb; + ss_data *old_info = current_info; +#ifndef NPOSIX + struct sigaction isig, csig, nsig, osig; + sigset_t nmask, omask; +#else + register sigtype (*sig_cont)(); + sigtype (*sig_int)(), (*old_sig_cont)(); + int mask; +#endif + + current_info = info = ss_info(sci_idx); + info->abort = 0; +#ifndef NPOSIX + csig.sa_handler = (sigtype (*)())0; + + sigemptyset(&nmask); + sigaddset(&nmask, SIGINT); + sigprocmask(SIG_BLOCK, &nmask, &omask); +#else + sig_cont = (sigtype (*)())0; + mask = sigblock(sigmask(SIGINT)); +#endif + + memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf)); + +#ifndef NPOSIX + nsig.sa_handler = listen_int_handler; + sigemptyset(&nsig.sa_mask); + nsig.sa_flags = 0; + sigaction(SIGINT, &nsig, &isig); +#else + sig_int = signal(SIGINT, listen_int_handler); +#endif + + setjmp(listen_jmpb); + +#ifndef NPOSIX + sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); +#else + (void) sigsetmask(mask); +#endif + while(!info->abort) { + print_prompt(); + *end = '\0'; +#ifndef NPOSIX + nsig.sa_handler = listen_int_handler; /* fgets is not signal-safe */ + osig = csig; + sigaction(SIGCONT, &nsig, &csig); + if ((sigtype (*)())csig.sa_handler==(sigtype (*)())listen_int_handler) + csig = osig; +#else + old_sig_cont = sig_cont; + sig_cont = signal(SIGCONT, print_prompt); +#ifdef mips + /* The mips compiler breaks on determining the types, we help */ + if ( (sigtype *) sig_cont == (sigtype *) print_prompt) + sig_cont = old_sig_cont; +#else + if (sig_cont == print_prompt) + sig_cont = old_sig_cont; +#endif +#endif + if (fgets(input, BUFSIZ, stdin) != input) { + code = SS_ET_EOF; + goto egress; + } + cp = strchr(input, '\n'); + if (cp) { + *cp = '\0'; + if (cp == input) + continue; + } +#ifndef NPOSIX + sigaction(SIGCONT, &csig, (struct sigaction *)0); +#else + (void) signal(SIGCONT, sig_cont); +#endif + for (end = input; *end; end++) + ; + + code = ss_execute_line (sci_idx, input); + if (code == SS_ET_COMMAND_NOT_FOUND) { + register char *c = input; + while (*c == ' ' || *c == '\t') + c++; + cp = strchr (c, ' '); + if (cp) + *cp = '\0'; + cp = strchr (c, '\t'); + if (cp) + *cp = '\0'; + ss_error (sci_idx, 0, + "Unknown request \"%s\". Type \"?\" for a request list.", + c); + } + } + code = 0; +egress: +#ifndef NPOSIX + sigaction(SIGINT, &isig, (struct sigaction *)0); +#else + (void) signal(SIGINT, sig_int); +#endif + memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf)); + current_info = old_info; + return code; +} + +void +ss_abort_subsystem(sci_idx, code) + int sci_idx; +{ + ss_info(sci_idx)->abort = 1; + ss_info(sci_idx)->exit_status = code; + +} + +int +ss_quit(argc, argv, sci_idx, infop) + int argc; + char **argv; + int sci_idx; + pointer infop; +{ + ss_abort_subsystem(sci_idx, 0); +} diff --git a/kerberosIV/ss/pager.c b/kerberosIV/ss/pager.c new file mode 100644 index 00000000000..f4484c0f993 --- /dev/null +++ b/kerberosIV/ss/pager.c @@ -0,0 +1,127 @@ +/* $Id: pager.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * Pager: Routines to create a "more" running out of a particular file + * descriptor. + */ + +#include "ss_internal.h" +#include +#include +#include +#include +#include + +static char MORE[] = "more"; +extern char *_ss_pager_name; +extern char *getenv(); +extern int errno; + +/* + * this needs a *lot* of work.... + * + * run in same process + * handle SIGINT sensibly + * allow finer control -- put-page-break-here + */ +void ss_page_stdin(); + +#ifndef NO_FORK +int +ss_pager_create() +{ + int filedes[2]; + + if (pipe(filedes) != 0) + return(-1); + + switch(fork()) { + case -1: + return(-1); + case 0: + /* + * Child; dup read half to 0, close all but 0, 1, and 2 + */ + if (dup2(filedes[0], 0) == -1) + exit(1); + ss_page_stdin(); + default: + /* + * Parent: close "read" side of pipe, return + * "write" side. + */ + (void) close(filedes[0]); + return(filedes[1]); + } +} +#else /* don't fork */ +int +ss_pager_create() +{ + int fd; + fd = open("/dev/tty", O_WRONLY, 0); + return fd; +} +#endif + +void +ss_page_stdin() +{ + int i; +#ifndef NPOSIX + struct sigaction sa; + sigset_t mask; +#endif + + for (i = 3; i < 32; i++) + (void) close(i); +#ifndef NPOSIX + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGINT, &sa, (struct sigaction *)0); +#else + (void) signal(SIGINT, SIG_DFL); +#endif + { +#ifndef NPOSIX + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)0); +#else + register int mask = sigblock(0); + mask &= ~sigmask(SIGINT); + sigsetmask(mask); +#endif + } + if (_ss_pager_name == (char *)NULL) { + if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL) + _ss_pager_name = MORE; + } + (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL); + { + /* minimal recovery if pager program isn't found */ + char buf[80]; + register int n; + while ((n = read(0, buf, 80)) > 0) + write(1, buf, n); + } + exit(errno); +} diff --git a/kerberosIV/ss/parse.c b/kerberosIV/ss/parse.c new file mode 100644 index 00000000000..6eff8ad7707 --- /dev/null +++ b/kerberosIV/ss/parse.c @@ -0,0 +1,155 @@ +/* $Id: parse.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include +#include + +#include "ss_internal.h" + +#ifndef lint +static char const rcsid[] = + "$Id: parse.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $"; +#endif + +enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; + +/* + * parse(line_ptr, argc_ptr) + * + * Function: + * Parses line, dividing at whitespace, into tokens, returns + * the "argc" and "argv" values. + * Arguments: + * line_ptr (char *) + * Pointer to text string to be parsed. + * argc_ptr (int *) + * Where to put the "argc" (number of tokens) value. + * Returns: + * argv (char **) + * Series of pointers to parsed tokens. + */ + +#define NEW_ARGV(old,n) (char **)realloc((char *)old,\ + (unsigned)(n+2)*sizeof(char*)) + +char ** +ss_parse (sci_idx, line_ptr, argc_ptr) + int sci_idx; + register char *line_ptr; + int *argc_ptr; +{ + register char **argv, *cp; + register int argc; + register enum parse_mode parse_mode; + + *argc_ptr = 0; /* In case of error return something sane */ + argv = (char **) malloc (sizeof(char *)); + if (argv == (char **)NULL) { + ss_error(sci_idx, errno, "Can't allocate storage"); + return(argv); + } + *argv = (char *)NULL; + + argc = 0; + + parse_mode = WHITESPACE; /* flushing whitespace */ + cp = line_ptr; /* cp is for output */ + while (1) { +#ifdef DEBUG + { + printf ("character `%c', mode %d\n", *line_ptr, parse_mode); + } +#endif + while (parse_mode == WHITESPACE) { + if (*line_ptr == '\0') + goto end_of_line; + if (*line_ptr == ' ' || *line_ptr == '\t') { + line_ptr++; + continue; + } + if (*line_ptr == '"') { + /* go to quoted-string mode */ + parse_mode = QUOTED_STRING; + cp = line_ptr++; + argv = NEW_ARGV (argv, argc); + argv[argc++] = cp; + argv[argc] = NULL; + } + else { + /* random-token mode */ + parse_mode = TOKEN; + cp = line_ptr; + argv = NEW_ARGV (argv, argc); + argv[argc++] = line_ptr; + argv[argc] = NULL; + } + } + while (parse_mode == TOKEN) { + if (*line_ptr == '\0') { + *cp++ = '\0'; + goto end_of_line; + } + else if (*line_ptr == ' ' || *line_ptr == '\t') { + *cp++ = '\0'; + line_ptr++; + parse_mode = WHITESPACE; + } + else if (*line_ptr == '"') { + line_ptr++; + parse_mode = QUOTED_STRING; + } + else { + *cp++ = *line_ptr++; + } + } + while (parse_mode == QUOTED_STRING) { + if (*line_ptr == '\0') { + ss_error (sci_idx, 0, + "Unbalanced quotes in command line"); + free (argv); + return NULL; + } + else if (*line_ptr == '"') { + if (*++line_ptr == '"') { + *cp++ = '"'; + line_ptr++; + } + else { + parse_mode = TOKEN; + } + } + else { + *cp++ = *line_ptr++; + } + } + } +end_of_line: + *argc_ptr = argc; +#ifdef DEBUG + { + int i; + printf ("argc = %d\n", argc); + for (i = 0; i <= argc; i++) + printf ("\targv[%2d] = `%s'\n", i, + argv[i] ? argv[i] : ""); + } +#endif + return(argv); +} diff --git a/kerberosIV/ss/prompt.c b/kerberosIV/ss/prompt.c new file mode 100644 index 00000000000..f4415e40de4 --- /dev/null +++ b/kerberosIV/ss/prompt.c @@ -0,0 +1,43 @@ +/* $Id: prompt.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +/* + * prompt.c: Routines for retrieving and setting a prompt. + */ + +#include +#include "ss_internal.h" + +static const char rcsid[] = + "$Id: prompt.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $"; + +int +ss_set_prompt(sci_idx, new_prompt) + int sci_idx; + char *new_prompt; +{ + ss_info(sci_idx)->prompt = new_prompt; +} + +char * +ss_get_prompt(sci_idx) + int sci_idx; +{ + return(ss_info(sci_idx)->prompt); +} diff --git a/kerberosIV/ss/request_tbl.c b/kerberosIV/ss/request_tbl.c new file mode 100644 index 00000000000..64732d81a29 --- /dev/null +++ b/kerberosIV/ss/request_tbl.c @@ -0,0 +1,80 @@ +/* $Id: request_tbl.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#include +#include + +#include "ss_internal.h" + +#define ssrt ss_request_table /* for some readable code... */ + +void +ss_add_request_table(sci_idx, rqtbl_ptr, position, code_ptr) + int sci_idx; + ssrt *rqtbl_ptr; + int position; /* 1 -> becomes second... */ + int *code_ptr; +{ + register ss_data *info; + register int i, size; + + info = ss_info(sci_idx); + for (size=0; info->rqt_tables[size] != (ssrt *)NULL; size++) + ; + /* size == C subscript of NULL == #elements */ + size += 2; /* new element, and NULL */ + info->rqt_tables = (ssrt **)realloc((char *)info->rqt_tables, + (unsigned)size*sizeof(ssrt)); + if (info->rqt_tables == (ssrt **)NULL) { + *code_ptr = errno; + return; + } + if (position > size - 2) + position = size - 2; + + if (size > 1) + for (i = size - 2; i >= position; i--) + info->rqt_tables[i+1] = info->rqt_tables[i]; + + info->rqt_tables[position] = rqtbl_ptr; + info->rqt_tables[size-1] = (ssrt *)NULL; + *code_ptr = 0; +} + +void +ss_delete_request_table(sci_idx, rqtbl_ptr, code_ptr) + int sci_idx; + ssrt *rqtbl_ptr; + int *code_ptr; +{ + register ss_data *info; + register ssrt **rt1, **rt2; + + *code_ptr = SS_ET_TABLE_NOT_FOUND; + info = ss_info(sci_idx); + rt1 = info->rqt_tables; + for (rt2 = rt1; *rt1; rt1++) { + if (*rt1 != rqtbl_ptr) { + *rt2++ = *rt1; + *code_ptr = 0; + } + } + *rt2 = (ssrt *)NULL; + return; +} diff --git a/kerberosIV/ss/requests.c b/kerberosIV/ss/requests.c new file mode 100644 index 00000000000..8484da0620f --- /dev/null +++ b/kerberosIV/ss/requests.c @@ -0,0 +1,62 @@ +/* $Id: requests.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */ + +/*- + * Copyright 1987, 1988, 1989 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. + */ + +/* + * Various minor routines... + */ + +#include +#include "ss_internal.h" + +#define DECLARE(name) name(argc,argv,sci_idx)int argc,sci_idx;char **argv; + +/* + * ss_self_identify -- assigned by default to the "." request + */ +DECLARE(ss_self_identify) +{ + register ss_data *info = ss_info(sci_idx); + printf("%s version %s\n", info->subsystem_name, + info->subsystem_version); +} + +/* + * ss_subsystem_name -- print name of subsystem + */ +DECLARE(ss_subsystem_name) +{ + printf("%s\n", ss_info(sci_idx)->subsystem_name); +} + +/* + * ss_subsystem_version -- print version of subsystem + */ +DECLARE(ss_subsystem_version) +{ + printf("%s\n", ss_info(sci_idx)->subsystem_version); +} + +/* + * ss_unimplemented -- routine not implemented (should be + * set up as (dont_list,dont_summarize)) + */ +DECLARE(ss_unimplemented) +{ + ss_perror(sci_idx, SS_ET_UNIMPLEMENTED, ""); +} diff --git a/kerberosIV/ss/shlib_version b/kerberosIV/ss/shlib_version new file mode 100644 index 00000000000..d9961ea9fef --- /dev/null +++ b/kerberosIV/ss/shlib_version @@ -0,0 +1,2 @@ +major=4 +minor=0 diff --git a/kerberosIV/ss/ss_err.et b/kerberosIV/ss/ss_err.et new file mode 100644 index 00000000000..80e9dfa4449 --- /dev/null +++ b/kerberosIV/ss/ss_err.et @@ -0,0 +1,39 @@ + error_table ss + +ec SS_ET_SUBSYSTEM_ABORTED, + "Subsystem aborted" + +ec SS_ET_VERSION_MISMATCH, + "Version mismatch" + +ec SS_ET_NULL_INV, + "No current invocation" + +ec SS_ET_NO_INFO_DIR, + "No info directory" + +ec SS_ET_COMMAND_NOT_FOUND, + "Command not found" + +ec SS_ET_LINE_ABORTED, + "Command line aborted" + +ec SS_ET_EOF, + "End-of-file reached" + +ec SS_ET_PERMISSION_DENIED, + "Permission denied" + +ec SS_ET_TABLE_NOT_FOUND, + "Request table not found" + +ec SS_ET_NO_HELP_FILE, + "No info available" + +ec SS_ET_ESCAPE_DISABLED, + "Shell escapes are disabled" + +ec SS_ET_UNIMPLEMENTED, + "Sorry, this request is not yet implemented" + + end diff --git a/kerberosIV/ss/ss_internal.h b/kerberosIV/ss/ss_internal.h new file mode 100644 index 00000000000..2c9e915e8a8 --- /dev/null +++ b/kerberosIV/ss/ss_internal.h @@ -0,0 +1,130 @@ +/* $Id: ss_internal.h,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */ + +/*- + * Copyright 1987, 1988 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * M.I.T. and the M.I.T. S.I.P.B. make no representations about + * the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + */ + +#ifndef _ss_ss_internal_h +#define _ss_ss_internal_h __FILE__ +#include +#include + +#ifdef __STDC__ + +#define PROTOTYPE(p) p +typedef void * pointer; + +#else + +#define const +#define volatile +#define PROTOTYPE(p) () +typedef char * pointer; + +#endif /* not __STDC__ */ + +#include + +#if defined(__GNUC__) +#define LOCAL_ALLOC(x) __builtin_alloca(x) +#define LOCAL_FREE(x) +#else +#if defined(vax) +#define LOCAL_ALLOC(x) alloca(x) +#define LOCAL_FREE(x) +extern pointer alloca PROTOTYPE((unsigned)); +#else +#if defined(__HIGHC__) /* Barf! */ +pragma on(alloca); +#define LOCAL_ALLOC(x) alloca(x) +#define LOCAL_FREE(x) +extern pointer alloca PROTOTYPE((unsigned)); +#else +/* no alloca? */ +#define LOCAL_ALLOC(x) malloc(x) +#define LOCAL_FREE(x) free(x) +#endif +#endif +#endif /* LOCAL_ALLOC stuff */ + +typedef char BOOL; + +typedef struct _ss_abbrev_entry { + char *name; /* abbrev name */ + char **abbrev; /* new tokens to insert */ + int beginning_of_line : 1; +} ss_abbrev_entry; + +typedef struct _ss_abbrev_list { + int n_abbrevs; + ss_abbrev_entry *first_abbrev; +} ss_abbrev_list; + +typedef struct { +/* char *path; */ + ss_abbrev_list abbrevs[127]; +} ss_abbrev_info; + +typedef struct _ss_data { /* init values */ + /* this subsystem */ + char *subsystem_name; + char *subsystem_version; + /* current request info */ + int argc; + char **argv; /* arg list */ + char const *current_request; /* primary name */ + /* info directory for 'help' */ + char **info_dirs; + /* to be extracted by subroutines */ + pointer info_ptr; /* (void *) NULL */ + /* for ss_listen processing */ + char *prompt; + ss_request_table **rqt_tables; + ss_abbrev_info *abbrev_info; + struct { + int escape_disabled : 1, + abbrevs_disabled : 1; + } flags; + /* to get out */ + int abort; /* exit subsystem */ + int exit_status; +} ss_data; + +#define CURRENT_SS_VERSION 1 + +#define ss_info(sci_idx) (_ss_table[sci_idx]) +#define ss_current_request(sci_idx,code_ptr) \ + (*code_ptr=0,ss_info(sci_idx)->current_request) +void ss_unknown_function(); +void ss_delete_info_dir(); +int ss_execute_line(); +char **ss_parse(); +ss_abbrev_info *ss_abbrev_initialize PROTOTYPE((char *, int *)); +void ss_page_stdin(); + +extern ss_data **_ss_table; +extern char *ss_et_msgs[]; + +#if 0 +extern pointer malloc PROTOTYPE((unsigned)); +extern pointer realloc PROTOTYPE((pointer, unsigned)); +extern pointer calloc PROTOTYPE((unsigned, unsigned)); +#ifndef sun +extern int exit PROTOTYPE((int)); +#endif +#endif /* 0 */ + +#endif /* _ss_internal_h */ diff --git a/kerberosIV/ss/std_rqs.ct b/kerberosIV/ss/std_rqs.ct new file mode 100644 index 00000000000..500288a02ed --- /dev/null +++ b/kerberosIV/ss/std_rqs.ct @@ -0,0 +1,46 @@ + command_table ss_std_requests; + + request ss_self_identify, "Identify the subsystem.", + ".", + (dont_list, dont_summarize); + + request ss_help, "Display info on command or topic.", + help; + + unimplemented + ss_list_help, + "List topics for which help is available.", + list_help, lh; + + request ss_list_requests, "List available commands.", + list_requests, lr, "?"; + + request ss_quit, "Leave the subsystem.", + quit, q; + + unimplemented + ss_abbrev, + "Enable/disable abbreviation processing of request lines.", + abbrev, ab; + + unimplemented + ss_execute, + "Execute a UNIX command line.", + execute, e; + + unimplemented + ss_summarize_requests, + "Produce a list of the most commonly used requests.", + "?"; + + request ss_subsystem_name, + "Return the name of this subsystem.", + subsystem_name, + (dont_list); + + request ss_subsystem_version, + "Return the version of this subsystem.", + subsystem_version, + (dont_list); + + end;