diff options
Diffstat (limited to 'eBones/usr.sbin')
29 files changed, 3413 insertions, 0 deletions
diff --git a/eBones/usr.sbin/ext_srvtab/Makefile b/eBones/usr.sbin/ext_srvtab/Makefile new file mode 100644 index 0000000..f30bbbb --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:22:34 g89r4222 Exp $ + +PROG= ext_srvtab +CFLAGS+=-DKERBEROS -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD+= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 new file mode 100644 index 0000000..af980a9 --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 @@ -0,0 +1,63 @@ +.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $ +.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ext_srvtab \- extract service key files from Kerberos key distribution center database +.SH SYNOPSIS +ext_srvtab [ +.B \-n +] [ +.B \-r realm +] [ +.B hostname ... +] +.SH DESCRIPTION +.I ext_srvtab +extracts service key files from the Kerberos key distribution center +(KDC) database. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +For each +.I hostname +specified on the command line, +.I ext_srvtab +creates the service key file +.IR hostname -new-srvtab, +containing all the entries in the database with an instance field of +.I hostname. +This new file contains all the keys registered for Kerberos-mediated +service providing programs which use the +.IR krb_get_phost (3) +principal and instance conventions to run on the host +.IR hostname . +If the +.B \-r +option is specified, the realm fields in the extracted file will +match the given realm rather than the local realm. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +.IR hostname -new-srvtab +Service key file generated for +.I hostname +.TP +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. +.SH SEE ALSO +read_service_key(3), krb_get_phost(3) diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.c b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c new file mode 100644 index 0000000..3a5dcec --- /dev/null +++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c @@ -0,0 +1,164 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $ + * $Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <signal.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> + +#define TRUE 1 +#define FALSE 0 + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +char progname[] = "ext_srvtab"; +char realm[REALM_SZ]; + +main(argc, argv) + int argc; + char *argv[]; +{ + FILE *fout; + char fname[1024]; + int fopen_errs = 0; + int arg; + Principal princs[40]; + int more; + int prompt = TRUE; + register int n, i; + + bzero(realm, sizeof(realm)); + + /* Parse commandline arguments */ + if (argc < 2) + usage(); + else { + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-n") == 0) + prompt = FALSE; + else if (strcmp(argv[i], "-r") == 0) { + if (++i >= argc) + usage(); + else { + strcpy(realm, argv[i]); + /* + * This is to humor the broken way commandline + * argument parsing is done. Later, this + * program ignores everything that starts with -. + */ + argv[i][0] = '-'; + } + } + else if (argv[i][0] == '-') + usage(); + else + if (!k_isinst(argv[i])) { + fprintf(stderr, "%s: bad instance name: %s\n", + progname, argv[i]); + usage(); + } + } + } + + if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + fflush (stderr); + exit(1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + exit(1); + } + + /* For each arg, search for instances of arg, and produce */ + /* srvtab file */ + if (!realm[0]) + if (krb_get_lrealm(realm, 1) != KSUCCESS) { + fprintf(stderr, "%s: couldn't get local realm\n", progname); + exit(1); + } + (void) umask(077); + + for (arg = 1; arg < argc; arg++) { + if (argv[arg][0] == '-') + continue; + sprintf(fname, "%s-new-srvtab", argv[arg]); + if ((fout = fopen(fname, "w")) == NULL) { + fprintf(stderr, "Couldn't create file '%s'.\n", fname); + fopen_errs++; + continue; + } + printf("Generating '%s'....\n", fname); + n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more); + if (more) + fprintf(stderr, "More than 40 found...\n"); + for (i = 0; i < n; i++) { + FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout); + FWrite(princs[i].instance, strlen(princs[i].instance) + 1, + 1, fout); + FWrite(realm, strlen(realm) + 1, 1, fout); + FWrite(&princs[i].key_version, + sizeof(princs[i].key_version), 1, fout); + bcopy(&princs[i].key_low, session_key, sizeof(long)); + bcopy(&princs[i].key_high, session_key + sizeof(long), + sizeof(long)); + kdb_encrypt_key (session_key, session_key, + master_key, master_key_schedule, DES_DECRYPT); + FWrite(session_key, sizeof session_key, 1, fout); + } + fclose(fout); + } + + StampOutSecrets(); + + exit(fopen_errs); /* 0 errors if successful */ + +} + +Die() +{ + StampOutSecrets(); + exit(1); +} + +FWrite(p, size, n, f) + char *p; + int size; + int n; + FILE *f; +{ + if (fwrite(p, size, n, f) != n) { + printf("Error writing output file. Terminating.\n"); + Die(); + } +} + +StampOutSecrets() +{ + bzero(master_key, sizeof master_key); + bzero(session_key, sizeof session_key); + bzero(master_key_schedule, sizeof master_key_schedule); +} + +usage() +{ + fprintf(stderr, + "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname); + exit(1); +} diff --git a/eBones/usr.sbin/kadmin/kadmind.8 b/eBones/usr.sbin/kadmin/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/usr.sbin/kadmin/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/usr.sbin/kadmind/kadmind.8 b/eBones/usr.sbin/kadmind/kadmind.8 new file mode 100644 index 0000000..59075ee --- /dev/null +++ b/eBones/usr.sbin/kadmind/kadmind.8 @@ -0,0 +1,117 @@ +.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $ +.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kadmind \- network daemon for Kerberos database administration +.SH SYNOPSIS +.B kadmind +[ +.B \-n +] [ +.B \-h +] [ +.B \-r realm +] [ +.B \-f filename +] [ +.B \-d dbname +] [ +.B \-a acldir +] +.SH DESCRIPTION +.I kadmind +is the network database server for the Kerberos password-changing and +administration tools. +.PP +Upon execution, it prompts the user to enter the master key string for +the database. +.PP +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +If the +.B \-r +.I realm +option is specified, the admin server will pretend that its +local realm is +.I realm +instead of the actual local realm of the host it is running on. +This makes it possible to run a server for a foreign kerberos +realm. +.PP +If the +.B \-f +.I filename +option is specified, then that file is used to hold the log information +instead of the default. +.PP +If the +.B \-d +.I dbname +option is specified, then that file is used as the database name instead +of the default. +.PP +If the +.B \-a +.I acldir +option is specified, then +.I acldir +is used as the directory in which to search for access control lists +instead of the default. +.PP +If the +.B \-h +option is specified, +.I kadmind +prints out a short summary of the permissible control arguments, and +then exits. +.PP +When performing requests on behalf of clients, +.I kadmind +checks access control lists (ACLs) to determine the authorization of the client +to perform the requested action. +Currently three distinct access types are supported: +.TP 1i +Addition +(.add ACL file). If a principal is on this list, it may add new +principals to the database. +.TP +Retrieval +(.get ACL file). If a principal is on this list, it may retrieve +database entries. NOTE: A principal's private key is never returned by +the get functions. +.TP +Modification +(.mod ACL file). If a principal is on this list, it may modify entries +in the database. +.PP +A principal is always granted authorization to change its own password. +.SH FILES +.TP 20n +/kerberos/admin_server.syslog +Default log file. +.TP +/kerberos +Default access control list directory. +.TP +admin_acl.{add,get,mod} +Access control list files (within the directory) +.TP +/kerberos/principal.pag, /kerberos/principal.dir +Default DBM files containing database +.TP +/.k +Master key cache file. +.SH "SEE ALSO" +kerberos(1), kpasswd(1), kadmin(8), acl_check(3) +.SH AUTHORS +Douglas A. Church, MIT Project Athena +.br +John T. Kohl, Project Athena/Digital Equipment Corporation diff --git a/eBones/usr.sbin/kdb_destroy/Makefile b/eBones/usr.sbin/kdb_destroy/Makefile new file mode 100644 index 0000000..a48805b --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/Makefile @@ -0,0 +1,8 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:23:46 g89r4222 Exp $ + +PROG= kdb_destroy +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 new file mode 100644 index 0000000..93db466 --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 @@ -0,0 +1,33 @@ +.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $ +.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_destroy \- destroy Kerberos key distribution center database +.SH SYNOPSIS +kdb_destroy +.SH DESCRIPTION +.I kdb_destroy +deletes a Kerberos key distribution center database. +.PP +The user is prompted to verify that the database should be destroyed. A +response beginning with `y' or `Y' confirms deletion. +Any other response aborts deletion. +.SH DIAGNOSTICS +.TP 20n +"Database cannot be deleted at /kerberos/principal" +The attempt to delete the database failed (probably due to a system or +access permission error). +.TP +"Database not deleted." +The user aborted the deletion. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.SH SEE ALSO +kdb_init(8) diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.c b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c new file mode 100644 index 0000000..0c45896 --- /dev/null +++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c @@ -0,0 +1,45 @@ +/* + * Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $ + * $Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $"; +#endif lint + +#include <strings.h> +#include <stdio.h> +#include "krb.h" +#include "krb_db.h" + +main() +{ + char answer[10]; /* user input */ + char dbm[256]; /* database path and name */ + char dbm1[256]; /* database path and name */ + char *file1, *file2; /* database file names */ + + strcpy(dbm, DBM_FILE); + strcpy(dbm1, DBM_FILE); + file1 = strcat(dbm, ".dir"); + file2 = strcat(dbm1, ".pag"); + + printf("You are about to destroy the Kerberos database "); + printf("on this machine.\n"); + printf("Are you sure you want to do this (y/n)? "); + fgets(answer, sizeof(answer), stdin); + + if (answer[0] == 'y' || answer[0] == 'Y') { + if (unlink(file1) == 0 && unlink(file2) == 0) + fprintf(stderr, "Database deleted at %s\n", DBM_FILE); + else + fprintf(stderr, "Database cannot be deleted at %s\n", + DBM_FILE); + } else + fprintf(stderr, "Database not deleted.\n"); +} diff --git a/eBones/usr.sbin/kdb_edit/Makefile b/eBones/usr.sbin/kdb_edit/Makefile new file mode 100644 index 0000000..65a5e5a --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/Makefile @@ -0,0 +1,12 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $ + +PROG= kdb_edit +CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include +SRCS= kdb_edit.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.8 b/eBones/usr.sbin/kdb_edit/kdb_edit.8 new file mode 100644 index 0000000..1cfd6ed --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/kdb_edit.8 @@ -0,0 +1,55 @@ +.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $ +.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_edit \- Kerberos key distribution center database editing utility +.SH SYNOPSIS +kdb_edit [ +.B \-n +] +.SH DESCRIPTION +.I kdb_edit +is used to create or change principals stored in the Kerberos key +distribution center (KDC) database. +.PP +When executed, +.I kdb_edit +prompts for the master key string and verifies that it matches the +master key stored in the database. +If the +.B \-n +option is specified, the master key is instead fetched from the master +key cache file. +.PP +Once the master key has been verified, +.I kdb_edit +begins a prompt loop. The user is prompted for the principal and +instance to be modified. If the entry is not found the user may create +it. +Once an entry is found or created, the user may set the password, +expiration date, maximum ticket lifetime, and attributes. +Default expiration dates, maximum ticket lifetimes, and attributes are +presented in brackets; if the user presses return the default is selected. +There is no default password. +The password RANDOM is interpreted specially, and if entered +the user may have the program select a random DES key for the +principal. +.PP +Upon successfully creating or changing the entry, ``Edit O.K.'' is +printed. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c new file mode 100644 index 0000000..4c02db6 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c @@ -0,0 +1,470 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * This routine changes the Kerberos encryption keys for principals, + * i.e., users or services. + * + * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $ + * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $ + */ + +/* + * exit returns 0 ==> success -1 ==> error + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#include <strings.h> +#include <sys/ioctl.h> +#include <sys/file.h> +#include "time.h" +#include <des.h> +#include <krb.h> +#include <krb_db.h> +/* MKEYFILE is now defined in kdc.h */ +#include <kdc.h> + +extern char *errmsg(); +extern int errno; +extern char *strcpy(); + +void sig_exit(); + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +char prog[32]; +char *progname = prog; +int nflag = 0; +int cflag; +int lflag; +int uflag; +int debug; +extern kerb_debug; + +Key_schedule KS; +C_Block new_key; +unsigned char *input; + +unsigned char *ivec; +int i, j; +int more; + +char *in_ptr; +char input_name[ANAME_SZ]; +char input_instance[INST_SZ]; +char input_string[ANAME_SZ]; + +#define MAX_PRINCIPAL 10 +Principal principal_data[MAX_PRINCIPAL]; + +static Principal old_principal; +static Principal default_princ; + +static C_Block master_key; +static C_Block session_key; +static Key_schedule master_key_schedule; +static char pw_str[255]; +static long master_key_version; + +/* + * gets replacement + */ +static char * s_gets(char * str, int len) +{ + int i; + char *s; + + if((s = fgets(str, len, stdin)) == NULL) + return(s); + if(str[i = (strlen(str)-1)] == '\n') + str[i] = '\0'; + return(s); +} + +main(argc, argv) + int argc; + char *argv[]; + +{ + /* Local Declarations */ + + long n; + + prog[sizeof prog - 1] = '\0'; /* make sure terminated */ + strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking + * program */ + + /* Assume a long is four bytes */ + if (sizeof(long) != 4) { + fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog); + exit(-1); + } + /* Assume <=32 signals */ + if (NSIG > 32) { + fprintf(stderr, "%s: more than 32 signals defined.\n", prog); + exit(-1); + } + while (--argc > 0 && (*++argv)[0] == '-') + for (i = 1; argv[0][i] != '\0'; i++) { + switch (argv[0][i]) { + + /* debug flag */ + case 'd': + debug = 1; + continue; + + /* debug flag */ + case 'l': + kerb_debug |= 1; + continue; + + case 'n': /* read MKEYFILE for master key */ + nflag = 1; + continue; + + default: + fprintf(stderr, "%s: illegal flag \"%c\"\n", + progname, argv[0][i]); + Usage(); /* Give message and die */ + } + }; + + fprintf(stdout, "Opening database...\n"); + fflush(stdout); + kerb_init(); + if (argc > 0) { + if (kerb_db_set_name(*argv) != 0) { + fprintf(stderr, "Could not open altername database name\n"); + exit(1); + } + } + +#ifdef notdef + no_core_dumps(); /* diddle signals to avoid core dumps! */ + + /* ignore whatever is reasonable */ + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + +#endif + + if (kdb_get_master_key ((nflag == 0), + master_key, master_key_schedule) != 0) { + fprintf (stdout, "Couldn't read master key.\n"); + fflush (stdout); + exit (-1); + } + + if ((master_key_version = kdb_verify_master_key(master_key, + master_key_schedule, + stdout)) < 0) + exit (-1); + + /* lookup the default values */ + n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, + &default_princ, 1, &more); + if (n != 1) { + fprintf(stderr, + "%s: Kerberos error on default value lookup, %d found.\n", + progname, n); + exit(-1); + } + fprintf(stdout, "Previous or default values are in [brackets] ,\n"); + fprintf(stdout, "enter return to leave the same, or new value.\n"); + + while (change_principal()) { + } + + cleanup(); +} + +change_principal() +{ + static char temp[255]; + int creating = 0; + int editpw = 0; + int changed = 0; + long temp_long; + int n; + struct tm *tp, edate, *localtime(); + long maketime(); + + fprintf(stdout, "\nPrincipal name: "); + fflush(stdout); + if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0') + return 0; + fprintf(stdout, "Instance: "); + fflush(stdout); + /* instance can be null */ + s_gets(input_instance, INST_SZ-1); + j = kerb_get_principal(input_name, input_instance, principal_data, + MAX_PRINCIPAL, &more); + if (!j) { + fprintf(stdout, "\n\07\07<Not found>, Create [y] ? "); + s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */ + if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0') + return -1; + /* make a new principal, fill in defaults */ + j = 1; + creating = 1; + strcpy(principal_data[0].name, input_name); + strcpy(principal_data[0].instance, input_instance); + principal_data[0].old = NULL; + principal_data[0].exp_date = default_princ.exp_date; + principal_data[0].max_life = default_princ.max_life; + principal_data[0].attributes = default_princ.attributes; + principal_data[0].kdc_key_ver = (unsigned char) master_key_version; + principal_data[0].key_version = 0; /* bumped up later */ + } + tp = localtime(&principal_data[0].exp_date); + (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d", + tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900, + tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */ + for (i = 0; i < j; i++) { + for (;;) { + fprintf(stdout, + "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d", + principal_data[i].name, principal_data[i].instance, + principal_data[i].kdc_key_ver); + editpw = 1; + changed = 0; + if (!creating) { + /* + * copy the existing data so we can use the old values + * for the qualifier clause of the replace + */ + principal_data[i].old = (char *) &old_principal; + bcopy(&principal_data[i], &old_principal, + sizeof(old_principal)); + printf("\nChange password [n] ? "); + s_gets(temp, sizeof(temp)-1); + if (strcmp("y", temp) && strcmp("Y", temp)) + editpw = 0; + } + /* password */ + if (editpw) { +#ifdef NOENCRYPTION + placebo_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#else + des_read_pw_string(pw_str, sizeof pw_str, + "\nNew Password: ", TRUE); +#endif + if (!strcmp(pw_str, "RANDOM")) { + printf("\nRandom password [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "RANDOM" */ + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + } else if (!strcmp(pw_str, "NULL")) { + printf("\nNull Key [y] ? "); + s_gets(temp, sizeof(temp)-1); + if (!strcmp("n", temp) || !strcmp("N", temp)) { + /* no, use literal */ +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str, new_key); +#endif + bzero(pw_str, sizeof pw_str); /* "NULL" */ + } else { + + principal_data[i].key_low = 0; + principal_data[i].key_high = 0; + goto null_key; + } + } else { +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + string_to_key(pw_str,new_key); +#endif + bzero(pw_str, sizeof pw_str); + } + + /* seal it under the kerberos master key */ + kdb_encrypt_key (new_key, new_key, + master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal_data[i].key_low, 4); + bcopy(((long *) new_key) + 1, + &principal_data[i].key_high, 4); + bzero(new_key, sizeof(new_key)); + null_key: + /* set master key version */ + principal_data[i].kdc_key_ver = + (unsigned char) master_key_version; + /* bump key version # */ + principal_data[i].key_version++; + fprintf(stdout, + "\nPrincipal's new key version = %d\n", + principal_data[i].key_version); + fflush(stdout); + changed = 1; + } + /* expiration date */ + fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) > + sizeof(principal_data[0].exp_date_txt))) { + bad_date: + fprintf(stdout, "\07\07Date Invalid\n"); + fprintf(stdout, + "Expiration date (enter yyyy-mm-dd) [ %s ] ? ", + principal_data[i].exp_date_txt); + zaptime(&edate); + } + + if (*temp) { + if (sscanf(temp, "%d-%d-%d", &edate.tm_year, + &edate.tm_mon, &edate.tm_mday) != 3) + goto bad_date; + (void) strcpy(principal_data[i].exp_date_txt, temp); + edate.tm_mon--; /* January is 0, not 1 */ + edate.tm_hour = 23; /* nearly midnight at the end of the */ + edate.tm_min = 59; /* specified day */ + if (!(principal_data[i].exp_date = maketime(&edate, 1))) + goto bad_date; + changed = 1; + } + + /* maximum lifetime */ + fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_life; + if (temp_long > 255 || (temp_long < 0)) { + bad_life: + fprintf(stdout, "\07\07Invalid, choose 0-255\n"); + fprintf(stdout, + "Max ticket lifetime (*5 minutes) [ %d ] ? ", + principal_data[i].max_life); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].max_life = (unsigned short) temp_long; + break; + } + + /* attributes */ + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + while (s_gets(temp, sizeof(temp)-1) && *temp) { + if (sscanf(temp, "%d", &temp_long) != 1) + goto bad_att; + if (temp_long > 65535 || (temp_long < 0)) { + bad_att: + fprintf(stdout, "\07\07Invalid, choose 0-65535\n"); + fprintf(stdout, "Attributes [ %d ] ? ", + principal_data[i].attributes); + continue; + } + changed = 1; + /* dont clobber */ + principal_data[i].attributes = + (unsigned short) temp_long; + break; + } + + /* + * remaining fields -- key versions and mod info, should + * not be directly manipulated + */ + if (changed) { + if (kerb_put_principal(&principal_data[i], 1)) { + fprintf(stdout, + "\nError updating Kerberos database"); + } else { + fprintf(stdout, "Edit O.K."); + } + } else { + fprintf(stdout, "Unchanged"); + } + + + bzero(&principal_data[i].key_low, 4); + bzero(&principal_data[i].key_high, 4); + fflush(stdout); + break; + } + } + if (more) { + fprintf(stdout, "\nThere were more tuples found "); + fprintf(stdout, "than there were space for"); + } + return 1; +} + + +no_core_dumps() +{ + + signal(SIGQUIT, sig_exit); + signal(SIGILL, sig_exit); + signal(SIGTRAP, sig_exit); + signal(SIGIOT, sig_exit); + signal(SIGEMT, sig_exit); + signal(SIGFPE, sig_exit); + signal(SIGBUS, sig_exit); + signal(SIGSEGV, sig_exit); + signal(SIGSYS, sig_exit); +} + +void +sig_exit(sig, code, scp) + int sig, code; + struct sigcontext *scp; +{ + cleanup(); + fprintf(stderr, + "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting", + sig, code, scp->sc_pc); + exit(-1); +} + + +cleanup() +{ + + bzero(master_key, sizeof(master_key)); + bzero(session_key, sizeof(session_key)); + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(principal_data, sizeof(principal_data)); + bzero(new_key, sizeof(new_key)); + bzero(pw_str, sizeof(pw_str)); +} +Usage() +{ + fprintf(stderr, "Usage: %s [-n]\n", progname); + exit(1); +} diff --git a/eBones/usr.sbin/kdb_edit/maketime.c b/eBones/usr.sbin/kdb_edit/maketime.c new file mode 100644 index 0000000..057ecc3 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/maketime.c @@ -0,0 +1,83 @@ +/* + * Copyright 1990 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Convert a struct tm * to a UNIX time. + * + * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $ + * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp "; +#endif lint + +#include <sys/time.h> + +#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) + +#define SECSPERDAY 24*60*60 +#define SECSPERHOUR 60*60 +#define SECSPERMIN 60 + +static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, + 365}; + +static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +long +maketime(tp, local) +register struct tm *tp; +int local; +{ + register long retval; + int foo; + int *marray; + + if (tp->tm_mon < 0 || tp->tm_mon > 11 || + tp->tm_hour < 0 || tp->tm_hour > 23 || + tp->tm_min < 0 || tp->tm_min > 59 || + tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */ + return 0; + + retval = 0; + if (tp->tm_year < 1900) + foo = tp->tm_year + 1900; + else + foo = tp->tm_year; + + if (foo < 1901 || foo > 2038) /* year is too small/large */ + return 0; + + if (daysinyear(foo) == 366) { + if (tp->tm_mon > 1) + retval+= SECSPERDAY; /* add leap day */ + marray = leapyear; + } else + marray = nonleapyear; + + if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon]) + return 0; /* out of range */ + + while (--foo >= 1970) + retval += daysinyear(foo) * SECSPERDAY; + + retval += cumdays[tp->tm_mon] * SECSPERDAY; + retval += (tp->tm_mday-1) * SECSPERDAY; + retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec; + + if (local) { + /* need to use local time, so we retrieve timezone info */ + struct timezone tz; + struct timeval tv; + if (gettimeofday(&tv, &tz) < 0) { + /* some error--give up? */ + return(retval); + } + retval += tz.tz_minuteswest * SECSPERMIN; + } + return(retval); +} diff --git a/eBones/usr.sbin/kdb_edit/time.h b/eBones/usr.sbin/kdb_edit/time.h new file mode 100644 index 0000000..ed128d8 --- /dev/null +++ b/eBones/usr.sbin/kdb_edit/time.h @@ -0,0 +1,45 @@ +/* Structure for use by time manipulating subroutines. + * The following library routines use it: + * libc: ctime, localtime, gmtime, asctime + * libcx: partime, maketime (may not be installed yet) + */ + +/* + * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $ + * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $ + */ + +struct tm { /* See defines below for allowable ranges */ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + int tm_zon; /* NEW: mins westward of Greenwich */ + int tm_ampm; /* NEW: 1 if AM, 2 if PM */ +}; + +#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/ +#define TMNULL (-1) /* Items not specified are given this value + * in order to distinguish null specs from zero + * specs. This is only used by partime and + * maketime. */ + + /* Indices into TM structure */ +#define TM_SEC 0 /* 0-59 */ +#define TM_MIN 1 /* 0-59 */ +#define TM_HOUR 2 /* 0-23 */ +#define TM_MDAY 3 /* 1-31 day of month */ +#define TM_DAY TM_MDAY /* " synonym */ +#define TM_MON 4 /* 0-11 */ +#define TM_YEAR 5 /* (year-1900) (year) */ +#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */ +#define TM_YDAY 7 /* 0-365 day of year */ +#define TM_ISDST 8 /* 0 Std, 1 DST */ + /* New stuff */ +#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */ +#define TM_AMPM 10 /* 1 AM, 2 PM */ diff --git a/eBones/usr.sbin/kdb_init/Makefile b/eBones/usr.sbin/kdb_init/Makefile new file mode 100644 index 0000000..ce51a9f --- /dev/null +++ b/eBones/usr.sbin/kdb_init/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:03 g89r4222 Exp $ + +PROG= kdb_init +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_init/kdb_init.8 b/eBones/usr.sbin/kdb_init/kdb_init.8 new file mode 100644 index 0000000..54537ad --- /dev/null +++ b/eBones/usr.sbin/kdb_init/kdb_init.8 @@ -0,0 +1,41 @@ +.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $ +.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_init \- Initialize Kerberos key distribution center database +.SH SYNOPSIS +kdb_init [ +.B realm +] +.SH DESCRIPTION +.I kdb_init +initializes a Kerberos key distribution center database, creating the +necessary principals. +.PP +If the optional +.I realm +argument is not present, +.I kdb_init +prompts for a realm name (defaulting to the definition in /usr/include/krb.h). +After determining the realm to be created, it prompts for +a master key password. The master key password is used to encrypt +every encryption key stored in the database. +.SH DIAGNOSTICS +.TP 20n +"/kerberos/principal: File exists" +An attempt was made to create a database on a machine which already had +an existing database. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/usr/include/krb.h +Include file defining default realm +.SH SEE ALSO +kdb_destroy(8) diff --git a/eBones/usr.sbin/kdb_init/kdb_init.c b/eBones/usr.sbin/kdb_init/kdb_init.c new file mode 100644 index 0000000..dc7055e --- /dev/null +++ b/eBones/usr.sbin/kdb_init/kdb_init.c @@ -0,0 +1,178 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * program to initialize the database, reports error if database file + * already exists. + * + * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $ + * $Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/time.h> +#include <des.h> +#include <krb.h> +#include <krb_db.h> +#include <string.h> + +#define TRUE 1 + +enum ap_op { + NULL_KEY, /* setup null keys */ + MASTER_KEY, /* use master key as new key */ + RANDOM_KEY, /* choose a random key */ +}; + +int debug = 0; +char *progname, *rindex(); +C_Block master_key; +Key_schedule master_key_schedule; + +main(argc, argv) + char *argv[]; +{ + char realm[REALM_SZ]; + char *cp; + int code; + char *database; + + progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + + if (argc > 3) { + fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]); + exit(1); + } + if (argc == 3) { + database = argv[2]; + --argc; + } else + database = DBM_FILE; + + /* Do this first, it'll fail if the database exists */ + if ((code = kerb_db_create(database)) != 0) { + fprintf(stderr, "Couldn't create database: %s\n", + sys_errlist[code]); + exit(1); + } + kerb_db_set_name(database); + + if (argc == 2) + strncpy(realm, argv[1], REALM_SZ); + else { + fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM); + if (fgets(realm, sizeof(realm), stdin) == NULL) { + fprintf(stderr, "\nEOF reading realm\n"); + exit(1); + } + if (cp = index(realm, '\n')) + *cp = '\0'; + if (!*realm) /* no realm given */ + strcpy(realm, KRB_REALM); + } + if (!k_isrealm(realm)) { + fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n", + progname, realm); + exit(1); + } + printf("You will be prompted for the database Master Password.\n"); + printf("It is important that you NOT FORGET this password.\n"); + fflush(stdout); + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "Couldn't read master key.\n"); + exit (-1); + } + + if ( + add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) || + add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) || + add_principal("krbtgt", realm, RANDOM_KEY) || + add_principal("changepw", KRB_MASTER, RANDOM_KEY) + ) { + fprintf(stderr, "\n%s: couldn't initialize database.\n", + progname); + exit(1); + } + + /* play it safe */ + bzero (master_key, sizeof (C_Block)); + bzero (master_key_schedule, sizeof (Key_schedule)); + exit(0); +} + +/* use a return code to indicate success or failure. check the return */ +/* values of the routines called by this routine. */ + +add_principal(name, instance, aap_op) + char *name, *instance; + enum ap_op aap_op; +{ + Principal principal; + char datestring[50]; + char pw_str[255]; + void read_pw_string(); + void string_to_key(); + void random_key(); + struct tm *tm, *localtime(); + C_Block new_key; + + bzero(&principal, sizeof(principal)); + strncpy(principal.name, name, ANAME_SZ); + strncpy(principal.instance, instance, INST_SZ); + switch (aap_op) { + case NULL_KEY: + principal.key_low = 0; + principal.key_high = 0; + break; + case RANDOM_KEY: +#ifdef NOENCRYPTION + bzero(new_key, sizeof(C_Block)); + new_key[0] = 127; +#else + random_key(new_key); +#endif + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + case MASTER_KEY: + bcopy (master_key, new_key, sizeof (C_Block)); + kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule, + ENCRYPT); + bcopy(new_key, &principal.key_low, 4); + bcopy(((long *) new_key) + 1, &principal.key_high, 4); + break; + } + principal.exp_date = 946702799; /* Happy new century */ + strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ); + principal.mod_date = time(0); + + tm = localtime(&principal.mod_date); + principal.attributes = 0; + principal.max_life = 255; + + principal.kdc_key_ver = 1; + principal.key_version = 1; + + strncpy(principal.mod_name, "db_creation", ANAME_SZ); + strncpy(principal.mod_instance, "", INST_SZ); + principal.old = 0; + + kerb_db_put_principal(&principal, 1); + + /* let's play it safe */ + bzero (new_key, sizeof (C_Block)); + bzero (&principal.key_low, 4); + bzero (&principal.key_high, 4); + return 0; +} diff --git a/eBones/usr.sbin/kdb_util/Makefile b/eBones/usr.sbin/kdb_util/Makefile new file mode 100644 index 0000000..b3513d6 --- /dev/null +++ b/eBones/usr.sbin/kdb_util/Makefile @@ -0,0 +1,13 @@ +# From: @(#)Makefile 5.2 (Berkeley) 2/14/91 +# $Id: Makefile,v 1.2 1994/07/19 19:24:09 g89r4222 Exp $ + +PROG= kdb_util +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../kdb_edit \ + -I${.CURDIR}/../include +SRCS= kdb_util.c maketime.c +.PATH: ${.CURDIR}/../kdb_edit +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kdb_util/kdb_util.8 b/eBones/usr.sbin/kdb_util/kdb_util.8 new file mode 100644 index 0000000..30a3b9f --- /dev/null +++ b/eBones/usr.sbin/kdb_util/kdb_util.8 @@ -0,0 +1,64 @@ +.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $ +.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kdb_util \- Kerberos key distribution center database utility +.SH SYNOPSIS +kdb_util +.B operation filename +.SH DESCRIPTION +.I kdb_util +allows the Kerberos key distribution center (KDC) database administrator to +perform utility functions on the database. +.PP +.I Operation +must be one of the following: +.TP 10n +.I load +initializes the KDC database with the records described by the +text contained in the file +.IR filename . +Any existing database is overwritten. +.TP +.I dump +dumps the KDC database into a text representation in the file +.IR filename . +.TP +.I slave_dump +performs a database dump like the +.I dump +operation, and additionally creates a semaphore file signalling the +propagation software that an update is available for distribution to +slave KDC databases. +.TP +.I new_master_key +prompts for the old and new master key strings, and then dumps the KDC +database into a text representation in the file +.IR filename . +The keys in the text representation are encrypted in the new master key. +.TP +.I convert_old_db +prompts for the master key string, and then dumps the KDC database into +a text representation in the file +.IR filename . +The existing database is assumed to be encrypted using the old format +(encrypted by the key schedule of the master key); the dumped database +is encrypted using the new format (encrypted directly with master key). +.PP +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +.IR filename .ok +semaphore file created by +.IR slave_dump. diff --git a/eBones/usr.sbin/kdb_util/kdb_util.c b/eBones/usr.sbin/kdb_util/kdb_util.c new file mode 100644 index 0000000..8465b5b --- /dev/null +++ b/eBones/usr.sbin/kdb_util/kdb_util.c @@ -0,0 +1,506 @@ +/* + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * Kerberos database manipulation utility. This program allows you to + * dump a kerberos database to an ascii readable file and load this + * file into the database. Read locking of the database is done during a + * dump operation. NO LOCKING is done during a load operation. Loads + * should happen with other processes shutdown. + * + * Written July 9, 1987 by Jeffrey I. Schiller + * + * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $ + * $Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "time.h" +#include <strings.h> +#include <des.h> +#include <krb.h> +#include <sys/file.h> +#include <krb_db.h> + +#define TRUE 1 + +Principal aprinc; + +static des_cblock master_key, new_master_key; +static des_key_schedule master_key_schedule, new_master_key_schedule; + +#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo))) + +extern long kdb_get_master_key(), kdb_verify_master_key(); +extern char *malloc(); +extern int errno; + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + FILE *file; + enum { + OP_LOAD, + OP_DUMP, + OP_SLAVE_DUMP, + OP_NEW_MASTER, + OP_CONVERT_OLD_DB, + } op; + char *file_name; + char *prog = argv[0]; + char *db_name; + + progname = prog; + + if (argc != 3 && argc != 4) { + fprintf(stderr, "Usage: %s operation file-name [database name].\n", + argv[0]); + exit(1); + } + if (argc == 3) + db_name = DBM_FILE; + else + db_name = argv[3]; + + if (kerb_db_set_name (db_name) != 0) { + perror("Can't open database"); + exit(1); + } + + if (!strcmp(argv[1], "load")) + op = OP_LOAD; + else if (!strcmp(argv[1], "dump")) + op = OP_DUMP; + else if (!strcmp(argv[1], "slave_dump")) + op = OP_SLAVE_DUMP; + else if (!strcmp(argv[1], "new_master_key")) + op = OP_NEW_MASTER; + else if (!strcmp(argv[1], "convert_old_db")) + op = OP_CONVERT_OLD_DB; + else { + fprintf(stderr, + "%s: %s is an invalid operation.\n", prog, argv[1]); + fprintf(stderr, + "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]); + fprintf(stderr, + "\"load\", \"new_master_key\", and \"convert_old_db\".\n"); + exit(1); + } + + file_name = argv[2]; + file = fopen(file_name, op == OP_LOAD ? "r" : "w"); + if (file == NULL) { + fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]); + (void) fflush(stderr); + perror("open"); + exit(1); + } + + switch (op) { + case OP_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + break; + case OP_SLAVE_DUMP: + if ((dump_db (db_name, file, (void (*)()) 0) == EOF) || + (fclose(file) == EOF)) { + fprintf(stderr, "error on file %s:", file_name); + perror(""); + exit(1); + } + update_ok_file (file_name); + break; + case OP_LOAD: + load_db (db_name, file); + break; + case OP_NEW_MASTER: + convert_new_master_key (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + case OP_CONVERT_OLD_DB: + convert_old_format_db (db_name, file); + printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name); + break; + } + exit(0); + } + +clear_secrets () +{ + bzero((char *)master_key, sizeof (des_cblock)); + bzero((char *)master_key_schedule, sizeof (Key_schedule)); + bzero((char *)new_master_key, sizeof (des_cblock)); + bzero((char *)new_master_key_schedule, sizeof (Key_schedule)); +} + +/* cv_key is a procedure which takes a principle and changes its key, + either for a new method of encrypting the keys, or a new master key. + if cv_key is null no transformation of key is done (other than net byte + order). */ + +struct callback_args { + void (*cv_key)(); + FILE *output_file; +}; + +static int dump_db_1(arg, principal) + char *arg; + Principal *principal; +{ /* replace null strings with "*" */ + struct callback_args *a = (struct callback_args *)arg; + + if (principal->instance[0] == '\0') { + principal->instance[0] = '*'; + principal->instance[1] = '\0'; + } + if (principal->mod_name[0] == '\0') { + principal->mod_name[0] = '*'; + principal->mod_name[1] = '\0'; + } + if (principal->mod_instance[0] == '\0') { + principal->mod_instance[0] = '*'; + principal->mod_instance[1] = '\0'; + } + if (a->cv_key != NULL) { + (*a->cv_key) (principal); + } + fprintf(a->output_file, "%s %s %d %d %d %d %x %x", + principal->name, + principal->instance, + principal->max_life, + principal->kdc_key_ver, + principal->key_version, + principal->attributes, + htonl (principal->key_low), + htonl (principal->key_high)); + print_time(a->output_file, principal->exp_date); + print_time(a->output_file, principal->mod_date); + fprintf(a->output_file, " %s %s\n", + principal->mod_name, + principal->mod_instance); + return 0; +} + +dump_db (db_file, output_file, cv_key) + char *db_file; + FILE *output_file; + void (*cv_key)(); +{ + struct callback_args a; + + a.cv_key = cv_key; + a.output_file = output_file; + + kerb_db_iterate (dump_db_1, (char *)&a); + return fflush(output_file); +} + +load_db (db_file, input_file) + char *db_file; + FILE *input_file; +{ + char exp_date_str[50]; + char mod_date_str[50]; + int temp1, temp2, temp3; + long time_explode(); + int code; + char *temp_db_file; + temp1 = strlen(db_file+2); + temp_db_file = malloc (temp1); + strcpy(temp_db_file, db_file); + strcat(temp_db_file, "~"); + + /* Create the database */ + if ((code = kerb_db_create(temp_db_file)) != 0) { + fprintf(stderr, "Couldn't create temp database %s: %s\n", + temp_db_file, sys_errlist[code]); + exit(1); + } + kerb_db_set_name(temp_db_file); + for (;;) { /* explicit break on eof from fscanf */ + bzero((char *)&aprinc, sizeof(aprinc)); + if (fscanf(input_file, + "%s %s %d %d %d %hd %x %x %s %s %s %s\n", + aprinc.name, + aprinc.instance, + &temp1, + &temp2, + &temp3, + &aprinc.attributes, + &aprinc.key_low, + &aprinc.key_high, + exp_date_str, + mod_date_str, + aprinc.mod_name, + aprinc.mod_instance) == EOF) + break; + aprinc.key_low = ntohl (aprinc.key_low); + aprinc.key_high = ntohl (aprinc.key_high); + aprinc.max_life = (unsigned char) temp1; + aprinc.kdc_key_ver = (unsigned char) temp2; + aprinc.key_version = (unsigned char) temp3; + aprinc.exp_date = time_explode(exp_date_str); + aprinc.mod_date = time_explode(mod_date_str); + if (aprinc.instance[0] == '*') + aprinc.instance[0] = '\0'; + if (aprinc.mod_name[0] == '*') + aprinc.mod_name[0] = '\0'; + if (aprinc.mod_instance[0] == '*') + aprinc.mod_instance[0] = '\0'; + if (kerb_db_put_principal(&aprinc, 1) != 1) { + fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n", + aprinc.name, aprinc.instance, + sys_errlist[errno]); + exit(1); + }; + } + if ((code = kerb_db_rename(temp_db_file, db_file)) != 0) + perror("database rename failed"); + (void) fclose(input_file); + free(temp_db_file); +} + +print_time(file, timeval) + FILE *file; + unsigned long timeval; +{ + struct tm *tm; + struct tm *gmtime(); + tm = gmtime((long *)&timeval); + fprintf(file, " %04d%02d%02d%02d%02d", + tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min); +} + +/*ARGSUSED*/ +update_ok_file (file_name) + char *file_name; +{ + /* handle slave locking/failure stuff */ + char *file_ok; + int fd; + static char ok[]=".dump_ok"; + + if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1)) + == NULL) { + fprintf(stderr, "kdb_util: out of memory.\n"); + (void) fflush (stderr); + perror ("malloc"); + exit (1); + } + strcpy(file_ok, file_name); + strcat(file_ok, ok); + if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) { + fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok); + perror(""); + (void) fflush (stderr); + exit (1); + } + free(file_ok); + close(fd); +} + +void +convert_key_new_master (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + /* move current key to des_cblock for encryption, special case master key + since that's changing */ + if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) && + (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) { + bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock)); + (p->key_version)++; + } else { + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4); + kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT); + } + + kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ + + (p->kdc_key_ver)++; +} + +convert_new_master_key (db_file, out) + char *db_file; + FILE *out; +{ + + printf ("\n\nEnter the CURRENT master key."); + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets (); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets (); + exit (-1); + } + + printf ("\n\nNow enter the NEW master key. Do not forget it!!"); + if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't get new master key.\n"); + clear_secrets (); + exit (-1); + } + + dump_db (db_file, out, convert_key_new_master); +} + +void +convert_key_old_db (p) + Principal *p; +{ + des_cblock key; + + /* leave null keys alone */ + if ((p->key_low == 0) && (p->key_high == 0)) return; + + bcopy((char *)&(p->key_low), (char *)key, 4); + bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4); + +#ifndef NOENCRYPTION + des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key, + (long)sizeof(des_cblock),master_key_schedule, + (des_cblock *)master_key_schedule,DECRYPT); +#endif + + /* make new key, new style */ + kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT); + + bcopy((char *)key, (char *)&(p->key_low), 4); + bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4); + bzero((char *)key, sizeof (key)); /* a little paranoia ... */ +} + +convert_old_format_db (db_file, out) + char *db_file; + FILE *out; +{ + des_cblock key_from_db; + Principal principal_data[1]; + int n, more; + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) { + fprintf (stderr, "%s: Couldn't get master key.\n"); + clear_secrets(); + exit (-1); + } + + /* can't call kdb_verify_master_key because this is an old style db */ + /* lookup the master key version */ + n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data, + 1 /* only one please */, &more); + if ((n != 1) || more) { + fprintf(stderr, "verify_master_key: ", + "Kerberos error on master key lookup, %d found.\n", + n); + exit (-1); + } + + /* set up the master key */ + fprintf(stderr, "Current Kerberos master key version is %d.\n", + principal_data[0].kdc_key_ver); + + /* + * now use the master key to decrypt (old style) the key in the db, had better + * be the same! + */ + bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4); + bcopy((char *)&principal_data[0].key_high, + (char *)(((long *) key_from_db) + 1), 4); +#ifndef NOENCRYPTION + des_pcbc_encrypt(key_from_db,key_from_db,(long)sizeof(key_from_db), + master_key_schedule,(des_cblock *)master_key_schedule,DECRYPT); +#endif + /* the decrypted database key had better equal the master key */ + n = bcmp((char *) master_key, (char *) key_from_db, + sizeof(master_key)); + bzero((char *)key_from_db, sizeof(key_from_db)); + + if (n) { + fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, "); + fprintf(stderr, "does not match database.\n"); + exit (-1); + } + + fprintf(stderr, "Master key verified.\n"); + (void) fflush(stderr); + + dump_db (db_file, out, convert_key_old_db); +} + +long +time_explode(cp) +register char *cp; +{ + char wbuf[5]; + struct tm tp; + long maketime(); + int local; + + zaptime(&tp); /* clear out the struct */ + + if (strlen(cp) > 10) { /* new format */ + (void) strncpy(wbuf, cp, 4); + wbuf[4] = 0; + tp.tm_year = atoi(wbuf); + cp += 4; /* step over the year */ + local = 0; /* GMT */ + } else { /* old format: local time, + year is 2 digits, assuming 19xx */ + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_year = 1900 + atoi(wbuf); + local = 1; /* local */ + } + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_mon = atoi(wbuf)-1; + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_mday = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_hour = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_min = atoi(wbuf); + + + return(maketime(&tp, local)); +} diff --git a/eBones/usr.sbin/kerberos/Makefile b/eBones/usr.sbin/kerberos/Makefile new file mode 100644 index 0000000..7f36cf7 --- /dev/null +++ b/eBones/usr.sbin/kerberos/Makefile @@ -0,0 +1,11 @@ +# From: @(#)Makefile 5.1 (Berkeley) 6/25/90 +# $Id: Makefile,v 1.2 1994/07/19 19:24:22 g89r4222 Exp $ + +PROG= kerberos +SRCS= kerberos.c cr_err_reply.c +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kerberos/cr_err_reply.c b/eBones/usr.sbin/kerberos/cr_err_reply.c new file mode 100644 index 0000000..585fd03 --- /dev/null +++ b/eBones/usr.sbin/kerberos/cr_err_reply.c @@ -0,0 +1,95 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $ + * $Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $"; +#endif /* lint */ + +#include <sys/types.h> +#include <krb.h> +#include <prot.h> +#include <strings.h> + +extern int req_act_vno; /* this is defined in the kerberos + * server code */ + +/* + * This routine is used by the Kerberos authentication server to + * create an error reply packet to send back to its client. + * + * It takes a pointer to the packet to be built, the name, instance, + * and realm of the principal, the client's timestamp, an error code + * and an error string as arguments. Its return value is undefined. + * + * The packet is built in the following format: + * + * type variable data + * or constant + * ---- ----------- ---- + * + * unsigned char req_ack_vno protocol version number + * + * unsigned char AUTH_MSG_ERR_REPLY protocol message type + * + * [least significant HOST_BYTE_ORDER sender's (server's) byte + * bit of above field] order + * + * string pname principal's name + * + * string pinst principal's instance + * + * string prealm principal's realm + * + * unsigned long time_ws client's timestamp + * + * unsigned long e error code + * + * string e_string error text + */ + +void +cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string) + KTEXT pkt; + char *pname; /* Principal's name */ + char *pinst; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + u_long time_ws; /* Workstation time */ + u_long e; /* Error code */ + char *e_string; /* Text of error */ +{ + u_char *v = (u_char *) pkt->dat; /* Prot vers number */ + u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */ + + /* Create fixed part of packet */ + *v = (unsigned char) req_act_vno; /* KRB_PROT_VERSION; */ + *t = (unsigned char) AUTH_MSG_ERR_REPLY; + *t |= HOST_BYTE_ORDER; + + /* Add the basic info */ + (void) strcpy((char *) (pkt->dat+2),pname); + pkt->length = 3 + strlen(pname); + (void) strcpy((char *)(pkt->dat+pkt->length),pinst); + pkt->length += 1 + strlen(pinst); + (void) strcpy((char *)(pkt->dat+pkt->length),prealm); + pkt->length += 1 + strlen(prealm); + /* ws timestamp */ + bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err code */ + bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4); + pkt->length += 4; + /* err text */ + (void) strcpy((char *)(pkt->dat+pkt->length),e_string); + pkt->length += 1 + strlen(e_string); + + /* And return */ + return; +} diff --git a/eBones/usr.sbin/kerberos/kerberos.c b/eBones/usr.sbin/kerberos/kerberos.c new file mode 100644 index 0000000..b980577 --- /dev/null +++ b/eBones/usr.sbin/kerberos/kerberos.c @@ -0,0 +1,810 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology. + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $ + * $Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> +#include <ctype.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +struct sockaddr_in s_in = {AF_INET}; +int f; + +/* XXX several files in libkdb know about this */ +char *progname; + +static Key_schedule master_key_schedule; +static C_Block master_key; + +static struct timeval kerb_time; +static Principal a_name_data; /* for requesting user */ +static Principal s_name_data; /* for services requested */ +static C_Block session_key; +static C_Block user_key; +static C_Block service_key; +static u_char master_key_version; +static char k_instance[INST_SZ]; +static char log_text[128]; +static char *lt; +static int more; + +static int mflag; /* Are we invoked manually? */ +static int lflag; /* Have we set an alterate log file? */ +static char *log_file; /* name of alt. log file */ +static int nflag; /* don't check max age */ +static int rflag; /* alternate realm specified */ + +/* fields within the received request packet */ +static u_char req_msg_type; +static u_char req_version; +static char *req_name_ptr; +static char *req_inst_ptr; +static char *req_realm_ptr; +static u_char req_no_req; +static u_long req_time_ws; + +int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */ + +static char local_realm[REALM_SZ]; + +/* statistics */ +static long q_bytes; /* current bytes remaining in queue */ +static long q_n; /* how many consecutive non-zero + * q_bytes */ +static long max_q_bytes; +static long max_q_n; +static long n_auth_req; +static long n_appl_req; +static long n_packets; +static long n_user; +static long n_server; + +static long max_age = -1; +static long pause_int = -1; + +static void check_db_age(); +static void hang(); + +/* + * Print usage message and exit. + */ +static void usage() +{ + fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname, + " [-a max_age] [-l log_file] [-r realm]" + ," [database_pathname]" + ); + exit(1); +} + + +main(argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in from; + register int n; + int on = 1; + int child; + struct servent *sp; + int fromlen; + static KTEXT_ST pkt_st; + KTEXT pkt = &pkt_st; + Principal *p; + int more, kerror; + C_Block key; + int c; + extern char *optarg; + extern int optind; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) { + switch(c) { + case 's': + /* + * Set parameters to slave server defaults. + */ + if (max_age == -1 && !nflag) + max_age = ONE_DAY; /* 24 hours */ + if (pause_int == -1) + pause_int = FIVE_MINUTES; /* 5 minutes */ + if (lflag == 0) { + log_file = KRBSLAVELOG; + lflag++; + } + break; + case 'n': + max_age = -1; /* don't check max age. */ + nflag++; + break; + case 'm': + mflag++; /* running manually; prompt for master key */ + break; + case 'p': + /* Set pause interval. */ + if (!isdigit(optarg[0])) + usage(); + pause_int = atoi(optarg); + if ((pause_int < 5) || (pause_int > ONE_HOUR)) { + fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n"); + usage(); + } + break; + case 'a': + /* Set max age. */ + if (!isdigit(optarg[0])) + usage(); + max_age = atoi(optarg); + if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) { + fprintf(stderr, "max_age must be between one hour and three days, in seconds\n"); + usage(); + } + break; + case 'l': + /* Set alternate log file */ + lflag++; + log_file = optarg; + break; + case 'r': + /* Set realm name */ + rflag++; + strcpy(local_realm, optarg); + break; + default: + usage(); + break; + } + } + + if (optind == (argc-1)) { + if (kerb_db_set_name(argv[optind]) != 0) { + fprintf(stderr, "Could not set alternate database name\n"); + exit(1); + } + optind++; + } + + if (optind != argc) + usage(); + + printf("Kerberos server starting\n"); + + if ((!nflag) && (max_age != -1)) + printf("\tMaximum database age: %d seconds\n", max_age); + if (pause_int != -1) + printf("\tSleep for %d seconds on error\n", pause_int); + else + printf("\tSleep forever on error\n"); + if (mflag) + printf("\tMaster key will be entered manually\n"); + + printf("\tLog file is %s\n", lflag ? log_file : KRBLOG); + + if (lflag) + kset_logfile(log_file); + + /* find our hostname, and use it as the instance */ + if (gethostname(k_instance, INST_SZ)) { + fprintf(stderr, "%s: gethostname error\n", progname); + exit(1); + } + + if ((sp = getservbyname("kerberos", "udp")) == 0) { + fprintf(stderr, "%s: udp/kerberos unknown service\n", progname); + exit(1); + } + s_in.sin_port = sp->s_port; + + if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "%s: Can't open socket\n", progname); + exit(1); + } + if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname); + + if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) { + fprintf(stderr, "%s: Can't bind socket\n", progname); + exit(1); + } + /* do all the database and cache inits */ + if (n = kerb_init()) { + if (mflag) { + printf("Kerberos db and cache init "); + printf("failed = %d ...exiting\n", n); + exit(-1); + } else { + klog(L_KRB_PERR, + "Kerberos db and cache init failed = %d ...exiting", n); + hang(); + } + } + + /* Make sure database isn't stale */ + check_db_age(); + + /* setup master key */ + if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) { + klog (L_KRB_PERR, "kerberos: couldn't get master key.\n"); + exit (-1); + } + kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout); + if (kerror < 0) { + klog (L_KRB_PERR, "Can't verify master key."); + bzero (master_key, sizeof (master_key)); + bzero (master_key_schedule, sizeof (master_key_schedule)); + exit (-1); + } + + master_key_version = (u_char) kerror; + + fprintf(stdout, "\nCurrent Kerberos master key version is %d\n", + master_key_version); + + if (!rflag) { + /* Look up our local realm */ + krb_get_lrealm(local_realm, 1); + } + fprintf(stdout, "Local realm: %s\n", local_realm); + fflush(stdout); + + if (set_tgtkey(local_realm)) { + /* Ticket granting service unknown */ + klog(L_KRB_PERR, "Ticket granting ticket service unknown"); + fprintf(stderr, "Ticket granting ticket service unknown\n"); + exit(1); + } + if (mflag) { + if ((child = fork()) != 0) { + printf("Kerberos started, PID=%d\n", child); + exit(0); + } + setup_disc(); + } + /* receive loop */ + for (;;) { + fromlen = S_AD_SZ; + n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from, + &fromlen); + if (n > 0) { + pkt->length = n; + pkt->mbz = 0; /* force zeros to catch runaway strings */ + /* see what is left in the input queue */ + ioctl(f, FIONREAD, &q_bytes); + gettimeofday(&kerb_time, NULL); + q_n++; + max_q_n = max(max_q_n, q_n); + n_packets++; + klog(L_NET_INFO, + "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d", + q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0); + max_q_bytes = max(max_q_bytes, q_bytes); + if (!q_bytes) + q_n = 0; /* reset consecutive packets */ + kerberos(&from, pkt); + } else + klog(L_NET_ERR, + "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0); + } +} + + +kerberos(client, pkt) + struct sockaddr_in *client; + KTEXT pkt; +{ + static KTEXT_ST rpkt_st; + KTEXT rpkt = &rpkt_st; + static KTEXT_ST ciph_st; + KTEXT ciph = &ciph_st; + static KTEXT_ST tk_st; + KTEXT tk = &tk_st; + static KTEXT_ST auth_st; + KTEXT auth = &auth_st; + AUTH_DAT ad_st; + AUTH_DAT *ad = &ad_st; + + + static struct in_addr client_host; + static int msg_byte_order; + static int swap_bytes; + static u_char k_flags; + char *p_name, *instance; + u_long lifetime; + int i; + C_Block key; + Key_schedule key_s; + char *ptr; + + + + ciph->length = 0; + + client_host = client->sin_addr; + + /* eval macros and correct the byte order and alignment as needed */ + req_version = pkt_version(pkt); /* 1 byte, version */ + req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */ + + req_act_vno = req_version; + + /* check packet version */ + if (req_version != KRB_PROT_VERSION) { + lt = klog(L_KRB_PERR, + "KRB prot version mismatch: KRB =%d request = %d", + KRB_PROT_VERSION, req_version, 0); + /* send an error reply */ + kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt); + return; + } + msg_byte_order = req_msg_type & 1; + + swap_bytes = 0; + if (msg_byte_order != HOST_BYTE_ORDER) { + swap_bytes++; + } + klog(L_KRB_PINFO, + "Prot version: %d, Byte order: %d, Message type: %d", + req_version, msg_byte_order, req_msg_type); + + switch (req_msg_type & ~1) { + + case AUTH_MSG_KDC_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + n_auth_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + + /* set up and correct for byte order and alignment */ + req_name_ptr = (char *) pkt_a_name(pkt); + req_inst_ptr = (char *) pkt_a_inst(pkt); + req_realm_ptr = (char *) pkt_a_realm(pkt); + bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws)); + /* time has to be diddled */ + if (swap_bytes) { + swap_u_long(req_time_ws); + } + ptr = (char *) pkt_time_ws(pkt) + 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + rpkt = &rpkt_st; + klog(L_INI_REQ, + "Initial ticket request Host: %s User: \"%s\" \"%s\"", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + + if (i = check_princ(req_name_ptr, req_inst_ptr, 0, + &a_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + tk->length = 0; /* init */ + if (strcmp(service, "krbtgt")) + klog(L_NTGT_INTK, + "INITIAL request from %s.%s for %s.%s", + req_name_ptr, req_inst_ptr, service, instance, 0); + /* this does all the checking */ + if (i = check_princ(service, instance, lifetime, + &s_name_data)) { + kerb_err_reply(client, pkt, i, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, ((u_long) s_name_data.max_life)); + lifetime = min(lifetime, ((u_long) a_name_data.max_life)); + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + krb_create_ticket(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + /* + * get the user's key, unseal it from the server's key, and + * use it to seal the cipher + */ + + /* a_name_data.key_low a_name_data.key_high */ + bcopy(&a_name_data.key_low, key, 4); + bcopy(&a_name_data.key_high, ((long *) key) + 1, 4); + + /* unseal the a_name key from the master key */ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + + create_ciph(ciph, session_key, s_name_data.name, + s_name_data.instance, local_realm, lifetime, + s_name_data.key_version, tk, kerb_time.tv_sec, key); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(key, sizeof(key)); + + + + /* always send a reply packet */ + rpkt = create_auth_reply(req_name_ptr, req_inst_ptr, + req_realm_ptr, req_time_ws, 0, a_name_data.exp_date, + a_name_data.key_version, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&a_name_data, sizeof(a_name_data)); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + case AUTH_MSG_APPL_REQUEST: + { + u_long time_ws; /* Workstation time */ + u_long req_life; /* Requested liftime */ + char *service; /* Service name */ + char *instance; /* Service instance */ + int kerno; /* Kerberos error number */ + char tktrlm[REALM_SZ]; + + n_appl_req++; + tk->length = 0; + k_flags = 0; /* various kerberos flags */ + + auth->length = 4 + strlen(pkt->dat + 3); + auth->length += (int) *(pkt->dat + auth->length) + + (int) *(pkt->dat + auth->length + 1) + 2; + + bcopy(pkt->dat, auth->dat, auth->length); + + strncpy(tktrlm, auth->dat + 3, REALM_SZ); + if (set_tgtkey(tktrlm)) { + lt = klog(L_ERR_UNK, + "FAILED realm %s unknown. Host: %s ", + tktrlm, inet_ntoa(client_host)); + kerb_err_reply(client, pkt, kerno, lt); + return; + } + kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, + ad, 0); + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", + inet_ntoa(client_host), krb_err_txt[kerno]); + kerb_err_reply(client, pkt, kerno, "krb_rd_req failed"); + return; + } + ptr = (char *) pkt->dat + auth->length; + + bcopy(ptr, &time_ws, 4); + ptr += 4; + + req_life = (u_long) (*ptr++); + + service = ptr; + instance = ptr + strlen(service) + 1; + + klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s", + ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host), + service, instance, 0); + + if (strcmp(ad->prealm, tktrlm)) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't hop realms"); + return; + } + if (!strcmp(service, "changepw")) { + kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, + "Can't authorize password changed based on TGT"); + return; + } + kerno = check_princ(service, instance, req_life, + &s_name_data); + if (kerno) { + kerb_err_reply(client, pkt, kerno, lt); + return; + } + /* Bound requested lifetime with service and user */ + lifetime = min(req_life, + (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300))); + lifetime = min(lifetime, ((u_long) s_name_data.max_life)); + + /* unseal server's key from master key */ + bcopy(&s_name_data.key_low, key, 4); + bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ + +#ifdef NOENCRYPTION + bzero(session_key, sizeof(C_Block)); +#else + random_key(session_key); +#endif + + krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, + ad->prealm, client_host, + session_key, lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + key); + bzero(key, sizeof(key)); + bzero(key_s, sizeof(key_s)); + + create_ciph(ciph, session_key, service, instance, + local_realm, + lifetime, s_name_data.key_version, tk, + kerb_time.tv_sec, ad->session); + + /* clear session key */ + bzero(session_key, sizeof(session_key)); + + bzero(ad->session, sizeof(ad->session)); + + rpkt = create_auth_reply(ad->pname, ad->pinst, + ad->prealm, time_ws, + 0, 0, 0, ciph); + sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + bzero(&s_name_data, sizeof(s_name_data)); + break; + } + + +#ifdef notdef_DIE + case AUTH_MSG_DIE: + { + lt = klog(L_DEATH_REQ, + "Host: %s User: \"%s\" \"%s\" Kerberos killed", + inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); + exit(0); + } +#endif notdef_DIE + + default: + { + lt = klog(L_KRB_PERR, + "Unknown message type: %d from %s port %u", + req_msg_type, inet_ntoa(client_host), + ntohs(client->sin_port)); + break; + } + } +} + + +/* + * setup_disc + * + * disconnect all descriptors, remove ourself from the process + * group that spawned us. + */ + +setup_disc() +{ + + int s; + + for (s = 0; s < 3; s++) { + (void) close(s); + } + + (void) open("/dev/null", 0); + (void) dup2(0, 1); + (void) dup2(0, 2); + + s = open("/dev/tty", 2); + + if (s >= 0) { + ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); + (void) close(s); + } + (void) chdir("/tmp"); + return; +} + + +/* + * kerb_er_reply creates an error reply packet and sends it to the + * client. + */ + +kerb_err_reply(client, pkt, err, string) + struct sockaddr_in *client; + KTEXT pkt; + long err; + char *string; + +{ + static KTEXT_ST e_pkt_st; + KTEXT e_pkt = &e_pkt_st; + static char e_msg[128]; + + strcpy(e_msg, "\nKerberos error -- "); + strcat(e_msg, string); + cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, + req_time_ws, err, e_msg); + sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client, + S_AD_SZ); + +} + +/* + * Make sure that database isn't stale. + * + * Exit if it is; we don't want to tell lies. + */ + +static void check_db_age() +{ + long age; + + if (max_age != -1) { + /* Requires existance of kerb_get_db_age() */ + gettimeofday(&kerb_time, 0); + age = kerb_get_db_age(); + if (age == 0) { + klog(L_KRB_PERR, "Database currently being updated!"); + hang(); + } + if ((age + max_age) < kerb_time.tv_sec) { + klog(L_KRB_PERR, "Database out of date!"); + hang(); + /* NOTREACHED */ + } + } +} + +check_princ(p_name, instance, lifetime, p) + char *p_name; + char *instance; + unsigned lifetime; + + Principal *p; +{ + static int n; + static int more; + long trans; + + n = kerb_get_principal(p_name, instance, p, 1, &more); + klog(L_ALL_REQ, + "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", + p_name, instance, lifetime, n, 0); + + if (n < 0) { + lt = klog(L_KRB_PERR, "Database unavailable!"); + hang(); + } + + /* + * if more than one p_name, pick one, randomly create a session key, + * compute maximum lifetime, lookup authorizations if applicable, + * and stuff into cipher. + */ + if (n == 0) { + /* service unknown, log error, skip to next request */ + lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_PRINCIPAL_UNKNOWN; + } + if (more) { + /* not unique, log error */ + lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"", + p_name, instance, 0); + return KERB_ERR_PRINCIPAL_NOT_UNIQUE; + } + /* If the user's key is null, we want to return an error */ + if ((p->key_low == 0) && (p->key_high == 0)) { + /* User has a null key */ + lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_NULL_KEY; + } + if (master_key_version != p->kdc_key_ver) { + /* log error reply */ + lt = klog(L_ERR_MKV, + "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d", + master_key_version, p->name, p->instance, p->kdc_key_ver, + 0); + return KERB_ERR_NAME_MAST_KEY_VER; + } + /* make sure the service hasn't expired */ + if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) { + /* service did expire, log it */ + lt = klog(L_ERR_SEXP, + "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance, + stime(&(p->exp_date)), 0); + return KERB_ERR_NAME_EXP; + } + /* ok is zero */ + return 0; +} + + +/* Set the key for krb_rd_req so we can check tgt */ +set_tgtkey(r) + char *r; /* Realm for desired key */ +{ + int n; + static char lastrealm[REALM_SZ]; + Principal p_st; + Principal *p = &p_st; + C_Block key; + + if (!strcmp(lastrealm, r)) + return (KSUCCESS); + + log("Getting key for %s", r); + + n = kerb_get_principal("krbtgt", r, p, 1, &more); + if (n == 0) + return (KFAILURE); + + /* unseal tgt key from master key */ + bcopy(&p->key_low, key, 4); + bcopy(&p->key_high, ((long *) key) + 1, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + krb_set_key(key, 0); + strcpy(lastrealm, r); + return (KSUCCESS); +} + +static void +hang() +{ + if (pause_int == -1) { + klog(L_KRB_PERR, "Kerberos will pause so as not to loop init"); + for (;;) + pause(); + } else { + char buf[256]; + sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int); + klog(L_KRB_PERR, buf); + sleep(pause_int); + klog(L_KRB_PERR, "Do svedania....\n"); + exit(1); + } +} diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.8 b/eBones/usr.sbin/ksrvutil/ksrvutil.8 new file mode 100644 index 0000000..a7fed82 --- /dev/null +++ b/eBones/usr.sbin/ksrvutil/ksrvutil.8 @@ -0,0 +1,93 @@ +.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $ +.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +ksrvutil \- host kerberos keyfile (srvtab) manipulation utility +.SH SYNOPSIS +ksrvutil +.B operation +[ +.B \-k +] [ +.B \-i +] [ +.B \-f filename +] +.SH DESCRIPTION +.I ksrvutil +allows a system manager to list or change keys currently in his +keyfile or to add new keys to the keyfile. +.PP + +Operation must be one of the following: +.TP 10n +.I list +lists the keys in a keyfile showing version number and principal +name. If the \-k option is given, keys will also be shown. +.TP 10n +.I change +changes all the keys in the keyfile by using the regular admin +protocol. If the \-i flag is given, +.I ksrvutil +will prompt for yes or no before changing each key. If the \-k +option is used, the old and new keys will be displayed. +.TP 10n +.I add +allows the user to add a key. +.I add +prompts for name, instance, realm, and key version number, asks +for confirmation, and then asks for a password. +.I ksrvutil +then converts the password to a key and appends the keyfile with +the new information. If the \-k option is used, the key is +displayed. + +.PP +In all cases, the default file used is KEY_FILE as defined in +krb.h unless this is overridden by the \-f option. + +.PP +A good use for +.I ksrvutil +would be for adding keys to a keyfile. A system manager could +ask a kerberos administrator to create a new service key with +.IR kadmin (8) +and could supply an initial password. Then, he could use +.I ksrvutil +to add the key to the keyfile and then to change the key so that +it will be random and unknown to either the system manager or +the kerberos administrator. + +.I ksrvutil +always makes a backup copy of the keyfile before making any +changes. + +.SH DIAGNOSTICS +If +.I ksrvutil +should exit on an error condition at any time during a change or +add, a copy of the +original keyfile can be found in +.IR filename .old +where +.I filename +is the name of the keyfile, and a copy of the file with all new +keys changed or added so far can be found in +.IR filename .work. +The original keyfile is left unmodified until the program exits +at which point it is removed and replaced it with the workfile. +Appending the workfile to the backup copy and replacing the +keyfile with the result should always give a usable keyfile, +although the resulting keyfile will have some out of date keys +in it. + +.SH SEE ALSO +kadmin(8), ksrvtgt(1) + +.SH AUTHOR +Emanuel Jay Berkenbilt, MIT Project Athena diff --git a/eBones/usr.sbin/kstash/Makefile b/eBones/usr.sbin/kstash/Makefile new file mode 100644 index 0000000..8331c97a --- /dev/null +++ b/eBones/usr.sbin/kstash/Makefile @@ -0,0 +1,10 @@ +# From: @(#)Makefile 5.2 (Berkeley) 3/5/91 +# $Id: Makefile,v 1.2 1994/07/19 19:27:04 g89r4222 Exp $ + +PROG= kstash +CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include +DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES} +LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes +NOMAN= noman + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/kstash/kstash.8 b/eBones/usr.sbin/kstash/kstash.8 new file mode 100644 index 0000000..d83379a --- /dev/null +++ b/eBones/usr.sbin/kstash/kstash.8 @@ -0,0 +1,41 @@ +.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $ +.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $ +.\" Copyright 1989 by the Massachusetts Institute of Technology. +.\" +.\" For copying and distribution information, +.\" please see the file <Copyright.MIT>. +.\" +.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena" +.SH NAME +kstash \- stash Kerberos key distribution center database master key +.SH SYNOPSIS +kstash +.SH DESCRIPTION +.I kstash +saves the Kerberos key distribution center (KDC) database master key in +the master key cache file. +.PP +The user is prompted to enter the key, to verify the authenticity of the +key and the authorization to store the key in the file. +.SH DIAGNOSTICS +.TP 20n +"verify_master_key: Invalid master key, does not match database." +The master key string entered was incorrect. +.TP +"kstash: Unable to open master key file" +The attempt to open the cache file for writing failed (probably due to a +system or access permission error). +.TP +"kstash: Write I/O error on master key file" +The +.BR write (2) +system call returned an error while +.I kstash +was attempting to write the key to the file. +.SH FILES +.TP 20n +/kerberos/principal.pag, /kerberos/principal.dir +DBM files containing database +.TP +/.k +Master key cache file. diff --git a/eBones/usr.sbin/kstash/kstash.c b/eBones/usr.sbin/kstash/kstash.c new file mode 100644 index 0000000..696e4e1 --- /dev/null +++ b/eBones/usr.sbin/kstash/kstash.c @@ -0,0 +1,92 @@ +/* + * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute + * of Technology + * For copying and distribution information, please see the file + * <Copyright.MIT>. + * + * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $ + * $Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $ + */ + +#ifndef lint +static char rcsid[] = +"$Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $"; +#endif lint + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> + +#include <krb.h> +#include <des.h> +#include <klog.h> +#include <prot.h> +#include <krb_db.h> +#include <kdc.h> + +extern int errno; + +/* change this later, but krblib_dbm needs it for now */ +char *progname; + +static C_Block master_key; +static Key_schedule master_key_schedule; +static Principal s_name_data; /* for services requested */ +static unsigned char master_key_version; +int debug; +static int more; +static int kfile; +static void clear_secrets(); + +main(argc, argv) + int argc; + char **argv; +{ + long n; + if (n = kerb_init()) { + fprintf(stderr, "Kerberos db and cache init failed = %d\n", n); + exit(1); + } + + if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) { + fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]); + fflush (stderr); + clear_secrets(); + exit (-1); + } + + if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) { + clear_secrets(); + exit (-1); + } + + kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600); + if (kfile < 0) { + clear_secrets(); + fprintf(stderr, "\n\07\07%s: Unable to open master key file\n", + argv[0]); + exit(1); + } + if (write(kfile, (char *) master_key, 8) < 0) { + clear_secrets(); + fprintf(stderr, "\n%s: Write I/O error on master key file\n", + argv[0]); + exit(1); + } + (void) close(kfile); + clear_secrets(); +} + +static void +clear_secrets() +{ + bzero(master_key_schedule, sizeof(master_key_schedule)); + bzero(master_key, sizeof(master_key)); +} diff --git a/eBones/usr.sbin/make_keypair/Makefile b/eBones/usr.sbin/make_keypair/Makefile new file mode 100644 index 0000000..b00048e --- /dev/null +++ b/eBones/usr.sbin/make_keypair/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/1/93 + +PROG= make_keypair +MAN8= make_keypair.8 +CFLAGS+=-DKERBEROS -I${.CURDIR}/../register +DPADD= ${LIBKRB} ${LIBDES} +LDADD= -lkdb -lkrb -ldes + +.include <bsd.prog.mk> diff --git a/eBones/usr.sbin/make_keypair/make_keypair.8 b/eBones/usr.sbin/make_keypair/make_keypair.8 new file mode 100644 index 0000000..d0b7b88 --- /dev/null +++ b/eBones/usr.sbin/make_keypair/make_keypair.8 @@ -0,0 +1,87 @@ +.\" Copyright (c) 1988, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)make_keypair.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt MAKE_KEYPAIR 8 +.Os +.Sh NAME +.Nm make_keypair +.Nd generate Kerberos host key pair +.Sh SYNOPSIS +.Nm make_keypair +.Ar hostname +.Op Ar hostname ... +.Sh DESCRIPTION +The +.Nm make_keypair +command +is used to create pairs of +.Tn DES +keys for +each +.Ar hostname . +The keys are used by privileged programs such as +.Xr register 1 +to make remote updates to the Kerberos database without +having to have first acquired a Kerberos ticket granting ticket +.Pq Tn TGT . +The keys created by +.Nm make_keypair +are placed (by hand) in the filesystems of the +kerberos server in +.Pa /etc/kerberosIV/register_keys , +and in the root directory of the clients. +For example, the file +.Pa /.update.key128.32.130.3 +would +contain a copy of the key of the client with +IP address 128.32.130.3. +These keys provide a shared secret which may be used to establish +a secure channel between the client hosts and the Kerberos server. +.Sh FILES +.Bl -tag -width /etc/kerberosIV/register_keysxx -compact +.It Pa /.update.keyxx.xx.xx.xx +shared +.Tn DES +key with server +.It Pa /etc/kerberosIV/register_keys +server's key storage directory +.El +.Sh SEE ALSO +.Xr register 1 , +.Xr registerd 8 , +.Xr kerberos 1 +.Sh HISTORY +The +.Nm make_keypair +utility first appeared in 4.4BSD. diff --git a/eBones/usr.sbin/make_keypair/make_keypair.c b/eBones/usr.sbin/make_keypair/make_keypair.c new file mode 100644 index 0000000..c9883ed --- /dev/null +++ b/eBones/usr.sbin/make_keypair/make_keypair.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <stdio.h> +#include <netdb.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> +#include "pathnames.h" +#include "register_proto.h" + +extern void random_key(), herror(); +void make_key(), usage(); + +char * progname; + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + char *addr; + int i; + struct sockaddr_in sin; + + progname = *argv; /* argv[0] */ + + if (argc != 2) { + usage(argv[0]); + exit(1); + } + + if ((hp = gethostbyname(argv[1])) == NULL) { + herror(argv[1]); + exit(1); + } + + for (i = 0; addr = hp->h_addr_list[i]; i++) { + addr = hp->h_addr_list[i]; + bcopy(addr, &sin.sin_addr, hp->h_length); + + printf("Making key for host %s (%s)\n", + argv[1], inet_ntoa(sin.sin_addr)); + make_key(sin.sin_addr); + } + printf("==========\n"); + printf("One copy of the each key should be put in %s on the\n", + SERVER_KEYDIR); + printf("Kerberos server machine (mode 600, owner root).\n"); + printf("Another copy of each key should be put on the named\n"); + printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n", + CLIENT_KEYFILE); + printf("where the X's refer to digits of the host's inet address.\n"); + (void)fflush(stdout); + exit(0); +} + +void +make_key(addr) + struct in_addr addr; +{ + struct keyfile_data kfile; + char namebuf[255]; + int fd; + + (void)sprintf(namebuf, "%s%s", + CLIENT_KEYFILE, + inet_ntoa(addr)); + fd = open(namebuf, O_WRONLY|O_CREAT, 0600); + if (fd < 0) { + perror("open"); + exit(1); + } + random_key(kfile.kf_key); + printf("writing to file -> %s ...", namebuf); + if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) { + fprintf(stderr, "error writing file %s\n", namebuf); + } + printf("done.\n"); + (void)close(fd); + return; +} + +void +usage(name) + char *name; +{ + fprintf(stderr, "usage: %s host\n", name); +} |