diff options
author | markm <markm@FreeBSD.org> | 1997-09-04 06:04:33 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 1997-09-04 06:04:33 +0000 |
commit | a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8 (patch) | |
tree | 0b84977f19022a965f8c6145f067f951173f6290 /crypto/kerberosIV/lib/kdb | |
download | FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.zip FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.tar.gz |
Initial import of KTH eBones. This has been cleaned up to only include
the "core" Kerberos functionality. The rest of the userland will get their
own changes later.
Diffstat (limited to 'crypto/kerberosIV/lib/kdb')
-rw-r--r-- | crypto/kerberosIV/lib/kdb/Makefile.in | 83 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/base64.c | 150 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/base64.h | 47 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/copykey.c | 55 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/kdb_locl.h | 98 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/kdc.h | 34 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/krb_cache.c | 189 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/krb_db.h | 137 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/krb_dbm.c | 823 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/krb_kdb_utils.c | 261 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/krb_lib.c | 259 | ||||
-rw-r--r-- | crypto/kerberosIV/lib/kdb/print_princ.c | 48 |
12 files changed, 2184 insertions, 0 deletions
diff --git a/crypto/kerberosIV/lib/kdb/Makefile.in b/crypto/kerberosIV/lib/kdb/Makefile.in new file mode 100644 index 0000000..f6fb962 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/Makefile.in @@ -0,0 +1,83 @@ +# +# $Id: Makefile.in,v 1.25 1997/05/06 03:47:39 assar Exp $ +# + +SHELL = /bin/sh + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +AR = ar +RANLIB = @RANLIB@ +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @top_srcdir@/mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ + +PICFLAGS = @PICFLAGS@ + +LIBNAME = $(LIBPREFIX)kdb +LIBEXT = @LIBEXT@ +SHLIBEXT = @SHLIBEXT@ +LIBPREFIX = @LIBPREFIX@ +LDSHARED = @LDSHARED@ +LIB = $(LIBNAME).$(LIBEXT) + +SOURCES = krb_cache.c krb_kdb_utils.c copykey.c krb_lib.c krb_dbm.c print_princ.c base64.c + +OBJECTS = krb_cache.o krb_kdb_utils.o copykey.o krb_lib.o krb_dbm.o print_princ.o base64.o + +all: $(LIB) + +Wall: + make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__" + +.c.o: + $(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $(PICFLAGS) $< + +install: all + $(MKINSTALLDIRS) $(libdir) + $(INSTALL_DATA) -m 0555 $(LIB) $(libdir) + +uninstall: + rm -f $(libdir)/$(LIB) + +TAGS: $(SOURCES) + etags $(SOURCES) + +check: + +clean: + rm -f $(LIB) *.o *.a + +mostlyclean: clean + +distclean: clean + rm -f Makefile *.tab.c *~ + +realclean: distclean + rm -f TAGS + +dist: $(DISTFILES) + for file in $(DISTFILES); do \ + ln $$file ../`cat ../.fname`/lib \ + || cp -p $$file ../`cat ../.fname`/lib; \ + done + +$(LIBNAME).a: $(OBJECTS) + rm -f $@ + $(AR) cr $@ $(OBJECTS) + -$(RANLIB) $@ + +$(LIBNAME).$(SHLIBEXT): $(OBJECTS) + rm -f $@ + $(LDSHARED) -o $@ $(OBJECTS) + +$(OBJECTS): ../../include/config.h diff --git a/crypto/kerberosIV/lib/kdb/base64.c b/crypto/kerberosIV/lib/kdb/base64.c new file mode 100644 index 0000000..d7e89c4 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/base64.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$Id: base64.c,v 1.7 1997/04/01 08:18:16 joda Exp $"); +#endif + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include "base64.h" + +static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static int POS(char c) +{ + if(c == '=') return 64; + if(isupper(c)) + return c - 'A'; + if(islower(c)) + return c - 'a' + 26; + if(isdigit(c)) + return c - '0' + 52; + if(c == '+') + return 62; + if(c == '/') + return 63; + return -1; +} + +char *base64_encode(const void *buf, int size) +{ + char *str = (char*)malloc((size+3)*4/3+1); + char *p=str; + unsigned char *q = (unsigned char*)buf; + int i; + int c; + i=0; + while(i<size){ + c=q[i++]; + c*=256; + if(i<size) + c+=q[i]; + i++; + c*=256; + if(i<size) + c+=q[i]; + i++; + p[0]=base64[(c&0x00fc0000) >> 18]; + p[1]=base64[(c&0x0003f000) >> 12]; + p[2]=base64[(c&0x00000fc0) >> 6]; + p[3]=base64[(c&0x0000003f) >> 0]; + if(i>size) + p[3]='='; + if(i>size+1) + p[2]='='; + p+=4; + } + *p=0; + return str; +} + +/* convert string in s to binary data. s should be a multiple of 4 + * bytes long. data should be at least len(s) * 3 / 4 bytes long. + * returns + */ +int base64_decode(char *s, void *data) +{ + char *p; + unsigned char *q; + int n[4]; + + if(strlen(s) % 4) + return -1; + q=(unsigned char*)data; + for(p=s; *p; p+=4){ + n[0] = POS(p[0]); + n[1] = POS(p[1]); + n[2] = POS(p[2]); + n[3] = POS(p[3]); + if((n[0] | n[1] | n[2] | n[3]) < 0) + return -1; + + if(n[0] == 64 || n[1] == 64) + return -1; + if(n[2] == 64 && n[3] < 64) + return -1; + q[0] = (n[0] << 2) + (n[1] >> 4); + if(n[2] < 64){ + q[1] = ((n[1] & 15) << 4) + (n[2] >> 2); + } + if(n[3] < 64){ + q[2] = ((n[2] & 3) << 6) + n[3]; + } + q+=3; + } + q -= (n[2] == 64) + (n[3] == 64); + return q - (unsigned char*)data; +} + +#ifdef TEST +int main(int argc, char **argv) +{ + char str[128]; + char buf[128]; + char *p; + printf("base64_encode(\"%s\") = \"%s\"\n", argv[1], + p=base64_encode(argv[1], strlen(argv[1]))); + printf("base64_decode(\"%s\") = %d", p, base64_decode(p, buf)); + printf(" (\"%s\")\n", buf); + printf("base64_decode(\"%s\") = %d", argv[1], base64_decode(argv[1], buf)); + printf(" (\"%s\")\n", buf); +} +#endif diff --git a/crypto/kerberosIV/lib/kdb/base64.h b/crypto/kerberosIV/lib/kdb/base64.h new file mode 100644 index 0000000..edfb344 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/base64.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/* $Id: base64.h,v 1.5 1997/04/01 08:18:16 joda Exp $ */ + +#ifndef _BASE64_H_ +#define _BASE64_H_ + +char *base64_encode(const void *buf, int size); +int base64_decode(char *s, void *data); + +#endif diff --git a/crypto/kerberosIV/lib/kdb/copykey.c b/crypto/kerberosIV/lib/kdb/copykey.c new file mode 100644 index 0000000..a78baf7 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/copykey.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#include "kdb_locl.h" + +RCSID("$Id: copykey.c,v 1.10 1997/04/01 08:18:17 joda Exp $"); + +void +copy_from_key(des_cblock in, u_int32_t *lo, u_int32_t *hi) +{ + memcpy(lo, ((char *) in) + 0, 4); + memcpy(hi, ((char *) in) + 4, 4); +} + +void +copy_to_key(u_int32_t *lo, u_int32_t *hi, des_cblock out) +{ + memcpy(((char *)out) + 0, lo, 4); + memcpy(((char *)out) + 4, hi, 4); +} diff --git a/crypto/kerberosIV/lib/kdb/kdb_locl.h b/crypto/kerberosIV/lib/kdb/kdb_locl.h new file mode 100644 index 0000000..fe4d079 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/kdb_locl.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/* $Id: kdb_locl.h,v 1.9 1997/05/02 14:29:08 assar Exp $ */ + +#ifndef __kdb_locl_h +#define __kdb_locl_h + +#include "config.h" +#include "protos.h" + +#include "base64.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <unistd.h> +#include <errno.h> + +#include <sys/types.h> + +#ifdef TIME_WITH_SYS_TIME +#include <sys/time.h> +#include <time.h> +#elif defined(HAVE_SYS_TIME_H) +#include <sys/time.h> +#else +#include <time.h> +#endif + +#include <sys/stat.h> +#include <fcntl.h> +#include <utime.h> +#include <sys/file.h> +#include <roken.h> + +#include <krb.h> +#include <krb_db.h> + +/* --- */ + +/* Globals! */ + +/* Utils */ + +int kerb_db_set_lockmode __P((int)); +void kerb_db_fini __P((void)); +int kerb_db_init __P((void)); +int kerb_db_get_principal __P((char *name, char *, Principal *, unsigned int, int *)); +int kerb_db_get_dba __P((char *, char *, Dba *, unsigned int, int *)); + +void delta_stat __P((DB_stat *, DB_stat *, DB_stat *)); + +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/crypto/kerberosIV/lib/kdb/kdc.h b/crypto/kerberosIV/lib/kdb/kdc.h new file mode 100644 index 0000000..f404d11 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/kdc.h @@ -0,0 +1,34 @@ +/* + * $Id: kdc.h,v 1.8 1997/04/01 03:59:05 assar Exp $ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Include file for the Kerberos Key Distribution Center. + */ + +#ifndef KDC_DEFS +#define KDC_DEFS + +/* Don't depend on this! */ +#ifndef MKEYFILE +#if 0 +#define MKEYFILE "/var/kerberos/master-key" +#else +#define MKEYFILE "/.k" +#endif +#endif +#ifndef K_LOGFIL +#define K_LOGFIL "/var/log/kpropd.log" +#endif + +#define ONE_MINUTE 60 +#define FIVE_MINUTES (5 * ONE_MINUTE) +#define ONE_HOUR (60 * ONE_MINUTE) +#define ONE_DAY (24 * ONE_HOUR) +#define THREE_DAYS (3 * ONE_DAY) + +#endif /* KDC_DEFS */ + diff --git a/crypto/kerberosIV/lib/kdb/krb_cache.c b/crypto/kerberosIV/lib/kdb/krb_cache.c new file mode 100644 index 0000000..ed4a5b1 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/krb_cache.c @@ -0,0 +1,189 @@ +/* + 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" + +RCSID("$Id: krb_cache.c,v 1.6 1997/05/02 10:27:53 joda Exp $"); + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +#endif +static int init = 0; + +/* + * initialization routine for cache + */ + +int +kerb_cache_init(void) +{ + init = 1; + return (0); +} + +/* + * look up a principal in the cache returns number of principals found + */ + +int +kerb_cache_get_principal(char *serv, char *inst, Principal *principal, unsigned int max) + /* could have wild card */ + /* could have wild card */ + + /* 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 *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(char *serv, char *inst, Dba *dba, unsigned int max) + /* could have wild card */ + /* could have wild card */ + + /* 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 *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/crypto/kerberosIV/lib/kdb/krb_db.h b/crypto/kerberosIV/lib/kdb/krb_db.h new file mode 100644 index 0000000..1a08b83 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/krb_db.h @@ -0,0 +1,137 @@ +/* + * $Id: krb_db.h,v 1.15 1996/12/17 20:34:32 assar Exp $ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * 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 + +#include <stdio.h> + +#define KERB_M_NAME "K" /* Kerberos */ +#define KERB_M_INST "M" /* Master */ +#define KERB_DEFAULT_NAME "default" +#define KERB_DEFAULT_INST "" +#ifndef DB_DIR +#define DB_DIR "/var/kerberos" +#endif +#ifndef DBM_FILE +#define DBM_FILE DB_DIR "/principal" +#endif + +/* 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 + +/* arguments to kdb_get_master_key */ + +#define KDB_GET_PROMPT 1 +#define KDB_GET_TWICE 2 + +/* 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; + +typedef int (*k_iter_proc_t)(void*, Principal*); + +void copy_from_key __P((des_cblock in, u_int32_t *lo, u_int32_t *hi)); +void copy_to_key __P((u_int32_t *lo, u_int32_t *hi, des_cblock out)); + +void kdb_encrypt_key __P((des_cblock *, des_cblock *, des_cblock *, + des_key_schedule, int)); +int kdb_get_master_key __P((int prompt, des_cblock *master_key, + des_key_schedule master_key_sched)); +int kdb_get_new_master_key __P((des_cblock *, des_key_schedule, int)); +int kdb_kstash __P((des_cblock *, char *)); +int kdb_new_get_master_key __P((des_cblock *, des_key_schedule)); +int kdb_new_get_new_master_key __P((des_cblock *key, des_key_schedule schedule, int verify)); +long kdb_verify_master_key __P((des_cblock *, des_key_schedule, FILE *)); +long *kerb_db_begin_update __P((void)); +int kerb_db_create __P((char *db_name)); +int kerb_db_delete_principal (char *name, char *inst); +void kerb_db_end_update __P((long *db)); +int kerb_db_get_dba __P((char *, char *, Dba *, unsigned, int *)); +void kerb_db_get_stat __P((DB_stat *)); +int kerb_db_iterate __P((k_iter_proc_t, void*)); +int kerb_db_put_principal __P((Principal *, unsigned int)); +void kerb_db_put_stat __P((DB_stat *)); +int kerb_db_rename __P((char *, char *)); +int kerb_db_set_lockmode __P((int)); +int kerb_db_set_name __P((char *)); +int kerb_db_update __P((long *db, Principal *principal, unsigned int max)); +int kerb_delete_principal __P((char *name, char *inst)); +void kerb_fini __P((void)); +int kerb_get_dba __P((char *, char *, Dba *, unsigned int, int *)); +time_t kerb_get_db_age __P((void)); +int kerb_get_principal __P((char *, char *, Principal *, unsigned int, int *)); +int kerb_init __P((void)); +int kerb_put_principal __P((Principal *, unsigned int)); + +#endif /* KRB_DB_DEFS */ diff --git a/crypto/kerberosIV/lib/kdb/krb_dbm.c b/crypto/kerberosIV/lib/kdb/krb_dbm.c new file mode 100644 index 0000000..963656a --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/krb_dbm.c @@ -0,0 +1,823 @@ +/* + 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" + +RCSID("$Id: krb_dbm.c,v 1.27 1997/05/02 14:29:09 assar Exp $"); + +#include <xdbm.h> + +#define KERB_DB_MAX_RETRY 5 + +#ifdef DEBUG +extern int debug; +extern long kerb_debug; +extern char *progname; +#endif + +static int 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. + */ + + +/* + * Utility routine: generate name of database file. + */ + +static char *gen_dbsuffix (char *db_name, char *sfx); + +static char * +gen_dbsuffix(char *db_name, char *sfx) +{ + char *dbsuffix; + + if (sfx == NULL) + sfx = ".ok"; + + asprintf (&dbsuffix, "%s%s", db_name, sfx); + return dbsuffix; +} + +static void +decode_princ_key (datum *key, char *name, char *instance); + +static void +decode_princ_key(datum *key, char *name, char *instance) +{ + strncpy(name, key->dptr, ANAME_SZ); + strncpy(instance, (char *)key->dptr + ANAME_SZ, INST_SZ); + name[ANAME_SZ - 1] = '\0'; + instance[INST_SZ - 1] = '\0'; +} + +static void +encode_princ_contents (datum *contents, Principal *principal); + +static void +encode_princ_contents(datum *contents, Principal *principal) +{ + contents->dsize = sizeof(*principal); + contents->dptr = (char *) principal; +} + +static void +decode_princ_contents (datum *contents, Principal *principal) +{ + memcpy(principal, contents->dptr, sizeof(*principal)); +} + +static void +encode_princ_key (datum *key, char *name, char *instance) +{ + static char keystring[ANAME_SZ + INST_SZ]; + + memset(keystring, 0, 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 (void); + +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 (void); + +static void +kerb_dbl_fini() +{ + close(dblfd); + dblfd = -1; + inited = 0; + mylock = 0; +} + +static int +kerb_dbl_lock (int mode); + +static int +kerb_dbl_lock(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 = K_LOCK_EX; + break; + case KERB_DBL_SHARED: + flock_mode = K_LOCK_SH; + break; + default: + fprintf(stderr, "invalid lock mode %d\n", mode); + abort(); + } + if (non_blocking) + flock_mode |= K_LOCK_NB; + + if (k_flock(dblfd, flock_mode) < 0) + return errno; + mylock++; + return 0; +} + +static void kerb_dbl_unlock (void); + +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 (k_flock(dblfd, K_LOCK_UN) < 0) { + fprintf(stderr, "Kerberos database lock error. (unlocking)\n"); + fflush(stderr); + perror("k_flock"); + exit(1); + } + mylock = 0; +} + +int +kerb_db_set_lockmode (int mode); + +int +kerb_db_set_lockmode(int mode) +{ + int old = non_blocking; + non_blocking = mode; + return old; +} + +/* + * initialization for data base routines. + */ + +int +kerb_db_init (void); + +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 (void); + +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 (char *name); + +int +kerb_db_set_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 (void); + +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 (char *db_name); + +static time_t +kerb_start_update(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 (char *db_name, time_t age); + +static int +kerb_end_update(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 (void); + +static time_t +kerb_start_read() +{ + return kerb_get_db_age(); +} + +static int kerb_end_read (time_t age); + +static int +kerb_end_read(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(char *db_name) +{ + char *okname = gen_dbsuffix(db_name, ".ok"); + int fd; + int ret = 0; +#ifdef NDBM + DBM *db; + + db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (db == NULL) + ret = errno; + else + dbm_close(db); +#else + char *dirname = gen_dbsuffix(db_name, ".dir"); + char *pagname = gen_dbsuffix(db_name, ".pag"); + + fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else { + close(fd); + fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd < 0) + ret = errno; + else + close(fd); + } + if (dbminit(db_name) < 0) + ret = errno; +#endif + if (ret == 0) { + fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + ret = errno; + close(fd); + } + return ret; +} + +/* + * "Atomically" rename the database in a way that locks out read + * access in the middle of the rename. + * + * Not perfect; if we crash in the middle of an update, we don't + * necessarily know to complete the transaction the rename, but... + */ + +int +kerb_db_rename(char *from, char *to) +{ +#ifdef HAVE_NEW_DB + char *fromdb = gen_dbsuffix (from, ".db"); + char *todb = gen_dbsuffix (to, ".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; + +#ifdef HAVE_NEW_DB + if (rename (fromdb, todb) == 0) { + unlink (fromok); + ok = 1; + } + free (fromdb); + free (todb); +#else + if ((rename (fromdir, todir) == 0) + && (rename (frompag, topag) == 0)) { + 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; +} + +int +kerb_db_delete_principal (char *name, char *inst) +{ + DBM *db; + int try; + int done = 0; + int code; + datum key; + + if(!init) + kerb_db_init(); + + for(try = 0; try < KERB_DB_MAX_RETRY; try++){ + if((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0) + return -1; + + db = dbm_open(current_db_name, O_RDWR, 0600); + if(db == NULL) + return -1; + encode_princ_key(&key, name, inst); + if(dbm_delete(db, key) == 0) + done = 1; + + dbm_close(db); + kerb_dbl_unlock(); + if(done) + break; + if(!non_blocking) + sleep(1); + } + if(!done) + return -1; + return 0; +} + + +/* + * 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 (char *name, char *inst, Principal *principal, + unsigned int max, int *more) +{ + int found = 0, code; + 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); +} + +/* Use long * rather than DBM * so that the database structure is private */ + +long * +kerb_db_begin_update(void) +{ + int code; + + gettimeofday(×tamp, NULL); + + if (!init) + kerb_db_init(); + + if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0) + return 0; + + return (long *) dbm_open(current_db_name, O_RDWR, 0600); +} + +void +kerb_db_end_update(long *db) +{ + dbm_close((DBM *)db); + kerb_dbl_unlock(); /* unlock database */ +} + +int +kerb_db_update(long *db, Principal *principal, unsigned int max) +{ + int found = 0; + u_long i; + datum key, contents; + +#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((DBM *)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 */ + } + return found; +} + +/* + * Update a name in the data base. Returns number of names + * successfully updated. + */ + +int +kerb_db_put_principal (Principal *principal, unsigned int max); + +int +kerb_db_put_principal(Principal *principal, + unsigned max) + +{ + int found; + long *db; + + db = kerb_db_begin_update(); + if (db == 0) + return -1; + + found = kerb_db_update(db, principal, max); + + kerb_db_end_update(db); + return (found); +} + +void +kerb_db_get_stat (DB_stat *s); + +void +kerb_db_get_stat(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 (DB_stat *s); + +void +kerb_db_put_stat(DB_stat *s) +{ +} + +void +delta_stat (DB_stat *a, DB_stat *b, DB_stat *c); + +void +delta_stat(DB_stat *a, DB_stat *b, DB_stat *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; + + memcpy(b, a, 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 (char *dba_name, char *dba_inst, Dba *dba, unsigned int max, int *more); + +int +kerb_db_get_dba(char *dba_name, char *dba_inst, Dba *dba, + unsigned max, + int *more) + /* could have wild card */ + /* could have wild card */ + /* max number of name structs to return */ + /* where there more than 'max' tuples? */ +{ + *more = 0; + return (0); +} + +int +kerb_db_iterate (k_iter_proc_t func, void *arg) +{ + 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/crypto/kerberosIV/lib/kdb/krb_kdb_utils.c b/crypto/kerberosIV/lib/kdb/krb_kdb_utils.c new file mode 100644 index 0000000..f321e9f --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/krb_kdb_utils.c @@ -0,0 +1,261 @@ +/* + 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 <kdc.h> + +RCSID("$Id: krb_kdb_utils.c,v 1.23 1997/05/02 14:29:10 assar Exp $"); + +/* always try /.k for backwards compatibility */ +static char *master_key_files[] = { MKEYFILE, "/.k", NULL }; + +#ifdef HAVE_STRERROR +#define k_strerror(e) strerror(e) +#else +static +char * +k_strerror(int eno) +{ + extern int sys_nerr; + extern char *sys_errlist[]; + + static char emsg[128]; + + if (eno < 0 || eno >= sys_nerr) + snprintf(emsg, sizeof(emsg), "Error %d occurred.", eno); + else + return sys_errlist[eno]; + + return emsg; +} +#endif + +int +kdb_new_get_master_key(des_cblock *key, des_key_schedule schedule) +{ + int kfile; + int i; + char buf[1024]; + + char **mkey; + + for(mkey = master_key_files; *mkey; mkey++){ + kfile = open(*mkey, O_RDONLY); + if(kfile < 0 && errno != ENOENT) + fprintf(stderr, "Failed to open master key file \"%s\": %s\n", + *mkey, + k_strerror(errno)); + if(kfile >= 0) + break; + } + if(*mkey){ + int bytes; + bytes = read(kfile, (char*)key, sizeof(des_cblock)); + close(kfile); + if(bytes == sizeof(des_cblock)){ + des_key_sched(key, schedule); + return 0; + } + fprintf(stderr, "Could only read %d bytes from master key file %s\n", + bytes, *mkey); + }else{ + fprintf(stderr, "No master key file found.\n"); + } + + + i=0; + while(i < 3){ + if(des_read_pw_string(buf, sizeof(buf), "Enter master password: ", 0)) + break; + + /* buffer now contains either an old format master key password or a + * new format base64 encoded master key + */ + + /* try to verify as old password */ + des_string_to_key(buf, key); + des_key_sched(key, schedule); + + if(kdb_verify_master_key(key, schedule, NULL) != -1){ + memset(buf, 0, sizeof(buf)); + return 0; + } + + /* failed test, so must be base64 encoded */ + + if(base64_decode(buf, key) == 8){ + des_key_sched(key, schedule); + if(kdb_verify_master_key(key, schedule, NULL) != -1){ + memset(buf, 0, sizeof(buf)); + return 0; + } + } + + memset(buf, 0, sizeof(buf)); + fprintf(stderr, "Failed to verify master key.\n"); + i++; + } + + /* life sucks */ + fprintf(stderr, "You loose.\n"); + exit(1); +} + +int kdb_new_get_new_master_key(des_cblock *key, des_key_schedule schedule, + int verify) +{ +#ifndef RANDOM_MKEY + des_read_password(key, "\nEnter Kerberos master password: ", verify); + printf ("\n"); +#else + char buf[1024]; + des_generate_random_block (key); + des_key_sched(key, schedule); + + des_read_pw_string(buf, sizeof(buf), "Enter master key seed: ", 0); + des_cbc_cksum((des_cblock*)buf, key, sizeof(buf), schedule, key); + memset(buf, 0, sizeof(buf)); +#endif + des_key_sched(key, schedule); + return 0; +} + +int kdb_get_master_key(int prompt, des_cblock *master_key, + des_key_schedule master_key_sched) +{ + int ask = (prompt == KDB_GET_TWICE); +#ifndef RANDOM_MKEY + ask |= (prompt == KDB_GET_PROMPT); +#endif + + if(ask) + kdb_new_get_new_master_key(master_key, master_key_sched, + prompt == KDB_GET_TWICE); + else + kdb_new_get_master_key(master_key, master_key_sched); + return 0; +} + +int kdb_kstash(des_cblock *master_key, char *file) +{ + int kfile; + kfile = open(file, O_TRUNC | O_RDWR | O_CREAT, 0600); + if (kfile < 0) { + return -1; + } + if (write(kfile, master_key, sizeof(des_cblock)) != sizeof(des_cblock)) { + close(kfile); + return -1; + } + close(kfile); + return 0; +} + +/* The old algorithm used the key schedule as the initial vector which + was byte order depedent ... */ + +void +kdb_encrypt_key (des_cblock (*in), des_cblock (*out), + des_cblock (*master_key), + des_key_schedule master_key_sched, int e_d_flag) +{ + +#ifdef NOENCRYPTION + memcpy(out, in, 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 (des_cblock *master_key, + des_key_schedule master_key_sched, + FILE *out) /* NULL -> no 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! + */ + copy_to_key(&principal_data[0].key_low, + &principal_data[0].key_high, + key_from_db); + 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 = memcmp(master_key, key_from_db, sizeof(master_key)); + /* this used to zero the master key here! */ + memset(key_from_db, 0, sizeof(key_from_db)); + memset(principal_data, 0, 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"); + } + if(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/crypto/kerberosIV/lib/kdb/krb_lib.c b/crypto/kerberosIV/lib/kdb/krb_lib.c new file mode 100644 index 0000000..19bf316 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/krb_lib.c @@ -0,0 +1,259 @@ +/* + 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" + +RCSID("$Id: krb_lib.c,v 1.11 1997/05/07 01:36:08 assar Exp $"); + +#ifdef DEBUG +extern int debug; +extern char *progname; +long kerb_debug; +#endif + +static int init = 0; + +/* + * initialization routine for data base + */ + +int +kerb_init(void) +{ +#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(void) +{ + kerb_db_fini(); +} + + +int +kerb_delete_principal(char *name, char *inst) +{ + int ret; + + if (!init) + kerb_init(); + + ret = kerb_db_delete_principal(name, inst); +#ifdef CACHE + if(ret == 0){ + kerb_cache_delete_principal(name, inst); + } +#endif + return ret; +} + + +/* + * look up a principal in the cache or data base returns number of + * principals found + */ + +int +kerb_get_principal(char *name, char *inst, Principal *principal, + unsigned int max, int *more) + /* could have wild card */ + /* could have wild card */ + + /* max number of name structs to return */ + /* 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 */ + memset(principal, 0, 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 *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); + snprintf(principal->mod_date_txt, + sizeof(principal->mod_date_txt), + "%4d-%2d-%2d", + 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(char *name, char *inst, Dba *dba, unsigned int max, int *more) + /* could have wild card */ + /* could have wild card */ + + /* max number of name structs to return */ + /* 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 */ + memset(dba, 0, 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/crypto/kerberosIV/lib/kdb/print_princ.c b/crypto/kerberosIV/lib/kdb/print_princ.c new file mode 100644 index 0000000..786c5a9 --- /dev/null +++ b/crypto/kerberosIV/lib/kdb/print_princ.c @@ -0,0 +1,48 @@ +/* + 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" + +RCSID("$Id: print_princ.c,v 1.5 1997/05/07 01:37:13 assar Exp $"); + +void +krb_print_principal(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_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); +} |