Kerberos IV code, based on a merge of fixed code from KTH and original
authortholo <tholo@openbsd.org>
Thu, 14 Dec 1995 06:52:32 +0000 (06:52 +0000)
committertholo <tholo@openbsd.org>
Thu, 14 Dec 1995 06:52:32 +0000 (06:52 +0000)
4.4BSD Lite code (international edition).  Provides all functionality
from the original 4.4BSD code plus standard Kerberos elements that were
omitted in the 4.4BSD code.

252 files changed:
kerberosIV/Makefile [new file with mode: 0644]
kerberosIV/Makefile.inc [new file with mode: 0644]
kerberosIV/acl/Makefile [new file with mode: 0644]
kerberosIV/acl/acl_check.3 [new file with mode: 0644]
kerberosIV/acl/acl_files.c [new file with mode: 0644]
kerberosIV/acl/shlib_version [new file with mode: 0644]
kerberosIV/com_err/Makefile [new file with mode: 0644]
kerberosIV/com_err/com_err.3 [new file with mode: 0644]
kerberosIV/com_err/com_err.c [new file with mode: 0644]
kerberosIV/com_err/error_message.c [new file with mode: 0644]
kerberosIV/com_err/error_table.h [new file with mode: 0644]
kerberosIV/com_err/et_name.c [new file with mode: 0644]
kerberosIV/com_err/init_et.c [new file with mode: 0644]
kerberosIV/compile_et/Makefile [new file with mode: 0644]
kerberosIV/compile_et/compile_et.1 [new file with mode: 0644]
kerberosIV/compile_et/compile_et.c [new file with mode: 0644]
kerberosIV/compile_et/compiler.h [new file with mode: 0644]
kerberosIV/compile_et/error_table.y [new file with mode: 0644]
kerberosIV/compile_et/et_lex.lex.l [new file with mode: 0644]
kerberosIV/des/3cbc_enc.c [new file with mode: 0644]
kerberosIV/des/3ecb_enc.c [new file with mode: 0644]
kerberosIV/des/ARTISTIC [new file with mode: 0644]
kerberosIV/des/CHANGES [new file with mode: 0644]
kerberosIV/des/COPYING [new file with mode: 0644]
kerberosIV/des/Makefile [new file with mode: 0644]
kerberosIV/des/README [new file with mode: 0644]
kerberosIV/des/VERSION [new file with mode: 0644]
kerberosIV/des/cbc_cksm.c [new file with mode: 0644]
kerberosIV/des/cbc_enc.c [new file with mode: 0644]
kerberosIV/des/cfb_enc.c [new file with mode: 0644]
kerberosIV/des/des_crypt.3 [new file with mode: 0644]
kerberosIV/des/des_locl.h [new file with mode: 0644]
kerberosIV/des/ecb_enc.c [new file with mode: 0644]
kerberosIV/des/enc_read.c [new file with mode: 0644]
kerberosIV/des/enc_writ.c [new file with mode: 0644]
kerberosIV/des/key_par.c [new file with mode: 0644]
kerberosIV/des/ofb_enc.c [new file with mode: 0644]
kerberosIV/des/pcbc_enc.c [new file with mode: 0644]
kerberosIV/des/podd.h [new file with mode: 0644]
kerberosIV/des/qud_cksm.c [new file with mode: 0644]
kerberosIV/des/random_key.c [new file with mode: 0644]
kerberosIV/des/read_pwd.c [new file with mode: 0644]
kerberosIV/des/rnd_keys.c [new file with mode: 0644]
kerberosIV/des/set_key.c [new file with mode: 0644]
kerberosIV/des/shlib_version [new file with mode: 0644]
kerberosIV/des/sk.h [new file with mode: 0644]
kerberosIV/des/spr.h [new file with mode: 0644]
kerberosIV/des/str2key.c [new file with mode: 0644]
kerberosIV/ext_srvtab/Makefile [new file with mode: 0644]
kerberosIV/ext_srvtab/ext_srvtab.8 [new file with mode: 0644]
kerberosIV/ext_srvtab/ext_srvtab.c [new file with mode: 0644]
kerberosIV/include/Makefile [new file with mode: 0644]
kerberosIV/include/adm_locl.h [new file with mode: 0644]
kerberosIV/include/kadm_locl.h [new file with mode: 0644]
kerberosIV/include/kadm_server.h [new file with mode: 0644]
kerberosIV/include/kdc.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/Makefile [new file with mode: 0644]
kerberosIV/include/kerberosIV/acl.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/com_err.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/des.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/kadm.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/kafs.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/kparse.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/krb.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/krb_db.h [new file with mode: 0644]
kerberosIV/include/kerberosIV/site.h [new file with mode: 0644]
kerberosIV/include/klog.h [new file with mode: 0644]
kerberosIV/include/kprop.h [new file with mode: 0644]
kerberosIV/include/kuser_locl.h [new file with mode: 0644]
kerberosIV/include/prot.h [new file with mode: 0644]
kerberosIV/include/slav_locl.h [new file with mode: 0644]
kerberosIV/include/ss/Makefile [new file with mode: 0644]
kerberosIV/include/ss/ss.h [new file with mode: 0644]
kerberosIV/kadm/Makefile [new file with mode: 0644]
kerberosIV/kadm/kadm_cli_wrap.c [new file with mode: 0644]
kerberosIV/kadm/kadm_err.et [new file with mode: 0644]
kerberosIV/kadm/kadm_local.h [new file with mode: 0644]
kerberosIV/kadm/kadm_stream.c [new file with mode: 0644]
kerberosIV/kadm/kadm_supp.c [new file with mode: 0644]
kerberosIV/kadm/shlib_version [new file with mode: 0644]
kerberosIV/kadmin/Makefile [new file with mode: 0644]
kerberosIV/kadmin/kadmin.8 [new file with mode: 0644]
kerberosIV/kadmin/kadmin.c [new file with mode: 0644]
kerberosIV/kadmin/kadmin_cmds.ct [new file with mode: 0644]
kerberosIV/kadmind/Makefile [new file with mode: 0644]
kerberosIV/kadmind/admin_server.c [new file with mode: 0644]
kerberosIV/kadmind/kadm_funcs.c [new file with mode: 0644]
kerberosIV/kadmind/kadm_ser_wrap.c [new file with mode: 0644]
kerberosIV/kadmind/kadm_server.c [new file with mode: 0644]
kerberosIV/kadmind/kadmind.8 [new file with mode: 0644]
kerberosIV/kafs/Makefile [new file with mode: 0644]
kerberosIV/kafs/afssys.c [new file with mode: 0644]
kerberosIV/kafs/afssysdefs.h [new file with mode: 0644]
kerberosIV/kafs/shlib_version [new file with mode: 0644]
kerberosIV/kdb/Makefile [new file with mode: 0644]
kerberosIV/kdb/kdb_locl.h [new file with mode: 0644]
kerberosIV/kdb/krb_cache.c [new file with mode: 0644]
kerberosIV/kdb/krb_dbm.c [new file with mode: 0644]
kerberosIV/kdb/krb_kdb_utils.c [new file with mode: 0644]
kerberosIV/kdb/krb_lib.c [new file with mode: 0644]
kerberosIV/kdb/print_princ.c [new file with mode: 0644]
kerberosIV/kdb/shlib_version [new file with mode: 0644]
kerberosIV/kdb_destroy/Makefile [new file with mode: 0644]
kerberosIV/kdb_destroy/kdb_destroy.8 [new file with mode: 0644]
kerberosIV/kdb_destroy/kdb_destroy.c [new file with mode: 0644]
kerberosIV/kdb_edit/Makefile [new file with mode: 0644]
kerberosIV/kdb_edit/kdb_edit.8 [new file with mode: 0644]
kerberosIV/kdb_edit/kdb_edit.c [new file with mode: 0644]
kerberosIV/kdb_edit/maketime.c [new file with mode: 0644]
kerberosIV/kdb_init/Makefile [new file with mode: 0644]
kerberosIV/kdb_init/kdb_init.8 [new file with mode: 0644]
kerberosIV/kdb_init/kdb_init.c [new file with mode: 0644]
kerberosIV/kdb_util/Makefile [new file with mode: 0644]
kerberosIV/kdb_util/kdb_util.8 [new file with mode: 0644]
kerberosIV/kdb_util/kdb_util.c [new file with mode: 0644]
kerberosIV/kdestroy/Makefile [new file with mode: 0644]
kerberosIV/kdestroy/kdestroy.1 [new file with mode: 0644]
kerberosIV/kdestroy/kdestroy.c [new file with mode: 0644]
kerberosIV/kerberos/Makefile [new file with mode: 0644]
kerberosIV/kerberos/kerberos.8 [new file with mode: 0644]
kerberosIV/kerberos/kerberos.c [new file with mode: 0644]
kerberosIV/kinit/Makefile [new file with mode: 0644]
kerberosIV/kinit/kinit.1 [new file with mode: 0644]
kerberosIV/kinit/kinit.c [new file with mode: 0644]
kerberosIV/klist/Makefile [new file with mode: 0644]
kerberosIV/klist/klist.1 [new file with mode: 0644]
kerberosIV/klist/klist.c [new file with mode: 0644]
kerberosIV/kpasswdd/Makefile [new file with mode: 0644]
kerberosIV/kpasswdd/kpasswdd.8 [new file with mode: 0644]
kerberosIV/kpasswdd/kpasswdd.c [new file with mode: 0644]
kerberosIV/kprop/Makefile [new file with mode: 0644]
kerberosIV/kprop/kprop.c [new file with mode: 0644]
kerberosIV/kpropd/Makefile [new file with mode: 0644]
kerberosIV/kpropd/kpropd.c [new file with mode: 0644]
kerberosIV/krb/Makefile [new file with mode: 0644]
kerberosIV/krb/cr_err_reply.c [new file with mode: 0644]
kerberosIV/krb/create_auth_reply.c [new file with mode: 0644]
kerberosIV/krb/create_ciph.c [new file with mode: 0644]
kerberosIV/krb/create_death_packet.c [new file with mode: 0644]
kerberosIV/krb/create_ticket.c [new file with mode: 0644]
kerberosIV/krb/debug_decl.c [new file with mode: 0644]
kerberosIV/krb/decomp_ticket.c [new file with mode: 0644]
kerberosIV/krb/dest_tkt.c [new file with mode: 0644]
kerberosIV/krb/extract_ticket.c [new file with mode: 0644]
kerberosIV/krb/fgetst.c [new file with mode: 0644]
kerberosIV/krb/get_ad_tkt.c [new file with mode: 0644]
kerberosIV/krb/get_admhst.c [new file with mode: 0644]
kerberosIV/krb/get_cred.c [new file with mode: 0644]
kerberosIV/krb/get_in_tkt.c [new file with mode: 0644]
kerberosIV/krb/get_krbhst.c [new file with mode: 0644]
kerberosIV/krb/get_krbrlm.c [new file with mode: 0644]
kerberosIV/krb/get_phost.c [new file with mode: 0644]
kerberosIV/krb/get_pw_tkt.c [new file with mode: 0644]
kerberosIV/krb/get_request.c [new file with mode: 0644]
kerberosIV/krb/get_svc_in_tkt.c [new file with mode: 0644]
kerberosIV/krb/get_tf_fullname.c [new file with mode: 0644]
kerberosIV/krb/get_tf_realm.c [new file with mode: 0644]
kerberosIV/krb/getrealm.c [new file with mode: 0644]
kerberosIV/krb/getst.c [new file with mode: 0644]
kerberosIV/krb/in_tkt.c [new file with mode: 0644]
kerberosIV/krb/k_localtime.c [new file with mode: 0644]
kerberosIV/krb/kerberos.3 [new file with mode: 0644]
kerberosIV/krb/klog.c [new file with mode: 0644]
kerberosIV/krb/kname_parse.c [new file with mode: 0644]
kerberosIV/krb/kntoln.c [new file with mode: 0644]
kerberosIV/krb/kparse.c [new file with mode: 0644]
kerberosIV/krb/krb_equiv.c [new file with mode: 0644]
kerberosIV/krb/krb_err.et [new file with mode: 0644]
kerberosIV/krb/krb_err_txt.c [new file with mode: 0644]
kerberosIV/krb/krb_get_in_tkt.c [new file with mode: 0644]
kerberosIV/krb/krb_locl.h [new file with mode: 0644]
kerberosIV/krb/krb_realmofhost.3 [new file with mode: 0644]
kerberosIV/krb/krb_sendauth.3 [new file with mode: 0644]
kerberosIV/krb/krb_set_tkt_string.3 [new file with mode: 0644]
kerberosIV/krb/kuserok.3 [new file with mode: 0644]
kerberosIV/krb/kuserok.c [new file with mode: 0644]
kerberosIV/krb/lifetime.c [new file with mode: 0644]
kerberosIV/krb/log.c [new file with mode: 0644]
kerberosIV/krb/lsb_addr_comp.h [new file with mode: 0644]
kerberosIV/krb/mk_err.c [new file with mode: 0644]
kerberosIV/krb/mk_priv.c [new file with mode: 0644]
kerberosIV/krb/mk_req.c [new file with mode: 0644]
kerberosIV/krb/mk_safe.c [new file with mode: 0644]
kerberosIV/krb/month_sname.c [new file with mode: 0644]
kerberosIV/krb/netread.c [new file with mode: 0644]
kerberosIV/krb/netwrite.c [new file with mode: 0644]
kerberosIV/krb/one.c [new file with mode: 0644]
kerberosIV/krb/pkt_cipher.c [new file with mode: 0644]
kerberosIV/krb/pkt_clen.c [new file with mode: 0644]
kerberosIV/krb/rd_err.c [new file with mode: 0644]
kerberosIV/krb/rd_priv.c [new file with mode: 0644]
kerberosIV/krb/rd_req.c [new file with mode: 0644]
kerberosIV/krb/rd_safe.c [new file with mode: 0644]
kerberosIV/krb/read_service_key.c [new file with mode: 0644]
kerberosIV/krb/recvauth.c [new file with mode: 0644]
kerberosIV/krb/save_credentials.c [new file with mode: 0644]
kerberosIV/krb/send_to_kdc.c [new file with mode: 0644]
kerberosIV/krb/sendauth.c [new file with mode: 0644]
kerberosIV/krb/shlib_version [new file with mode: 0644]
kerberosIV/krb/str2key.c [new file with mode: 0644]
kerberosIV/krb/tf_util.3 [new file with mode: 0644]
kerberosIV/krb/tf_util.c [new file with mode: 0644]
kerberosIV/krb/tkt_string.c [new file with mode: 0644]
kerberosIV/ksrvtgt/Makefile [new file with mode: 0644]
kerberosIV/ksrvtgt/ksrvtgt.1 [new file with mode: 0644]
kerberosIV/ksrvtgt/ksrvtgt.c [new file with mode: 0644]
kerberosIV/ksrvutil/Makefile [new file with mode: 0644]
kerberosIV/ksrvutil/ksrvutil.8 [new file with mode: 0644]
kerberosIV/ksrvutil/ksrvutil.c [new file with mode: 0644]
kerberosIV/kstash/Makefile [new file with mode: 0644]
kerberosIV/kstash/kstash.8 [new file with mode: 0644]
kerberosIV/kstash/kstash.c [new file with mode: 0644]
kerberosIV/make_keypair/Makefile [new file with mode: 0644]
kerberosIV/make_keypair/make_keypair.8 [new file with mode: 0644]
kerberosIV/make_keypair/make_keypair.c [new file with mode: 0644]
kerberosIV/man/Makefile [new file with mode: 0644]
kerberosIV/man/kerberos.1 [new file with mode: 0644]
kerberosIV/man/krb.conf.5 [new file with mode: 0644]
kerberosIV/man/krb.equiv.5 [new file with mode: 0644]
kerberosIV/man/krb.realms.5 [new file with mode: 0644]
kerberosIV/mk_cmds/Makefile [new file with mode: 0644]
kerberosIV/mk_cmds/cmd_tbl.l [new file with mode: 0644]
kerberosIV/mk_cmds/ct.y [new file with mode: 0644]
kerberosIV/mk_cmds/mk_cmds.c [new file with mode: 0644]
kerberosIV/mk_cmds/mk_cmds_defs.h [new file with mode: 0644]
kerberosIV/mk_cmds/options.c [new file with mode: 0644]
kerberosIV/mk_cmds/utils.c [new file with mode: 0644]
kerberosIV/register/Makefile [new file with mode: 0644]
kerberosIV/register/pathnames.h [new file with mode: 0644]
kerberosIV/register/register.1 [new file with mode: 0644]
kerberosIV/register/register.c [new file with mode: 0644]
kerberosIV/register/register_proto.h [new file with mode: 0644]
kerberosIV/registerd/Makefile [new file with mode: 0644]
kerberosIV/registerd/registerd.8 [new file with mode: 0644]
kerberosIV/registerd/registerd.c [new file with mode: 0644]
kerberosIV/ss/Makefile [new file with mode: 0644]
kerberosIV/ss/data.c [new file with mode: 0644]
kerberosIV/ss/error.c [new file with mode: 0644]
kerberosIV/ss/execute_cmd.c [new file with mode: 0644]
kerberosIV/ss/help.c [new file with mode: 0644]
kerberosIV/ss/invocation.c [new file with mode: 0644]
kerberosIV/ss/list_rqs.c [new file with mode: 0644]
kerberosIV/ss/listen.c [new file with mode: 0644]
kerberosIV/ss/pager.c [new file with mode: 0644]
kerberosIV/ss/parse.c [new file with mode: 0644]
kerberosIV/ss/prompt.c [new file with mode: 0644]
kerberosIV/ss/request_tbl.c [new file with mode: 0644]
kerberosIV/ss/requests.c [new file with mode: 0644]
kerberosIV/ss/shlib_version [new file with mode: 0644]
kerberosIV/ss/ss_err.et [new file with mode: 0644]
kerberosIV/ss/ss_internal.h [new file with mode: 0644]
kerberosIV/ss/std_rqs.ct [new file with mode: 0644]

diff --git a/kerberosIV/Makefile b/kerberosIV/Makefile
new file mode 100644 (file)
index 0000000..b807540
--- /dev/null
@@ -0,0 +1,20 @@
+#      from @(#)Makefile       5.1 (Berkeley) 6/25/90
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $
+
+# do compile_et and mk_cmds first, used by other directories
+
+.ifmake install
+SUBDIR=        include
+.else
+SUBDIR=        compile_et mk_cmds
+.endif
+
+SUBDIR+=acl com_err des krb kadm kafs kdb ss
+
+SUBDIR+=ext_srvtab kadmin kadmind kdb_destroy kdb_edit kdb_init kdb_util \
+       kdestroy kerberos kinit klist kpasswdd kprop kpropd ksrvtgt ksrvutil \
+       kstash make_keypair register registerd
+
+SUBDIR+=man
+
+.include <bsd.subdir.mk>
diff --git a/kerberosIV/Makefile.inc b/kerberosIV/Makefile.inc
new file mode 100644 (file)
index 0000000..4a57015
--- /dev/null
@@ -0,0 +1,23 @@
+#      from @(#)Makefile.inc   8.1 (Berkeley) 6/1/93
+#      $Id: Makefile.inc,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $
+
+CFLAGS+=-I${.CURDIR}/../include
+BINDIR?=/usr/sbin
+
+.if exists(${.CURDIR}/../mk_cmds/obj)
+MK_CMDS=${.CURDIR}/../mk_cmds/obj/mk_cmds
+.else
+MK_CMDS=${.CURDIR}/../mk_cmds/mk_cmds
+.endif
+
+.if exists(${.CURDIR}/../compile_et/obj)
+COMPILE_ET=${.CURDIR}/../compile_et/obj/compile_et
+.else
+COMPILE_ET=${.CURDIR}/../compile_et/compile_et
+.endif
+
+.if exists(${.CURDIR}/../com_err/obj)
+COM_ERR=-L${.CURDIR}/../com_err/obj -lcom_err_pic
+.else
+COM_ERR=-L${.CURDIR}/../com_err -lcom_err_pic
+.endif
diff --git a/kerberosIV/acl/Makefile b/kerberosIV/acl/Makefile
new file mode 100644 (file)
index 0000000..8b19ea8
--- /dev/null
@@ -0,0 +1,11 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $
+
+LIB=   acl
+SRCS=  acl_files.c
+MAN=   acl_check.3
+MLINKS+=acl_check.3 acl_canonicalize_principal.3 \
+       acl_check.3 acl_exact_match.3 \
+       acl_check.3 acl_add.3 acl_check.3 acl_delete.3 \
+       acl_check.3 acl_initialize.3
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/acl/acl_check.3 b/kerberosIV/acl/acl_check.3
new file mode 100644 (file)
index 0000000..8531572
--- /dev/null
@@ -0,0 +1,182 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: acl_check.3,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $
+.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+acl_canonicalize_principal, acl_check, acl_exact_match, acl_add,
+acl_delete, acl_initialize \- Access control list routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+cc <files> \-lacl \-lkrb
+.PP
+.ft B
+#include <krb.h>
+.PP
+.ft B
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf;
+.PP
+.ft B
+acl_check(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_add(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_initialize(acl_file, mode)
+char *acl_file;
+int mode;
+.fi
+.ft R
+.SH DESCRIPTION
+.SS Introduction
+.PP
+An access control list (ACL) is a list of principals, where each
+principal is represented by a text string which cannot contain
+whitespace.  The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface.  At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+.PP
+.SS Principal Names
+.PP
+Principal names have the form
+.nf
+.in +5n
+<name>[.<instance>][@<realm>]
+.in -5n
+e.g.:
+.in +5n
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+.in -5n
+.fi
+It is possible for principals to be underspecified.  If an instance is
+missing, it is assumed to be "".  If realm is missing, it is assumed
+to be the local realm as determined by
+.IR krb_get_lrealm (3).
+The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form.  Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+.SS Routines
+.PP
+.I acl_canonicalize_principal
+stores the canonical form of 
+.I principal
+in 
+.IR buf .
+.I Buf
+must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ,
+respectively, in
+.IR /usr/include/krb.h .
+.PP
+.I acl_check
+returns nonzero if
+.I principal
+appears in 
+.IR acl .
+Returns 0 if principal
+does not appear in acl, or if an error occurs.  Canonicalizes
+principal before checking, and allows the ACL to contain wildcards.  The
+only supported wildcards are entries of the form
+name.*@realm, *.*@realm, and *.*@*.  An asterisk matches any value for the
+its component field.  For example, "jtkohl.*@*" would match principal
+jtkohl, with any instance and any realm.
+.PP
+.I acl_exact_match
+performs like 
+.IR acl_check ,
+but does no canonicalization or wildcard matching.
+.PP
+.I acl_add
+atomically adds 
+.I principal
+to 
+.IR acl .
+Returns 0 if successful, nonzero otherwise.  It is considered a failure
+if
+.I principal
+is already in 
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_delete
+atomically deletes 
+.I principal
+from 
+.IR acl .
+Returns 0 if successful,
+nonzero otherwise.  It is considered a failure if 
+.I principal
+is not
+already in 
+.IR acl .
+This routine will canonicalize 
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_initialize
+initializes
+.IR acl_file .
+If the file 
+.I acl_file
+does not exist,
+.I acl_initialize
+creates it with mode
+.IR mode .
+If the file
+.I acl_file
+exists,
+.I acl_initialize
+removes all members.  Returns 0 if successful,
+nonzero otherwise.  WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.  
+.SH NOTES
+In the presence of concurrency, there is a very small chance that
+.I acl_add
+or
+.I acl_delete
+could report success even though it would have
+had no effect.  This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+.PP
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
+.SH SEE ALSO
+kerberos(3), krb_get_lrealm(3)
+.SH AUTHOR
+James Aspnes (MIT Project Athena)
diff --git a/kerberosIV/acl/acl_files.c b/kerberosIV/acl/acl_files.c
new file mode 100644 (file)
index 0000000..cc9dd5e
--- /dev/null
@@ -0,0 +1,557 @@
+/*     $Id: acl_files.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $      */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include <kerberosIV/site.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <ctype.h>
+
+#include <kerberosIV/krb.h>
+#include <kerberosIV/acl.h>
+
+/*** Routines for manipulating access control list files ***/
+
+/* "aname.inst@realm" */
+#define MAX_PRINCIPAL_SIZE  (ANAME_SZ + INST_SZ + REALM_SZ + 3)
+#define INST_SEP '.'
+#define REALM_SEP '@'
+
+#define LINESIZE 2048          /* Maximum line length in an acl file */
+
+#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
+#define WAIT_TIME 300          /* Maximum time allowed write acl file */
+
+#define CACHED_ACLS 8          /* How many acls to cache */
+                               /* Each acl costs 1 open file descriptor */
+#define ACL_LEN 16             /* Twice a reasonable acl length */
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#define COR(a,b) ((a!=NULL)?(a):(b))
+
+/* Canonicalize a principal name */
+/* If instance is missing, it becomes "" */
+/* If realm is missing, it becomes the local realm */
+/* Canonicalized form is put in canon, which must be big enough to hold
+   MAX_PRINCIPAL_SIZE characters */
+void
+acl_canonicalize_principal(principal, canon)
+       char *principal;
+       char *canon;
+{
+    char *dot, *atsign, *end;
+    int len;
+
+    dot = strchr(principal, INST_SEP);
+    atsign = strchr(principal, REALM_SEP);
+
+    /* Maybe we're done already */
+    if(dot != NULL && atsign != NULL) {
+       if(dot < atsign) {
+           /* It's for real */
+           /* Copy into canon */
+           strncpy(canon, principal, MAX_PRINCIPAL_SIZE);
+           canon[MAX_PRINCIPAL_SIZE-1] = '\0';
+           return;
+       } else {
+           /* Nope, it's part of the realm */
+           dot = NULL;
+       }
+    }
+    
+    /* No such luck */
+    end = principal + strlen(principal);
+
+    /* Get the principal name */
+    len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal);
+    strncpy(canon, principal, len);
+    canon += len;
+
+    /* Add INST_SEP */
+    *canon++ = INST_SEP;
+
+    /* Get the instance, if it exists */
+    if(dot != NULL) {
+       ++dot;
+       len = MIN(INST_SZ, COR(atsign, end) - dot);
+       strncpy(canon, dot, len);
+       canon += len;
+    }
+
+    /* Add REALM_SEP */
+    *canon++ = REALM_SEP;
+
+    /* Get the realm, if it exists */
+    /* Otherwise, default to local realm */
+    if(atsign != NULL) {
+       ++atsign;
+       len = MIN(REALM_SZ, end - atsign);
+       strncpy(canon, atsign, len);
+       canon += len;
+       *canon++ = '\0';
+    } else if(krb_get_lrealm(canon, 1) != KSUCCESS) {
+       strcpy(canon, KRB_REALM);
+    }
+}
+           
+/* Get a lock to modify acl_file */
+/* Return new FILE pointer */
+/* or NULL if file cannot be modified */
+/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
+static FILE *
+acl_lock_file(acl_file)
+       char *acl_file;
+{
+    struct stat s;
+    char new[LINESIZE];
+    int nfd;
+    FILE *nf;
+    int mode;
+
+    if(stat(acl_file, &s) < 0) return(NULL);
+    mode = s.st_mode;
+    sprintf(new, NEW_FILE, acl_file);
+    for(;;) {
+       /* Open the new file */
+       if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
+           if(errno == EEXIST) {
+               /* Maybe somebody got here already, maybe it's just old */
+               if(stat(new, &s) < 0) return(NULL);
+               if(time(0) - s.st_ctime > WAIT_TIME) {
+                   /* File is stale, kill it */
+                   unlink(new);
+                   continue;
+               } else {
+                   /* Wait and try again */
+                   sleep(1);
+                   continue;
+               }
+           } else {
+               /* Some other error, we lose */
+               return(NULL);
+           }
+       }
+
+       /* If we got to here, the lock file is ours and ok */
+       /* Reopen it under stdio */
+       if((nf = fdopen(nfd, "w")) == NULL) {
+           /* Oops, clean up */
+           unlink(new);
+       }
+       return(nf);
+    }
+}
+
+/* Abort changes to acl_file written onto FILE *f */
+/* Returns 0 if successful, < 0 otherwise */
+/* Closes f */
+static int
+acl_abort(acl_file, f)
+       char *acl_file;
+       FILE *f;
+{
+    char new[LINESIZE];
+    int ret;
+    struct stat s;
+
+    /* make sure we aren't nuking someone else's file */
+    if(fstat(fileno(f), &s) < 0
+       || s.st_nlink == 0) {
+          fclose(f);
+          return(-1);
+       } else {
+          sprintf(new, NEW_FILE, acl_file);
+          ret = unlink(new);
+          fclose(f);
+          return(ret);
+       }
+}
+
+/* Commit changes to acl_file written onto FILE *f */
+/* Returns zero if successful */
+/* Returns > 0 if lock was broken */
+/* Returns < 0 if some other error occurs */
+/* Closes f */
+static int
+acl_commit(acl_file, f)
+       char *acl_file;
+       FILE *f;
+{
+    char new[LINESIZE];
+    int ret;
+    struct stat s;
+
+    sprintf(new, NEW_FILE, acl_file);
+    if(fflush(f) < 0
+       || fstat(fileno(f), &s) < 0
+       || s.st_nlink == 0) {
+       acl_abort(acl_file, f);
+       return(-1);
+    }
+
+    ret = rename(new, acl_file);
+    fclose(f);
+    return(ret);
+}
+
+/* Initialize an acl_file */
+/* Creates the file with permissions perm if it does not exist */
+/* Erases it if it does */
+/* Returns return value of acl_commit */
+int
+acl_initialize(acl_file, perm)
+       char *acl_file;
+       int perm;
+{
+    FILE *new;
+    int fd;
+
+    /* Check if the file exists already */
+    if((new = acl_lock_file(acl_file)) != NULL) {
+       return(acl_commit(acl_file, new));
+    } else {
+       /* File must be readable and writable by owner */
+       if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
+           return(-1);
+       } else {
+           close(fd);
+           return(0);
+       }
+    }
+}
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static void
+nuke_whitespace(buf)
+       char *buf;
+{
+    register char *pin, *pout;
+
+    for(pin = pout = buf; *pin != '\0'; pin++)
+       if(!isspace(*pin)) *pout++ = *pin;
+    *pout = '\0';              /* Terminate the string */
+}
+
+/* Hash table stuff */
+
+struct hashtbl {
+    int size;                  /* Max number of entries */
+    int entries;               /* Actual number of entries */
+    char **tbl;                        /* Pointer to start of table */
+};
+
+/* Make an empty hash table of size s */
+static struct hashtbl *
+make_hash(size)
+       int size;
+{
+    struct hashtbl *h;
+
+    if(size < 1) size = 1;
+    h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
+    h->size = size;
+    h->entries = 0;
+    h->tbl = (char **) calloc(size, sizeof(char *));
+    return(h);
+}
+
+/* Destroy a hash table */
+static void
+destroy_hash(h)
+       struct hashtbl *h;
+{
+    int i;
+
+    for(i = 0; i < h->size; i++) {
+       if(h->tbl[i] != NULL) free(h->tbl[i]);
+    }
+    free(h->tbl);
+    free(h);
+}
+
+/* Compute hash value for a string */
+static unsigned int
+hashval(s)
+       register char *s;
+{
+    register unsigned hv;
+
+    for(hv = 0; *s != '\0'; s++) {
+       hv ^= ((hv << 3) ^ *s);
+    }
+    return(hv);
+}
+
+/* Add an element to a hash table */
+static void
+add_hash(h, el)
+       struct hashtbl *h;
+       char *el;
+{
+    unsigned hv;
+    char *s;
+    char **old;
+    int i;
+
+    /* Make space if it isn't there already */
+    if(h->entries + 1 > (h->size >> 1)) {
+       old = h->tbl;
+       h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
+       for(i = 0; i < h->size; i++) {
+           if(old[i] != NULL) {
+               hv = hashval(old[i]) % (h->size << 1);
+               while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
+               h->tbl[hv] = old[i];
+           }
+       }
+       h->size = h->size << 1;
+       free(old);
+    }
+
+    hv = hashval(el) % h->size;
+    while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
+    s = malloc(strlen(el)+1);
+    strcpy(s, el);
+    h->tbl[hv] = s;
+    h->entries++;
+}
+
+/* Returns nonzero if el is in h */
+static int
+check_hash(h, el)
+       struct hashtbl *h;
+       char *el;
+{
+    unsigned hv;
+
+    for(hv = hashval(el) % h->size;
+       h->tbl[hv] != NULL;
+       hv = (hv + 1) % h->size) {
+           if(!strcmp(h->tbl[hv], el)) return(1);
+       }
+    return(0);
+}
+
+struct acl {
+    char filename[LINESIZE];   /* Name of acl file */
+    int fd;                    /* File descriptor for acl file */
+    struct stat status;                /* File status at last read */
+    struct hashtbl *acl;       /* Acl entries */
+};
+
+static struct acl acl_cache[CACHED_ACLS];
+
+static int acl_cache_count = 0;
+static int acl_cache_next = 0;
+
+/* Returns < 0 if unsuccessful in loading acl */
+/* Returns index into acl_cache otherwise */
+/* Note that if acl is already loaded, this is just a lookup */
+static int
+acl_load(name)
+       char *name;
+{
+    int i;
+    FILE *f;
+    struct stat s;
+    char buf[MAX_PRINCIPAL_SIZE];
+    char canon[MAX_PRINCIPAL_SIZE];
+
+    /* See if it's there already */
+    for(i = 0; i < acl_cache_count; i++) {
+       if(!strcmp(acl_cache[i].filename, name)
+          && acl_cache[i].fd >= 0) goto got_it;
+    }
+
+    /* It isn't, load it in */
+    /* maybe there's still room */
+    if(acl_cache_count < CACHED_ACLS) {
+       i = acl_cache_count++;
+    } else {
+       /* No room, clean one out */
+       i = acl_cache_next;
+       acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
+       close(acl_cache[i].fd);
+       if(acl_cache[i].acl) {
+           destroy_hash(acl_cache[i].acl);
+           acl_cache[i].acl = (struct hashtbl *) 0;
+       }
+    }
+
+    /* Set up the acl */
+    strcpy(acl_cache[i].filename, name);
+    if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+    /* Force reload */
+    acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+    /*
+     * See if the stat matches
+     *
+     * Use stat(), not fstat(), as the file may have been re-created by
+     * acl_add or acl_delete.  If this happens, the old inode will have
+     * no changes in the mod-time and the following test will fail.
+     */
+    if(stat(acl_cache[i].filename, &s) < 0) return(-1);
+    if(acl_cache[i].acl == (struct hashtbl *) 0
+       || s.st_nlink != acl_cache[i].status.st_nlink
+       || s.st_mtime != acl_cache[i].status.st_mtime
+       || s.st_ctime != acl_cache[i].status.st_ctime) {
+          /* Gotta reload */
+          if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
+          if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+          if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
+          if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+          acl_cache[i].acl = make_hash(ACL_LEN);
+          while(fgets(buf, sizeof(buf), f) != NULL) {
+              nuke_whitespace(buf);
+              acl_canonicalize_principal(buf, canon);
+              add_hash(acl_cache[i].acl, canon);
+          }
+          fclose(f);
+          acl_cache[i].status = s;
+       }
+    return(i);
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+int
+acl_exact_match(acl, principal)
+       char *acl;
+       char *principal;
+{
+    int idx;
+
+    return((idx = acl_load(acl)) >= 0
+          && check_hash(acl_cache[idx].acl, principal));
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Recognizes wildcards in acl of the form
+   name.*@realm, *.*@realm, and *.*@* */
+int
+acl_check(acl, principal)
+       char *acl;
+       char *principal;
+{
+    char buf[MAX_PRINCIPAL_SIZE];
+    char canon[MAX_PRINCIPAL_SIZE];
+    char *realm;
+
+    acl_canonicalize_principal(principal, canon);
+
+    /* Is it there? */
+    if(acl_exact_match(acl, canon)) return(1);
+
+    /* Try the wildcards */
+    realm = strchr(canon, REALM_SEP);
+    *strchr(canon, INST_SEP) = '\0';   /* Chuck the instance */
+
+    sprintf(buf, "%s.*%s", canon, realm);
+    if(acl_exact_match(acl, buf)) return(1);
+
+    sprintf(buf, "*.*%s", realm);
+    if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
+       
+    return(0);
+}
+
+/* Adds principal to acl */
+/* Wildcards are interpreted literally */
+int
+acl_add(acl, principal)
+       char *acl;
+       char *principal;
+{
+    int idx;
+    int i;
+    FILE *new;
+    char canon[MAX_PRINCIPAL_SIZE];
+
+    acl_canonicalize_principal(principal, canon);
+
+    if((new = acl_lock_file(acl)) == NULL) return(-1);
+    if((acl_exact_match(acl, canon))
+       || (idx = acl_load(acl)) < 0) {
+          acl_abort(acl, new);
+          return(-1);
+       }
+    /* It isn't there yet, copy the file and put it in */
+    for(i = 0; i < acl_cache[idx].acl->size; i++) {
+       if(acl_cache[idx].acl->tbl[i] != NULL) {
+           if(fputs(acl_cache[idx].acl->tbl[i], new) == 0
+              || putc('\n', new) != '\n') {
+                  acl_abort(acl, new);
+                  return(-1);
+              }
+       }
+    }
+    fputs(canon, new);
+    putc('\n', new);
+    return(acl_commit(acl, new));
+}
+
+/* Removes principal from acl */
+/* Wildcards are interpreted literally */
+int
+acl_delete(acl, principal)
+       char *acl;
+       char *principal;
+{
+    int idx;
+    int i;
+    FILE *new;
+    char canon[MAX_PRINCIPAL_SIZE];
+
+    acl_canonicalize_principal(principal, canon);
+
+    if((new = acl_lock_file(acl)) == NULL) return(-1);
+    if((!acl_exact_match(acl, canon))
+       || (idx = acl_load(acl)) < 0) {
+          acl_abort(acl, new);
+          return(-1);
+       }
+    /* It isn't there yet, copy the file and put it in */
+    for(i = 0; i < acl_cache[idx].acl->size; i++) {
+       if(acl_cache[idx].acl->tbl[i] != NULL
+          && strcmp(acl_cache[idx].acl->tbl[i], canon)) {
+              fputs(acl_cache[idx].acl->tbl[i], new);
+              putc('\n', new);
+       }
+    }
+    return(acl_commit(acl, new));
+}
diff --git a/kerberosIV/acl/shlib_version b/kerberosIV/acl/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/com_err/Makefile b/kerberosIV/com_err/Makefile
new file mode 100644 (file)
index 0000000..709fc81
--- /dev/null
@@ -0,0 +1,8 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $
+
+LIB=   com_err
+SRCS=  com_err.c error_message.c et_name.c init_et.c
+CFLAGS+=-I${.CURDIR}
+MAN=   com_err.3
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/com_err/com_err.3 b/kerberosIV/com_err/com_err.3
new file mode 100644 (file)
index 0000000..7be3a64
--- /dev/null
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1988 Massachusetts Institute of Technology,
+.\" Student Information Processing Board.  All rights reserved.
+.\"
+.\" $Id: com_err.3,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $
+.TH COM_ERR 3 "22 Nov 1988" SIPB
+.SH NAME
+com_err \- common error display routine
+.SH SYNOPSIS
+.nf
+ #include <com_err.h>
+.PP
+void com_err (whoami, code, format, ...);
+       const char *whoami;
+       long code;
+       const char *format;
+.PP
+proc = set_com_err_hook (proc);
+.fi
+void (*
+.I proc
+) (const char *, long, const char *, va_list);
+.nf
+.PP
+proc = reset_com_err_hook ();
+.PP
+void initialize_XXXX_error_table ();
+.fi
+.SH DESCRIPTION
+.I Com_err
+displays an error message on the standard error stream
+.I stderr
+(see
+.IR stdio (3S))
+composed of the
+.I whoami
+string, which should specify the program name or some subportion of
+a program, followed by an error message generated from the
+.I code
+value (derived from
+.IR compile_et (1)),
+and a string produced using the
+.I format
+string and any following arguments, in the same style as
+.IR fprintf (3).
+
+The behavior of
+.I com_err
+can be modified using
+.I set_com_err_hook;
+this defines a procedure which is called with the arguments passed to
+.I com_err,
+instead of the default internal procedure which sends the formatted
+text to error output.  Thus the error messages from a program can all
+easily be diverted to another form of diagnostic logging, such as
+.IR syslog (3).
+.I Reset_com_err_hook
+may be used to restore the behavior of
+.I com_err
+to its default form.  Both procedures return the previous ``hook''
+value.  These ``hook'' procedures must have the declaration given for
+.I proc
+above in the synopsis.
+
+The
+.I initialize_XXXX_error_table
+routine is generated mechanically by
+.IR compile_et (1)
+from a source file containing names and associated strings.  Each
+table has a name of up to four characters, which is used in place of
+the
+.B XXXX
+in the name of the routine.  These routines should be called before
+any of the corresponding error codes are used, so that the
+.I com_err
+library will recognize error codes from these tables when they are
+used.
+
+The
+.B com_err.h
+header file should be included in any source file that uses routines
+from the
+.I com_err
+library; executable files must be linked using
+.I ``-lcom_err''
+in order to cause the
+.I com_err
+library to be included.
+
+.\" .IR for manual entries
+.\" .PP for paragraph breaks
+
+.SH "SEE ALSO"
+compile_et (1), syslog (3).
+
+Ken Raeburn, "A Common Error Description Library for UNIX".
diff --git a/kerberosIV/com_err/com_err.c b/kerberosIV/com_err/com_err.c
new file mode 100644 (file)
index 0000000..415cb83
--- /dev/null
@@ -0,0 +1,151 @@
+/*     $Id: com_err.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+
+#if __STDC__
+#  undef VARARGS
+#  include <stdarg.h>
+#else
+#  undef VARARGS
+#  define VARARGS 1
+#  include <varargs.h>
+#endif
+
+#include "kerberosIV/com_err.h"
+#include "error_table.h"
+
+/*
+ * Protect us from header version (externally visible) of com_err, so
+ * we can survive in a <varargs.h> environment.  I think.
+ */
+#if VARARGS
+#define com_err com_err_external
+#include "kerberosIV/com_err.h"
+#undef com_err
+#endif
+
+#ifdef NPOSIX
+#undef vfprintf
+#define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream)
+#endif
+
+#if !defined(lint)
+static const char rcsid[] =
+    "$Id: com_err.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $";
+#endif /* ! lint */
+
+static void
+#ifdef __STDC__
+    default_com_err_proc (const char *whoami, long code, const char *fmt, va_list args)
+#else
+    default_com_err_proc (whoami, code, fmt, args)
+    const char *whoami;
+    long code;
+    const char *fmt;
+    va_list args;
+#endif
+{
+    if (whoami) {
+       fputs(whoami, stderr);
+       fputs(": ", stderr);
+    }
+#ifdef SOLARIS
+    if (code) {
+       fputs(error_message(code), stderr);
+       fputs(" ", stderr);
+    } else {
+        vfprintf (stderr, fmt, args);
+    }
+#else
+    if (code) {
+       fputs(error_message(code), stderr);
+       fputs(" ", stderr);
+    }
+    if (fmt) {
+        vfprintf (stderr, fmt, args);
+    }
+#endif
+    putc('\n', stderr);
+    /* should do this only on a tty in raw mode */
+    putc('\r', stderr);
+    fflush(stderr);
+}
+
+typedef void (*errf) __P((const char *, long, const char *, va_list));
+
+errf com_err_hook = default_com_err_proc;
+
+void com_err_va (whoami, code, fmt, args)
+    const char *whoami;
+    long code;
+    const char *fmt;
+    va_list args;
+{
+  if (! com_err_hook)
+        com_err_hook = default_com_err_proc;
+    (*com_err_hook) (whoami, code, fmt, args);
+}
+
+#if ! VARARGS
+void com_err (const char *whoami,
+             long code,
+             const char *fmt, ...)
+{
+#else
+void com_err (va_alist)
+    va_dcl
+{
+    const char *whoami, *fmt;
+    long code;
+#endif
+    va_list pvar;
+
+    if (!com_err_hook)
+       com_err_hook = default_com_err_proc;
+#if VARARGS
+    va_start (pvar);
+    whoami = va_arg (pvar, const char *);
+    code = va_arg (pvar, long);
+    fmt = va_arg (pvar, const char *);
+#else
+    va_start(pvar, fmt);
+#endif
+    com_err_va (whoami, code, fmt, pvar);
+    va_end(pvar);
+}
+
+errf set_com_err_hook (new_proc)
+    errf new_proc;
+{
+    errf x = com_err_hook;
+
+    if (new_proc)
+       com_err_hook = new_proc;
+    else
+       com_err_hook = default_com_err_proc;
+
+    return x;
+}
+
+errf reset_com_err_hook () {
+    errf x = com_err_hook;
+    com_err_hook = default_com_err_proc;
+    return x;
+}
diff --git a/kerberosIV/com_err/error_message.c b/kerberosIV/com_err/error_message.c
new file mode 100644 (file)
index 0000000..601a4e1
--- /dev/null
@@ -0,0 +1,79 @@
+/*     $Id: error_message.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "error_table.h"
+
+static const char rcsid[] =
+    "$Id: error_message.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $";
+static const char copyright[] =
+    "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology";
+
+static char buffer[25];
+
+struct et_list * _et_list = (struct et_list *) NULL;
+
+const char *
+error_message (code)
+       long    code;
+{
+    int offset;
+    struct et_list *et;
+    int table_num;
+    int started = 0;
+    char *cp;
+
+    offset = code & ((1<<ERRCODE_RANGE)-1);
+    table_num = code - offset;
+    if (!table_num) {
+       if (offset < sys_nerr)
+           return(sys_errlist[offset]);
+       else
+           goto oops;
+    }
+    for (et = _et_list; et; et = et->next) {
+       if (et->table->base == table_num) {
+           /* This is the right table */
+           if (et->table->n_msgs <= offset)
+               goto oops;
+           return(et->table->msgs[offset]);
+       }
+    }
+oops:
+    strcpy (buffer, "Unknown code ");
+    if (table_num) {
+       strcat (buffer, error_table_name (table_num));
+       strcat (buffer, " ");
+    }
+    for (cp = buffer; *cp; cp++)
+       ;
+    if (offset >= 100) {
+       *cp++ = '0' + offset / 100;
+       offset %= 100;
+       started++;
+    }
+    if (started || offset >= 10) {
+       *cp++ = '0' + offset / 10;
+       offset %= 10;
+    }
+    *cp++ = '0' + offset;
+    *cp = '\0';
+    return(buffer);
+}
diff --git a/kerberosIV/com_err/error_table.h b/kerberosIV/com_err/error_table.h
new file mode 100644 (file)
index 0000000..a967753
--- /dev/null
@@ -0,0 +1,41 @@
+/*     $Id: error_table.h,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#ifndef _ET_H
+#define _ET_H
+
+struct error_table {
+    char const * const * msgs;
+    long base;
+    int n_msgs;
+};
+
+struct et_list {
+    struct et_list *next;
+    const struct error_table *table;
+};
+
+extern struct et_list * _et_list;
+
+#define        ERRCODE_RANGE   8       /* # of bits to shift table number */
+#define        BITS_PER_CHAR   6       /* # bits to shift per character in name */
+
+extern const char *error_table_name();
+
+#endif
diff --git a/kerberosIV/com_err/et_name.c b/kerberosIV/com_err/et_name.c
new file mode 100644 (file)
index 0000000..68267d8
--- /dev/null
@@ -0,0 +1,55 @@
+/*     $Id: et_name.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include "error_table.h"
+
+#ifndef        lint
+static const char copyright[] =
+    "Copyright 1987,1988 by Student Information Processing Board, Massachusetts Institute of Technology";
+static const char rcsid_et_name_c[] =
+    "$Id: et_name.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $";
+#endif
+
+static const char char_set[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+static char buf[6];
+
+const char *
+error_table_name(num)
+    int num;
+{
+    int ch;
+    int i;
+    char *p;
+
+    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+    p = buf;
+    num >>= ERRCODE_RANGE;
+    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+    num &= 077777777;
+    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+    for (i = 4; i >= 0; i--) {
+       ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
+       if (ch != 0)
+           *p++ = char_set[ch-1];
+    }
+    *p = '\0';
+    return(buf);
+}
diff --git a/kerberosIV/com_err/init_et.c b/kerberosIV/com_err/init_et.c
new file mode 100644 (file)
index 0000000..b2b8602
--- /dev/null
@@ -0,0 +1,63 @@
+/*     $Id: init_et.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "error_table.h"
+
+#ifndef __STDC__
+#define const
+#endif
+
+#ifndef        lint
+static const char rcsid_init_et_c[] =
+    "$Id: init_et.c,v 1.1.1.1 1995/12/14 06:52:32 tholo Exp $";
+#endif
+
+struct foobar {
+    struct et_list etl;
+    struct error_table et;
+};
+
+extern struct et_list * _et_list;
+
+int
+init_error_table(msgs, base, count)
+    const char * const * msgs;
+    int base;
+    int count;
+{
+    struct foobar * new_et;
+
+    if (!base || !count || !msgs)
+       return 0;
+
+    new_et = (struct foobar *) malloc(sizeof(struct foobar));
+    if (!new_et)
+       return errno;   /* oops */
+    new_et->etl.table = &new_et->et;
+    new_et->et.msgs = msgs;
+    new_et->et.base = base;
+    new_et->et.n_msgs= count;
+
+    new_et->etl.next = _et_list;
+    _et_list = &new_et->etl;
+    return 0;
+}
diff --git a/kerberosIV/compile_et/Makefile b/kerberosIV/compile_et/Makefile
new file mode 100644 (file)
index 0000000..d3d3abc
--- /dev/null
@@ -0,0 +1,15 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $
+
+PROG=  compile_et
+SRCS=  compile_et.c error_table.y #et_lex.lex.l
+CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../com_err
+DPADD= ${LIBL}
+LDADD= -ll
+CLEANFILES=error_table.c y.tab.h et_lex.lex.c
+
+beforedepend:  et_lex.lex.c
+error_table.o: et_lex.lex.c
+
+install:
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/compile_et/compile_et.1 b/kerberosIV/compile_et/compile_et.1
new file mode 100644 (file)
index 0000000..7606d90
--- /dev/null
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1988 Massachusetts Institute of Technology,
+.\" Student Information Processing Board.  All rights reserved.
+.\"
+.\" $Id: compile_et.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $
+.\"
+.TH COMPILE_ET 1 "22 Nov 1988" SIPB
+.SH NAME
+compile_et \- error table compiler
+.SH SYNOPSIS
+.B compile_et
+file
+.SH DESCRIPTION
+.B Compile_et
+converts a table listing error-code names and associated messages into
+a C source file suitable for use with the
+.IR com_err (3)
+library.
+
+The source file name must end with a suffix of ``.et''; the file
+consists of a declaration supplying the name (up to four characters
+long) of the error-code table:
+
+.B error_table
+.I name
+
+followed by up to 256 entries of the form:
+
+.B error_code
+.I name,
+"
+.I string
+"
+
+and a final
+
+.B end
+
+to indicate the end of the table.
+
+The name of the table is used to construct the name of a subroutine
+.I initialize_XXXX_error_table
+which must be called in order for the
+.I com_err
+library to recognize the error table.
+
+The various error codes defined are assigned sequentially increasing
+numbers (starting with a large number computed as a hash function of
+the name of the table); thus for compatibility it is suggested that
+new codes be added only to the end of an existing table, and that no
+codes be removed from tables.
+
+The names defined in the table are placed into a C header file with
+preprocessor directives defining them as integer constants of up to
+32 bits in magnitude.
+
+A C source file is also generated which should be compiled and linked
+with the object files which reference these error codes; it contains
+the text of the messages and the initialization subroutine.  Both C
+files have names derived from that of the original source file, with
+the ``.et'' suffix replaced by ``.c'' and ``.h''.
+
+A ``#'' in the source file is treated as a comment character, and all
+remaining text to the end of the source line will be ignored.
+
+.SH BUGS
+
+Since
+.B compile_et
+uses a very simple parser based on
+.IR yacc (1),
+its error recovery leaves much to be desired.
+
+.\" .IR for manual entries
+.\" .PP for paragraph breaks
+
+.SH "SEE ALSO"
+com_err (3).
+
+Ken Raeburn, "A Common Error Description Library for UNIX".
diff --git a/kerberosIV/compile_et/compile_et.c b/kerberosIV/compile_et/compile_et.c
new file mode 100644 (file)
index 0000000..4bd9676
--- /dev/null
@@ -0,0 +1,289 @@
+/*     $id$    */
+
+/*
+ * Copyright 1986, 1987, 1988
+ * by MIT Student Information Processing Board.
+ *
+ * For copyright info, see "mit-sipb-copyright.h".
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <string.h>
+#include <sys/param.h>
+#include "compiler.h"
+
+#ifndef __STDC__
+#define const
+#endif
+
+#ifndef lint
+static const char copyright[] =
+    "Copyright 1987,1988 by MIT Student Information Processing Board";
+
+static const char rcsid_compile_et_c[] =
+    "$Id: compile_et.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $";
+#endif
+
+extern char *gensym();
+extern char *current_token;
+extern int table_number, current;
+char buffer[BUFSIZ];
+char *table_name = (char *)NULL;
+FILE *hfile, *cfile;
+
+/* C library */
+extern char *malloc();
+extern int errno;
+
+/* lex stuff */
+extern FILE *yyin;
+extern unsigned lineno;
+
+char * xmalloc (size) unsigned int size; {
+    char * p = malloc (size);
+    if (!p) {
+       perror (whoami);
+       exit (1);
+    }
+    return p;
+}
+
+static int check_arg (str_list, arg) char const *const *str_list, *arg; {
+    while (*str_list)
+       if (!strcmp(arg, *str_list++))
+           return 1;
+    return 0;
+}
+
+static const char *const debug_args[] = {
+    "d",
+    "debug",
+    0,
+};
+
+static const char *const lang_args[] = {
+    "lang",
+    "language",
+    0,
+};
+
+static const char *const language_names[] = {
+    "C",
+    "K&R C",
+    "C++",
+    0,
+};
+
+static const char * const c_src_prolog[] = {
+    "static const char * const text[] = {\n",
+    0,
+};
+
+static const char * const krc_src_prolog[] = {
+    "#ifdef __STDC__\n",
+    "#define NOARGS void\n",
+    "#else\n",
+    "#define NOARGS\n",
+    "#define const\n",
+    "#endif\n\n",
+    "static const char * const text[] = {\n",
+    0,
+};
+
+static const char *const struct_def[] = {
+    "struct error_table {\n",
+    "    char const * const * msgs;\n",
+    "    long base;\n",
+    "    int n_msgs;\n",
+    "};\n",
+    "struct et_list {\n",
+    "    struct et_list *next;\n",
+    "    const struct error_table * table;\n",
+    "};\n",
+    "extern struct et_list *_et_list;\n",
+    "\n", 0,
+};
+
+static const char warning[] =
+    "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
+
+/* pathnames */
+char c_file[MAXPATHLEN];       /* output file */
+char h_file[MAXPATHLEN];       /* output */
+
+static void usage () {
+    fprintf (stderr, "%s: usage: %s ERROR_TABLE\n",
+            whoami, whoami);
+    exit (1);
+}
+
+static void dup_err (type, one, two) char const *type, *one, *two; {
+    fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n",
+            whoami, type, one, two);
+    usage ();
+}
+
+int main (argc, argv) int argc; char **argv; {
+    char *p, *ename;
+    int len;
+    char const * const *cpp;
+    int got_language = 0;
+
+    /* argument parsing */
+    debug = 0;
+    filename = 0;
+    whoami = argv[0];
+    p = strrchr (whoami, '/');
+    if (p)
+       whoami = p+1;
+    while (argv++, --argc) {
+       char *arg = *argv;
+       if (arg[0] != '-') {
+           if (filename)
+               dup_err ("filenames", filename, arg);
+           filename = arg;
+       }
+       else {
+           arg++;
+           if (check_arg (debug_args, arg))
+               debug++;
+           else if (check_arg (lang_args, arg)) {
+               got_language++;
+               arg = *++argv, argc--;
+               if (!arg)
+                   usage ();
+               if (language)
+                   dup_err ("languanges", language_names[(int)language], arg);
+#define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v
+               check_lang ("c", lang_C);
+               check_lang ("ansi_c", lang_C);
+               check_lang ("ansi-c", lang_C);
+               check_lang ("krc", lang_KRC);
+               check_lang ("kr_c", lang_KRC);
+               check_lang ("kr-c", lang_KRC);
+               check_lang ("k&r-c", lang_KRC);
+               check_lang ("k&r_c", lang_KRC);
+               check_lang ("c++", lang_CPP);
+               check_lang ("cplusplus", lang_CPP);
+               check_lang ("c-plus-plus", lang_CPP);
+#undef check_lang
+               else {
+                   fprintf (stderr, "%s: unknown language name `%s'\n",
+                            whoami, arg);
+                   fprintf (stderr, "\tpick one of: C K&R-C\n");
+                   exit (1);
+               }
+           }
+           else {
+               fprintf (stderr, "%s: unknown control argument -`%s'\n",
+                        whoami, arg);
+               usage ();
+           }
+       }
+    }
+    if (!filename)
+       usage ();
+    if (!got_language)
+       language = lang_KRC;
+    else if (language == lang_CPP) {
+       fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n",
+                whoami);
+       exit (1);
+    }
+
+    p = xmalloc (strlen (filename) + 5);
+    strcpy (p, filename);
+    filename = p;
+    p = strrchr(filename, '/');
+    if (p == (char *)NULL)
+       p = filename;
+    else
+       p++;
+    ename = p;
+    len = strlen (ename);
+    p += len - 3;
+    if (strcmp (p, ".et"))
+       p += 3;
+    *p++ = '.';
+    /* now p points to where "et" suffix should start */
+    /* generate new filenames */
+    strcpy (p, "c");
+    strcpy (c_file, ename);
+    *p = 'h';
+    strcpy (h_file, ename);
+    strcpy (p, "et");
+
+    yyin = fopen(filename, "r");
+    if (!yyin) {
+       perror(filename);
+       exit(1);
+    }
+
+    hfile = fopen(h_file, "w");
+    if (hfile == (FILE *)NULL) {
+       perror(h_file);
+       exit(1);
+    }
+    fprintf (hfile, warning, h_file);
+
+    cfile = fopen(c_file, "w");
+    if (cfile == (FILE *)NULL) {
+       perror(c_file);
+       exit(1);
+    }
+    fprintf (cfile, warning, c_file);
+
+    /* prologue */
+    if (language == lang_C)
+       cpp = c_src_prolog;
+    else if (language == lang_KRC)
+       cpp = krc_src_prolog;
+    else
+       abort ();
+    while (*cpp)
+       fputs (*cpp++, cfile);
+
+    /* parse it */
+    yyparse();
+    fclose(yyin);              /* bye bye input file */
+
+    fputs ("    0\n};\n\n", cfile);
+    for (cpp = struct_def; *cpp; cpp++)
+       fputs (*cpp, cfile);
+    fprintf(cfile,
+           "static const struct error_table et = { text, %ldL, %d };\n\n",
+           table_number, current);
+    fputs("static struct et_list link = { 0, 0 };\n\n",
+         cfile);
+    fprintf(cfile, "void initialize_%s_error_table (%s) {\n",
+           table_name, (language == lang_C) ? "void" : "NOARGS");
+    fputs("    if (!link.table) {\n", cfile);
+    fputs("        link.next = _et_list;\n", cfile);
+    fputs("        link.table = &et;\n", cfile);
+    fputs("        _et_list = &link;\n", cfile);
+    fputs("    }\n", cfile);
+    fputs("}\n", cfile);
+    fclose(cfile);
+
+    fprintf (hfile, "extern void initialize_%s_error_table ();\n",
+            table_name);
+    fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n",
+            table_name, table_number);
+    /* compatibility... */
+    fprintf (hfile, "\n/* for compatibility with older versions... */\n");
+    fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
+            table_name, table_name);
+    fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
+            table_name);
+    fclose(hfile);             /* bye bye include file */
+
+    return 0;
+}
+
+int yyerror(s) char *s; {
+    fputs(s, stderr);
+    fprintf(stderr, "\nLine number %d; last token was '%s'\n",
+           lineno, current_token);
+}
diff --git a/kerberosIV/compile_et/compiler.h b/kerberosIV/compile_et/compiler.h
new file mode 100644 (file)
index 0000000..0f9ac1b
--- /dev/null
@@ -0,0 +1,22 @@
+/*     $Id: compiler.h,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $       */
+
+/*
+ * definitions common to the source files of the error table compiler
+ */
+
+#ifndef __STDC__
+/* loser */
+#undef const
+#define const
+#endif
+
+enum lang {
+    lang_C,                    /* ANSI C (default) */
+    lang_KRC,                  /* C: ANSI + K&R */
+    lang_CPP                   /* C++ */
+};
+
+int debug;                     /* dump debugging info? */
+char *filename;                        /* error table source */
+enum lang language;
+const char *whoami;
diff --git a/kerberosIV/compile_et/error_table.y b/kerberosIV/compile_et/error_table.y
new file mode 100644 (file)
index 0000000..11ddd22
--- /dev/null
@@ -0,0 +1,260 @@
+%{
+/*     $Id: error_table.y,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+char *str_concat(), *ds(), *quote();
+char *current_token = (char *)NULL;
+extern char *table_name;
+%}
+%union {
+       char *dynstr;
+}
+
+%token ERROR_TABLE ERROR_CODE_ENTRY END
+%token <dynstr> STRING QUOTED_STRING
+%type <dynstr> ec_name description table_id
+%{
+%}
+%start error_table
+%%
+
+error_table    :       ERROR_TABLE table_id error_codes END
+                       { table_name = ds($2);
+                         current_token = table_name;
+                         put_ecs(); }
+               ;
+
+table_id       :       STRING
+                       { current_token = $1;
+                         set_table_num($1);
+                         $$ = $1; }
+               ;
+
+error_codes    :       error_codes ec_entry
+               |       ec_entry
+               ;
+
+ec_entry       :       ERROR_CODE_ENTRY ec_name ',' description
+                       { add_ec($2, $4);
+                         free($2);
+                         free($4); }
+               |       ERROR_CODE_ENTRY ec_name '=' STRING ',' description
+                       { add_ec_val($2, $4, $6);
+                         free($2);
+                         free($4);
+                         free($6);
+                       }
+               ;
+
+ec_name                :       STRING
+                       { $$ = ds($1);
+                         current_token = $$; }
+               ;
+
+description    :       QUOTED_STRING
+                       { $$ = ds($1);
+                         current_token = $$; }
+               ;
+
+%%
+/*
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include "error_table.h"
+
+#ifndef        lint
+static char const rcsid_error_table_y[] =
+    "$Id: error_table.y,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $";
+#endif
+
+#include "et_lex.lex.c"
+
+extern FILE *hfile, *cfile;
+
+static long gensym_n = 0;
+char *
+gensym(x)
+       char const *x;
+{
+       char *symbol;
+       if (!gensym_n) {
+               struct timeval tv;
+               struct timezone tzp;
+               gettimeofday(&tv, &tzp);
+               gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
+       }
+       symbol = (char *)malloc(32 * sizeof(char));
+       gensym_n++;
+       sprintf(symbol, "et%ld", gensym_n);
+       return(symbol);
+}
+
+char *
+ds(string)
+       char const *string;
+{
+       char *rv;
+       rv = (char *)malloc(strlen(string)+1);
+       strcpy(rv, string);
+       return(rv);
+}
+
+char *
+quote(string)
+       char const *string;
+{
+       char *rv;
+       rv = (char *)malloc(strlen(string)+3);
+       strcpy(rv, "\"");
+       strcat(rv, string);
+       strcat(rv, "\"");
+       return(rv);
+}
+
+long table_number;
+int current = 0;
+char **error_codes = (char **)NULL;
+
+add_ec(name, description)
+       char const *name, *description;
+{
+       fprintf(cfile, "\t\"%s\",\n", description);
+       if (error_codes == (char **)NULL) {
+               error_codes = (char **)malloc(sizeof(char *));
+               *error_codes = (char *)NULL;
+       }
+       error_codes = (char **)realloc((char *)error_codes,
+                                      (current + 2)*sizeof(char *));
+       error_codes[current++] = ds(name);
+       error_codes[current] = (char *)NULL;
+}
+
+add_ec_val(name, val, description)
+       char const *name, *val, *description;
+{
+       const int ncurrent = atoi(val);
+       if (ncurrent < current) {
+               printf("Error code %s (%d) out of order", name,
+                      current);
+               return;
+       }
+      
+       while (ncurrent > current)
+            fputs("\t(char *)NULL,\n", cfile), current++;
+       
+       fprintf(cfile, "\t\"%s\",\n", description);
+       if (error_codes == (char **)NULL) {
+               error_codes = (char **)malloc(sizeof(char *));
+               *error_codes = (char *)NULL;
+       }
+       error_codes = (char **)realloc((char *)error_codes,
+                                      (current + 2)*sizeof(char *));
+       error_codes[current++] = ds(name);
+       error_codes[current] = (char *)NULL;
+} 
+
+put_ecs()
+{
+       int i;
+       for (i = 0; i < current; i++) {
+            if (error_codes[i] != (char *)NULL)
+                 fprintf(hfile, "#define %-40s (%ldL)\n",
+                         error_codes[i], table_number + i);
+       }
+}
+
+/*
+ * char_to_num -- maps letters and numbers into a small numbering space
+ *     uppercase ->  1-26
+ *     lowercase -> 27-52
+ *     digits    -> 53-62
+ *     underscore-> 63
+ */
+
+static const char char_set[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+int char_to_num(c)
+       char c;
+{
+       const char *where;
+       int diff;
+
+       where = strchr (char_set, c);
+       if (where) {
+               diff = where - char_set + 1;
+               assert (diff < (1 << ERRCODE_RANGE));
+               return diff;
+       }
+       else if (isprint (c))
+               fprintf (stderr,
+                        "Illegal character `%c' in error table name\n",
+                        c);
+       else
+               fprintf (stderr,
+                        "Illegal character %03o in error table name\n",
+                        c);
+       exit (1);
+}
+
+set_table_num(string)
+       char *string;
+{
+       if (char_to_num (string[0]) > char_to_num ('z')) {
+               fprintf (stderr, "%s%s%s%s",
+                        "First character of error table name must be ",
+                        "a letter; name ``",
+                        string, "'' rejected\n");
+               exit (1);
+       }
+       if (strlen(string) > 4) {
+               fprintf(stderr, "Table name %s too long, truncated ",
+                       string);
+               string[4] = '\0';
+               fprintf(stderr, "to %s\n", string);
+       }
+       while (*string != '\0') {
+               table_number = (table_number << BITS_PER_CHAR)
+                       + char_to_num(*string);
+               string++;
+       }
+       table_number = table_number << ERRCODE_RANGE;
+}
+
diff --git a/kerberosIV/compile_et/et_lex.lex.l b/kerberosIV/compile_et/et_lex.lex.l
new file mode 100644 (file)
index 0000000..cedeff5
--- /dev/null
@@ -0,0 +1,31 @@
+%{
+  unsigned lineno = 1;
+%}
+
+PC     [^\"]
+AN     [A-Z_a-z0-9]
+%%
+
+error_table    return ERROR_TABLE;
+et             return ERROR_TABLE;
+error_code     return ERROR_CODE_ENTRY;
+ec             return ERROR_CODE_ENTRY;
+end            return END;
+
+[\t ]          ;
+\n             ++lineno;
+
+\"{PC}*\"      { register char *p; yylval.dynstr = ds(yytext+1);
+                 if (p=strrchr(yylval.dynstr, '"')) *p='\0';
+                 return QUOTED_STRING;
+               }
+
+{AN}*  { yylval.dynstr = ds(yytext); return STRING; }
+
+#.*\n          ++lineno;
+
+.              { return (*yytext); }
+%%
+#ifndef lint
+static char rcsid_et_lex_lex_l[] = "$Id: et_lex.lex.l,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $";
+#endif
diff --git a/kerberosIV/des/3cbc_enc.c b/kerberosIV/des/3cbc_enc.c
new file mode 100644 (file)
index 0000000..e370456
--- /dev/null
@@ -0,0 +1,52 @@
+/*     $Id: 3cbc_enc.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+static void 
+xp(des_cblock *arg)
+{
+  unsigned char *a = (unsigned char *) arg;
+  int i;
+  for(i=0; i<8; i++) printf("%02X",a[i]);printf("\n");
+}
+
+int des_3cbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *ks1, struct des_ks_struct *ks2, des_cblock (*iv1), des_cblock (*iv2), int encrypt)
+{
+  int off=length/8-1;
+  des_cblock niv1,niv2;
+
+  printf("3cbc\n");
+  xp(iv1);
+  xp(iv1);
+  xp(iv2);
+  xp(input);
+  if (encrypt == DES_ENCRYPT)
+    {
+      des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+      if (length >= sizeof(des_cblock))
+       memcpy(niv1,output[off],sizeof(des_cblock));
+      des_cbc_encrypt(output,output,length,ks2,iv1,!encrypt);
+      des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+      if (length >= sizeof(des_cblock))
+       memcpy(niv2,output[off],sizeof(des_cblock));
+      memcpy(*iv1,niv1,sizeof(des_cblock));
+    }
+  else
+    {
+      if (length >= sizeof(des_cblock))
+       memcpy(niv1,input[off],sizeof(des_cblock));
+      des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+      des_cbc_encrypt(output,output,length,ks2,iv2,!encrypt);
+      if (length >= sizeof(des_cblock))
+       memcpy(niv2,output[off],sizeof(des_cblock));
+      des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+    }
+  memcpy(iv1,niv1,sizeof(des_cblock));
+  memcpy(iv2,niv2,sizeof(des_cblock));
+  xp(iv1);
+  xp(iv1);
+  xp(iv2);
+  xp(output);
+  return(0);
+}
diff --git a/kerberosIV/des/3ecb_enc.c b/kerberosIV/des/3ecb_enc.c
new file mode 100644 (file)
index 0000000..f3b4fa3
--- /dev/null
@@ -0,0 +1,27 @@
+/*     $Id: 3ecb_enc.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+int des_3ecb_encrypt(des_cblock (*input), des_cblock (*output), struct des_ks_struct *ks1, struct des_ks_struct *ks2, int encrypt)
+{
+  register u_int32_t l0,l1;
+  register unsigned char *in,*out;
+  u_int32_t ll[2];
+
+  in=(unsigned char *)input;
+  out=(unsigned char *)output;
+  c2l(in,l0);
+  c2l(in,l1);
+  ll[0]=l0;
+  ll[1]=l1;
+  des_encrypt(ll,ll,ks1,encrypt);
+  des_encrypt(ll,ll,ks2,!encrypt);
+  des_encrypt(ll,ll,ks1,encrypt);
+  l0=ll[0];
+  l1=ll[1];
+  l2c(l0,out);
+  l2c(l1,out);
+  return(0);
+}
+
diff --git a/kerberosIV/des/ARTISTIC b/kerberosIV/des/ARTISTIC
new file mode 100644 (file)
index 0000000..eb67071
--- /dev/null
@@ -0,0 +1,103 @@
+                        The "Artistic License"
+
+                               Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+       "Package" refers to the collection of files distributed by the
+       Copyright Holder, and derivatives of that collection of files
+       created through textual modification.
+
+       "Standard Version" refers to such a Package if it has not been
+       modified, or has been modified in accordance with the wishes
+       of the Copyright Holder as specified below.
+
+       "Copyright Holder" is whoever is named in the copyright or
+       copyrights for the package.
+
+       "You" is you, if you're thinking about copying or distributing
+       this Package.
+
+       "Reasonable copying fee" is whatever you can justify on the
+       basis of media cost, duplication charges, time of people involved,
+       and so on.  (You will not be required to justify it to the
+       Copyright Holder, but only to the computing community at large
+       as a market that must bear the fee.)
+
+       "Freely Available" means that no fee is charged for the item
+       itself, though there may be fees involved in handling the item.
+       It also means that recipients of the item may redistribute it
+       under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder.  A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+    a) place your modifications in the Public Domain or otherwise make them
+    Freely Available, such as by posting said modifications to Usenet or
+    an equivalent medium, or placing the modifications on a major archive
+    site such as uunet.uu.net, or by allowing the Copyright Holder to include
+    your modifications in the Standard Version of the Package.
+
+    b) use the modified Package only within your corporation or organization.
+
+    c) rename any non-standard executables so the names do not conflict
+    with standard executables, which must also be provided, and provide
+    a separate manual page for each non-standard executable that clearly
+    documents how it differs from the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+    a) distribute a Standard Version of the executables and library files,
+    together with instructions (in the manual page or equivalent) on where
+    to get the Standard Version.
+
+    b) accompany the distribution with the machine-readable source of
+    the Package with your modifications.
+
+    c) give non-standard executables non-standard names, and clearly
+    document the differences in manual pages (or equivalent), together
+    with instructions on where to get the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this
+Package.  You may not charge a fee for this Package itself.  However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.
+
+6. Any programs linked with this library do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+
+7. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+8. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+                               The End
diff --git a/kerberosIV/des/CHANGES b/kerberosIV/des/CHANGES
new file mode 100644 (file)
index 0000000..4f441fa
--- /dev/null
@@ -0,0 +1,16 @@
+The main changes in this package since it was last posted to
+comp.sources.misc are
+
+The main changes are
+- Major changes to the Copyright restrictions.
+- Lots and lots of features added to the des(1) command, including
+  - Triple DES, both triple ECB and triple CBC options.
+  - uuencodeing/uudecoding built in to des(1).
+  - generate checksums.
+  - hex keys.
+- Cleaned up the prototypes in des.h
+- Filenames are now mostly <= 8 characters long.
+- OFB, CFB, triple ECB and triple CBC modes of DES added to the library.
+- Compiles and runs of all 64bit machines I could test the code on
+  (Cray, ETA10, DEC Alpha).
+- It really does work with kerberos v 4 now :-).
diff --git a/kerberosIV/des/COPYING b/kerberosIV/des/COPYING
new file mode 100644 (file)
index 0000000..9b1a932
--- /dev/null
@@ -0,0 +1,489 @@
+Copyright (C) 1993 Eric Young
+
+This is a DES implementation written by Eric Young (eay@psych.psy.uq.oz.au)
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+
+
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/kerberosIV/des/Makefile b/kerberosIV/des/Makefile
new file mode 100644 (file)
index 0000000..784220f
--- /dev/null
@@ -0,0 +1,16 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $
+
+LIB=   des
+SRCS=  3cbc_enc.c 3ecb_enc.c cbc_cksm.c cbc_enc.c cfb_enc.c \
+       ecb_enc.c enc_read.c enc_writ.c key_par.c ofb_enc.c \
+       pcbc_enc.c qud_cksm.c random_key.c read_pwd.c rnd_keys.c \
+       set_key.c str2key.c
+CFLAGS+=-I${.CURDIR}
+MAN=   des_crypt.3
+MLINKS+=des_crypt.3 des_read_password.3 des_crypt.3 des_string_to_key.3 \
+       des_crypt.3 des_random_key.3 des_crypt.3 des_set_key.3 \
+       des_crypt.3 des_ecb_encrypt.3 des_crypt.3 des_cbc_encrypt.3 \
+       des_crypt.3 des_pcbc_encrypt.3 des_crypt.3 des_cbc_cksum.3 \
+       des_crypt.3 des_quad_cksum.3
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/des/README b/kerberosIV/des/README
new file mode 100644 (file)
index 0000000..ee1fa0c
--- /dev/null
@@ -0,0 +1,55 @@
+                       libdes, Version 3.00 93/10/07
+
+               Copyright (c) 1993, Eric Young
+                         All rights reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of either:
+    
+       a) the GNU General Public License as published by the Free
+       Software Foundation; either version 1, or (at your option) any
+       later version, or
+
+       b) the "Artistic License" which comes with this Kit.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either
+    the GNU General Public License or the Artistic License for more details.
+
+    You should have received a copy of the Artistic License with this
+    Kit, in the file named "Artistic".  If not, I'll be glad to provide one.
+
+    You should also have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+---
+This kit builds a DES encryption library and a DES encryption program.
+It suports ecb, cbc, ofb, cfb, triple ecb, triple cbc and MIT's pcbc
+encryption modes and also has a fast implementation of crypt(3).
+It contains support routines to read keys from a terminal,
+generate a random key, generate a key from an arbitary length string,
+read/write encrypted data from/to a file descriptor.
+
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+destest should be run after compilation to test the des routines.
+rpw should be run after compilation to test the read password routines.
+The des program is a replacement for the sun des command.  I believe it
+conforms to the sun version.
+
+The Imakefile is setup for use in the kerberos distribution.
+
+These routines are best compiled with gcc or any other good
+optimising compiler.
+Just turn you optimiser up to the highest settings and run destest
+after the build to make sure everything works.
+
+I believe these routines are close to the fastest and most portable DES
+routines that use small lookup tables (4.5k) that are publicly available.
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
+(on a sun3/260 168 vs 336).
+
+Eric Young (eay@psych.psy.uq.oz.au)
diff --git a/kerberosIV/des/VERSION b/kerberosIV/des/VERSION
new file mode 100644 (file)
index 0000000..21e3b8d
--- /dev/null
@@ -0,0 +1,185 @@
+Release apon comp.sources.misc
+Version 3.01 08/10/93
+       Added des_3cbc_encrypt()
+
+Version 3.00 07/10/93
+       Fixed up documentation.
+       quad_cksum definitly compatable with MIT's now.
+
+Version 2.30 24/08/93
+       Tripple DES now defaults to tripple cbc but can do tripple ecb
+        with the -b flag.
+       Fixed some MSDOS uuen/uudecoding problems, thanks to
+       Added prototypes.
+       
+Version 2.22 29/06/93
+       Fixed a bug in des_is_weak_key() which stopped it working :-(
+       thanks to engineering@MorningStar.Com.
+
+Version 2.21 03/06/93
+       des(1) with no arguments gives quite a bit of help.
+       Added -c (generate ckecksum) flag to des(1).
+       Added -3 (tripple DES) flag to des(1).
+       Added cfb and ofb routines to the library.
+
+Version 2.20 11/03/93
+       Added -u (uuencode) flag to des(1).
+       I have been playing with byte order in quad_cksum to make it
+        compatible with MIT's version.  All I can say is aviod this
+        function if possible since MIT's output is endian dependent.
+
+Version 2.12 14/10/92
+       Added MSDOS specific macro in ecb_encrypt which gives a %70
+        speed up when the code is compiled with turbo C.
+
+Version 2.11 12/10/92
+       Speedup in set_key (recoding of PC-1)
+        I now do it in 47 simple operations, down from 60.
+        Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+        for motivating me to look for a faster system :-)
+        The speedup is probably less that 1% but it is still 13
+        instructions less :-).
+
+Version 2.10 06/10/92
+       The code now works on the 64bit ETA10 and CRAY without modifications or
+        #defines.  I believe the code should work on any machine that
+        defines long, int or short to be 8 bytes long.
+       Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
+        for helping me fix the code to run on 64bit machines (he had
+        access to an ETA10).
+       Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
+        for testing the routines on a CRAY.
+       read_password.c has been renamed to read_passwd.c
+       string_to_key.c has been renamed to string2key.c
+
+Version 2.00 14/09/92
+       Made mods so that the library should work on 64bit CPU's.
+       Removed all my uchar and ulong defs.  To many different
+        versions of unix define them in their header files in too many
+        different combinations :-)
+       IRIX - Sillicon Graphics mods (mostly in read_password.c).
+        Thanks to Andrew Daviel (advax@erich.triumf.ca)
+
+Version 1.99 26/08/92
+       Fixed a bug or 2 in enc_read.c
+       Fixed a bug in enc_write.c
+       Fixed a pseudo bug in fcrypt.c (very obscure).
+
+Version 1.98 31/07/92
+       Support for the ETA10.  This is a strange machine that defines
+       longs and ints as 8 bytes and shorts as 4 bytes.
+       Since I do evil things with long * that assume that they are 4
+       bytes.  Look in the Makefile for the option to compile for
+       this machine.  quad_cksum appears to have problems but I
+       will don't have the time to fix it right now, and this is not
+       a function that uses DES and so will not effect the main uses
+       of the library.
+
+Version 1.97 20/05/92 eay
+       Fixed the Imakefile and made some changes to des.h to fix some
+       problems when building this package with Kerberos v 4.
+
+Version 1.96 18/05/92 eay
+       Fixed a small bug in string_to_key() where problems could
+       occur if des_check_key was set to true and the string
+       generated a weak key.
+
+Patch2 posted to comp.sources.misc
+Version 1.95 13/05/92 eay
+       Added an alternative version of the D_ENCRYPT macro in
+       ecb_encrypt and fcrypt.  Depending on the compiler, one version or the
+       other will be faster.  This was inspired by 
+       Dana How <how@isl.stanford.edu>, and her pointers about doing the
+       *(ulong *)((uchar *)ptr+(value&0xfc))
+       vs
+       ptr[value&0x3f]
+       to stop the C compiler doing a <<2 to convert the long array index.
+
+Version 1.94 05/05/92 eay
+       Fixed an incompatibility between my string_to_key and the MIT
+        version.  When the key is longer than 8 chars, I was wrapping
+        with a different method.  To use the old version, define
+        OLD_STR_TO_KEY in the makefile.  Thanks to
+        viktor@newsu.shearson.com (Viktor Dukhovni).
+
+Version 1.93 28/04/92 eay
+       Fixed the VMS mods so that echo is now turned off in
+        read_password.  Thanks again to brennan@coco.cchs.su.oz.AU.
+       MSDOS support added.  The routines can be compiled with
+        Turbo C (v2.0) and MSC (v5.1).  Make sure MSDOS is defined.
+
+Patch1 posted to comp.sources.misc
+Version 1.92 13/04/92 eay
+       Changed D_ENCRYPT so that the rotation of R occurs outside of
+        the loop.  This required rotating all the longs in sp.h (now
+        called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+       speed.c has been changed so it will work without SIGALRM.  If
+        times(3) is not present it will try to use ftime() instead.
+
+Version 1.91 08/04/92 eay
+       Added -E/-D options to des(1) so it can use string_to_key.
+       Added SVR4 mods suggested by witr@rwwa.COM
+       Added VMS mods suggested by brennan@coco.cchs.su.oz.AU.  If
+       anyone knows how to turn of tty echo in VMS please tell me or
+       implement it yourself :-).
+       Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
+       does not like IN/OUT being used.
+
+Libdes posted to comp.sources.misc
+Version 1.9 24/03/92 eay
+       Now contains a fast small crypt replacement.
+       Added des(1) command.
+       Added des_rw_mode so people can use cbc encryption with
+       enc_read and enc_write.
+
+Version 1.8 15/10/91 eay
+       Bug in cbc_cksum.
+       Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
+       one out.
+
+Version 1.7 24/09/91 eay
+       Fixed set_key :-)
+       set_key is 4 times faster and takes less space.
+       There are a few minor changes that could be made.
+
+Version 1.6 19/09/1991 eay
+       Finally go IP and FP finished.
+       Now I need to fix set_key.
+       This version is quite a bit faster that 1.51
+
+Version 1.52 15/06/1991 eay
+       20% speedup in ecb_encrypt by changing the E bit selection
+       to use 2 32bit words.  This also required modification of the
+       sp table.  There is still a way to speedup the IP and IP-1
+       (hints from outer@sq.com) still working on this one :-(.
+
+Version 1.51 07/06/1991 eay
+       Faster des_encrypt by loop unrolling
+       Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
+
+Version 1.50 28/05/1991 eay
+       Optimized the code a bit more for the sparc.  I have improved the
+       speed of the inner des_encrypt by speeding up the initial and
+       final permutations.
+
+Version 1.40 23/10/1990 eay
+       Fixed des_random_key, it did not produce a random key :-(
+
+Version 1.30  2/10/1990 eay
+       Have made des_quad_cksum the same as MIT's, the full package
+       should be compatible with MIT's
+       Have tested on a DECstation 3100
+       Still need to fix des_set_key (make it faster).
+       Does des_cbc_encrypts at 70.5k/sec on a 3100.
+
+Version 1.20 18/09/1990 eay
+       Fixed byte order dependencies.
+       Fixed (I hope) all the word alignment problems.
+       Speedup in des_ecb_encrypt.
+
+Version 1.10 11/09/1990 eay
+       Added des_enc_read and des_enc_write.
+       Still need to fix des_quad_cksum.
+       Still need to document des_enc_read and des_enc_write.
+
+Version 1.00 27/08/1990 eay
diff --git a/kerberosIV/des/cbc_cksm.c b/kerberosIV/des/cbc_cksm.c
new file mode 100644 (file)
index 0000000..262111b
--- /dev/null
@@ -0,0 +1,46 @@
+/*     $Id: cbc_cksm.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+u_int32_t des_cbc_cksum(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec))
+{
+  register u_int32_t tout0,tout1,tin0,tin1;
+  register long l=length;
+  u_int32_t tin[2],tout[2];
+  unsigned char *in,*out,*iv;
+
+  in=(unsigned char *)input;
+  out=(unsigned char *)output;
+  iv=(unsigned char *)ivec;
+
+  c2l(iv,tout0);
+  c2l(iv,tout1);
+  for (; l>0; l-=8)
+    {
+      if (l >= 8)
+       {
+         c2l(in,tin0);
+         c2l(in,tin1);
+       }
+      else
+       c2ln(in,tin0,tin1,l);
+                       
+      tin0^=tout0;
+      tin1^=tout1;
+      tin[0]=tin0;
+      tin[1]=tin1;
+      des_encrypt(tin,tout,
+                 schedule,DES_ENCRYPT);
+      /* fix 15/10/91 eay - thanks to keithr@sco.COM */
+      tout0=tout[0];
+      tout1=tout[1];
+    }
+  if (out != NULL)
+    {
+      l2c(tout0,out);
+      l2c(tout1,out);
+    }
+  tout0=tin0=tin1=tin[0]=tin[1]=tout[0]=tout[1]=0;
+  return(tout1);
+}
diff --git a/kerberosIV/des/cbc_enc.c b/kerberosIV/des/cbc_enc.c
new file mode 100644 (file)
index 0000000..cf82ca6
--- /dev/null
@@ -0,0 +1,73 @@
+/*     $Id: cbc_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+int des_cbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt)
+{
+  register u_int32_t tin0,tin1;
+  register u_int32_t tout0,tout1,xor0,xor1;
+  register unsigned char *in,*out;
+  register long l=length;
+  u_int32_t tout[2],tin[2];
+  unsigned char *iv;
+
+  in=(unsigned char *)input;
+  out=(unsigned char *)output;
+  iv=(unsigned char *)ivec;
+
+  if (encrypt)
+    {
+      c2l(iv,tout0);
+      c2l(iv,tout1);
+      for (; l>0; l-=8)
+       {
+         if (l >= 8)
+           {
+             c2l(in,tin0);
+             c2l(in,tin1);
+           }
+         else
+           c2ln(in,tin0,tin1,l);
+         tin0^=tout0;
+         tin1^=tout1;
+         tin[0]=tin0;
+         tin[1]=tin1;
+         des_encrypt(tin,tout,
+                     schedule,encrypt);
+         tout0=tout[0];
+         tout1=tout[1];
+         l2c(tout0,out);
+         l2c(tout1,out);
+       }
+    }
+  else
+    {
+      c2l(iv,xor0);
+      c2l(iv,xor1);
+      for (; l>0; l-=8)
+       {
+         c2l(in,tin0);
+         c2l(in,tin1);
+         tin[0]=tin0;
+         tin[1]=tin1;
+         des_encrypt(tin,tout,
+                     schedule,encrypt);
+         tout0=tout[0]^xor0;
+         tout1=tout[1]^xor1;
+         if (l >= 8)
+           {
+             l2c(tout0,out);
+             l2c(tout1,out);
+           }
+         else
+           l2cn(tout0,tout1,out,l);
+         xor0=tin0;
+         xor1=tin1;
+       }
+    }
+  tin0=tin1=tout0=tout1=xor0=xor1=0;
+  tin[0]=tin[1]=tout[0]=tout[1]=0;
+  return(0);
+}
+
diff --git a/kerberosIV/des/cfb_enc.c b/kerberosIV/des/cfb_enc.c
new file mode 100644 (file)
index 0000000..c5f3364
--- /dev/null
@@ -0,0 +1,100 @@
+/*     $Id: cfb_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+int des_cfb_encrypt(unsigned char *in, unsigned char *out, int numbits, long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt)
+{
+  register u_int32_t d0,d1,v0,v1,n=(numbits+7)/8;
+  register u_int32_t mask0,mask1;
+  register long l=length;
+  register int num=numbits;
+  u_int32_t ti[2],to[2];
+  unsigned char *iv;
+
+  if (num > 64) return(0);
+  if (num > 32)
+    {
+      mask0=0xffffffff;
+      if (num == 64)
+       mask1=mask0;
+      else
+       mask1=(1L<<(num-32))-1;
+    }
+  else
+    {
+      if (num == 32)
+       mask0=0xffffffff;
+      else
+       mask0=(1L<<num)-1;
+      mask1=0x00000000;
+    }
+
+  iv=(unsigned char *)ivec;
+  c2l(iv,v0);
+  c2l(iv,v1);
+  if (encrypt)
+    {
+      while (l-- > 0)
+       {
+         ti[0]=v0;
+         ti[1]=v1;
+         des_encrypt(ti,to,
+                     schedule,DES_ENCRYPT);
+         c2ln(in,d0,d1,n);
+         in+=n;
+         d0=(d0^to[0])&mask0;
+         d1=(d1^to[1])&mask1;
+         l2cn(d0,d1,out,n);
+         out+=n;
+         if (num > 32)
+           {
+             v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff;
+             v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff;
+           }
+         else
+           {
+             v0=((v0>>num)|(v1<<(32-num)))&0xffffffff;
+             v1=((v1>>num)|(d0<<(32-num)))&0xffffffff;
+           }
+       }
+    }
+  else
+    {
+      while (l-- > 0)
+       {
+         ti[0]=v0;
+         ti[1]=v1;
+         des_encrypt(ti,to,
+                     schedule,DES_ENCRYPT);
+         c2ln(in,d0,d1,n);
+         in+=n;
+         if (num > 32)
+           {
+             v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff;
+             v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff;
+           }
+         else
+           {
+             v0=((v0>>num)|(v1<<(32-num)))&0xffffffff;
+             v1=((v1>>num)|(d0<<(32-num)))&0xffffffff;
+           }
+         d0=(d0^to[0])&mask0;
+         d1=(d1^to[1])&mask1;
+         l2cn(d0,d1,out,n);
+         out+=n;
+       }
+    }
+  iv=(unsigned char *)ivec;
+  l2c(v0,iv);
+  l2c(v1,iv);
+  v0=v1=d0=d1=ti[0]=ti[1]=to[0]=to[1]=0;
+  return(0);
+}
+
diff --git a/kerberosIV/des/des_crypt.3 b/kerberosIV/des/des_crypt.3
new file mode 100644 (file)
index 0000000..311690d
--- /dev/null
@@ -0,0 +1,379 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: des_crypt.3,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $
+.TH DES_CRYPT 3  "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+des_read_password, des_string_to_key, des_random_key, des_set_key,
+des_ecb_encrypt, des_cbc_encrypt, des_pcbc_encrypt, des_cbc_cksum,
+des_quad_cksum, \- (new) DES encryption
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+.PP
+.ft B
+.B int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+.PP
+.ft B
+int des_string_to_key(str,key)
+char *str;
+des_cblock key;
+.PP
+.ft B
+int des_random_key(key)
+des_cblock *key;
+.PP
+.ft B
+int des_set_key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.ft B
+int des_ecb_encrypt(input,output,schedule,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule schedule;
+int encrypt;
+.PP
+.ft B
+int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.ft B
+int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.ft B
+unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.ft B
+unsigned long quad_cksum(input,output,length,out_count,seed)
+des_cblock *input;
+des_cblock *output;
+long length;
+int out_count;
+des_cblock *seed;
+.PP
+.fi
+.SH DESCRIPTION
+This library supports various DES encryption related operations. It differs
+from the
+.I crypt, setkey, and encrypt
+library routines in that it provides
+a true DES encryption, without modifying the algorithm,
+and executes much faster.
+.PP
+For each key that may be simultaneously active, create a
+.B des_key_schedule
+struct,
+defined in "des.h". Next, create key schedules (from the 8-byte keys) as
+needed, via
+.I des_set_key,
+prior to using the encryption or checksum routines. Then
+setup the input and output areas.  Make sure to note the restrictions
+on lengths being multiples of eight bytes. Finally, invoke the
+encryption/decryption routines,
+.I des_ecb_encrypt
+or
+.I des_cbc_encrypt
+or
+.I des_pcbc_encrypt,
+or, to generate a cryptographic checksum, use
+.I quad_cksum
+(fast) or
+.I des_cbc_cksum
+(slow).
+.PP
+A
+.I des_cblock
+struct is an 8 byte block used as the fundamental unit for DES data and
+keys, and is defined as:
+.PP
+.B     typedef unsigned char des_cblock[8];
+.PP
+and a
+.I des_key_schedule,
+is defined as:
+.PP
+.B     typedef struct des_ks_struct {des_cblock _;}  des_key_schedule[16];
+.PP
+.I des_read_password
+writes the string specified by
+.I prompt
+to the standard
+output, turns off echo (if possible)
+and reads an input string from standard input until terminated with a newline.
+If
+.I verify
+is non-zero, it prompts and reads input again, for use
+in applications such as changing a password; both
+versions are compared, and the input is requested repeatedly until they
+match.  Then
+.I des_read_password
+converts the input string into a valid DES key, internally
+using the
+.I des_string_to_key
+routine.  The newly created key is copied to the
+area pointed to by the
+.I key
+argument.
+.I des_read_password
+returns a zero if no errors occurred, or a -1
+indicating that an error
+occurred trying to manipulate the terminal echo.
+.PP
+.PP
+.I des_string_to_key
+converts an arbitrary length null-terminated string
+to an 8 byte DES key, with odd byte parity, per FIPS specification.
+A one-way function is used to convert the string to a key, making it
+very difficult to reconstruct the string from the key.
+The
+.I str
+argument is a pointer to the string, and
+.I key
+should
+point to a
+.I des_cblock
+supplied by the caller to receive the generated key.
+No meaningful value is returned. Void is not used for compatibility with
+other compilers.
+.PP
+.PP
+.I des_random_key
+generates a random DES encryption key (eight bytes), set to odd parity per
+FIPS
+specifications.
+This routine uses the current time, process id, and a counter
+as a seed for the random number generator.
+The caller must        supply space for the output key, pointed to
+by argument
+.I key,
+then after calling
+.I des_random_key
+should
+call the
+.I des_set_key
+routine when needed.
+No meaningful value is returned.  Void is not used for compatibility
+with other compilers.
+.PP
+.PP
+.I des_set_key
+calculates a key schedule from all eight bytes of the input key, pointed
+to by the
+.I key
+argument, and outputs the schedule into the
+.I des_key_schedule
+indicated by the
+.I schedule
+argument. Make sure to pass a valid eight byte
+key; no padding is done.  The key schedule may then be used in subsequent
+encryption/decryption/checksum operations.  Many key schedules may be
+cached for later use.  The user is responsible to clear keys and schedules
+as soon as no longer needed, to prevent their disclosure.
+The routine also checks the key
+parity, and returns a zero if the key parity is correct (odd), a -1
+indicating a key parity error, or a -2 indicating use of an illegal
+weak key. If an error is returned, the key schedule was not created.
+.PP
+.PP
+.I des_ecb_encrypt
+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
+block in
+.B electronic code book
+mode.  It always transforms the input data, pointed to by
+.I input,
+into the output data, pointed to by the
+.I output
+argument.
+.PP
+If the
+.I encrypt
+argument is non-zero, the
+.I input
+(cleartext) is encrypted into the
+.I output
+(ciphertext) using the key_schedule specified by the
+.I schedule
+argument, previously set via
+.I des_set_key
+.PP
+If encrypt is zero, the
+.I input
+(now ciphertext) is decrypted into the
+.I output
+(now cleartext).
+.PP
+Input and output may overlap.
+.PP
+No meaningful value is returned.  Void is not used for compatibility
+with other compilers.
+.PP
+.PP
+.I des_cbc_encrypt
+encrypts/decrypts using the
+.B cipher-block-chaining mode of DES.
+If the
+.I encrypt
+argument is non-zero, the routine cipher-block-chain encrypts
+the cleartext data pointed to by the
+.I input
+argument into the ciphertext pointed to by the
+.I output
+argument, using the key schedule provided by the
+.I schedule
+argument, and initialization vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral
+multiple of eight bytes, the last block is copied to a temp and zero
+filled (highest addresses).  The output is ALWAYS an integral multiple
+of eight bytes.
+.PP
+If
+.I encrypt
+is zero, the routine cipher-block chain decrypts the (now) ciphertext
+data pointed to by the
+.I input
+argument into (now) cleartext pointed to by the
+.I output
+argument using the key schedule provided by the
+.I schedule
+argument, and initialization vector provided by the
+.I ivec
+argument. Decryption ALWAYS operates on integral
+multiples of 8 bytes, so it will round the
+.I length
+provided up to the
+appropriate multiple. Consequently, it will always produce the rounded-up
+number of bytes of output cleartext. The application must determine if
+the output cleartext was zero-padded due to original cleartext lengths that
+were not integral multiples of 8.
+.PP
+No errors or meaningful values are returned.  Void is not used for
+compatibility with other compilers.
+.PP
+A characteristic of cbc mode is that changing a single bit of the
+cleartext, then encrypting using cbc mode,
+affects ALL the subsequent ciphertext.  This makes cryptanalysis
+much more difficult. However, modifying a single bit of the ciphertext,
+then decrypting, only affects the resulting cleartext from
+the modified block and the succeeding block.  Therefore,
+.I des_pcbc_encrypt
+is STRONGLY recommended for applications where
+indefinite propagation of errors is required in order to detect modifications.
+.PP
+.PP
+.I des_pcbc_encrypt
+encrypts/decrypts using a modified block chaining mode. Its calling
+sequence is identical to
+.I des_cbc_encrypt.
+It differs in its error propagation characteristics.
+.PP
+.I des_pcbc_encrypt
+is highly recommended for most encryption purposes, in that
+modification of a single bit of the ciphertext will affect ALL the
+subsequent (decrypted) cleartext. Similarly, modifying a single bit of
+the cleartext will affect ALL the subsequent (encrypted) ciphertext.
+"PCBC" mode, on encryption, "xors" both the
+cleartext of block N and the ciphertext resulting from block N with the
+cleartext for block N+1 prior to encrypting block N+1.
+.PP
+.I des_cbc_cksum
+produces an 8 byte cryptographic checksum by cipher-block-chain
+encrypting the cleartext data pointed to by the
+.I input
+argument. All of the ciphertext output is discarded, except the
+last 8-byte ciphertext block, which is written into the area pointed to by
+the
+.I output
+argument.
+It uses the key schedule,
+provided by the
+.I schedule
+argument and initialization vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral
+multiple of eight bytes, the last cleartext block is copied to a temp and zero
+filled (highest addresses).  The output is ALWAYS eight bytes.
+.PP
+The routine also returns an unsigned long, which is the last (highest address)
+half of the 8 byte checksum computed.
+.PP
+.PP
+.I quad_cksum
+produces a checksum by chaining quadratic operations on the cleartext data
+pointed to by the
+.I input
+argument. The
+.I length
+argument specifies the length of the
+input -- only exactly that many bytes are included for the checksum,
+without any padding.
+.PP
+The algorithm may be iterated over the same input data, if the
+.I out_count
+argument is 2, 3 or 4, and the optional
+.I output
+argument is a non-null pointer .
+The default is one iteration, and it will not run
+more than 4 times. Multiple iterations run slower, but provide
+a longer checksum if desired. The
+.I seed
+argument provides an 8-byte seed for the first iteration. If multiple iterations are
+requested, the results of one iteration are automatically used as
+the seed for the next iteration.
+.PP
+It returns both an unsigned long checksum value, and
+if the
+.I output
+argument is not a null pointer, up to 16 bytes of
+the computed checksum are written into the output.
+.PP
+.PP
+.SH FILES
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.SH "SEE ALSO"
+.SH DIAGNOSTICS
+.SH BUGS
+This software has not yet been compiled or tested on machines other than the
+VAX and the IBM PC.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.SH RESTRICTIONS
+COPYRIGHT 1985,1986 Massachusetts Institute of Technology
+.PP
+This software may not be exported outside of the US without a special
+license from the US Dept of Commerce. It may be replaced by any secret
+key block cipher with block length and key length of 8 bytes, as long
+as the interface is the same as described here.
diff --git a/kerberosIV/des/des_locl.h b/kerberosIV/des/des_locl.h
new file mode 100644 (file)
index 0000000..4a7f472
--- /dev/null
@@ -0,0 +1,174 @@
+/*     $Id: des_locl.h,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+#ifndef __des_locl_h
+#define __des_locl_h
+
+#include <sys/cdefs.h>
+
+#include <stdio.h>
+#include <memory.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "kerberosIV/des.h"
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE       (1024*16)
+#define BSIZE          (MAXWRITE+4)
+
+#define c2l(c,l)       (l =((u_int32_t)(*((c)++)))    , \
+                        l|=((u_int32_t)(*((c)++)))<< 8, \
+                        l|=((u_int32_t)(*((c)++)))<<16, \
+                        l|=((u_int32_t)(*((c)++)))<<24)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)        { \
+                       c+=n; \
+                       l1=l2=0; \
+                       switch (n) { \
+                       case 8: l2|=((u_int32_t)(*(--(c))))<<24; \
+                       case 7: l2|=((u_int32_t)(*(--(c))))<<16; \
+                       case 6: l2|=((u_int32_t)(*(--(c))))<< 8; \
+                       case 5: l2|=((u_int32_t)(*(--(c))));     \
+                       case 4: l1|=((u_int32_t)(*(--(c))))<<24; \
+                       case 3: l1|=((u_int32_t)(*(--(c))))<<16; \
+                       case 2: l1|=((u_int32_t)(*(--(c))))<< 8; \
+                       case 1: l1|=((u_int32_t)(*(--(c))));     \
+                               } \
+                       }
+
+#define l2c(l,c)       (*((c)++)=(unsigned char)(((l)    )&0xff), \
+                        *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l)       (l =((u_int32_t)(*((c)++)))<<24, \
+                        l|=((u_int32_t)(*((c)++)))<<16, \
+                        l|=((u_int32_t)(*((c)++)))<< 8, \
+                        l|=((u_int32_t)(*((c)++))))
+
+#define l2n(l,c)       (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                        *((c)++)=(unsigned char)(((l)    )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)        { \
+                       c+=n; \
+                       switch (n) { \
+                       case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                       case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                       case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                       case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                       case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                       case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                       case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                       case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                               } \
+                       }
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture.  gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs. */
+#ifdef ALT_ECB
+#define D_ENCRYPT(L,R,S) \
+       u=((R^s[S  ])<<2);      \
+       t= R^s[S+1]; \
+       t=((t>>2)+(t<<30)); \
+       L^= \
+       *(u_int32_t *)(des_SP+0x0100+((t    )&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0500+((t>>16)&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0700+((t>>24)&0xfc))+ \
+       *(u_int32_t *)(des_SP+       ((u    )&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0400+((u>>16)&0xfc))+ \
+       *(u_int32_t *)(des_SP+0x0600+((u>>24)&0xfc));
+#else /* original version */
+#ifdef MSDOS
+#define D_ENCRYPT(L,R,S)       \
+       U.l=R^s[S+1]; \
+       T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \
+       T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \
+       U.l=(R^s[S  ])&0x3f3f3f3f; \
+       L^=     des_SPtrans[1][(T.c[0])]| \
+               des_SPtrans[3][(T.c[1])]| \
+               des_SPtrans[5][(T.c[2])]| \
+               des_SPtrans[7][(T.c[3])]| \
+               des_SPtrans[0][(U.c[0])]| \
+               des_SPtrans[2][(U.c[1])]| \
+               des_SPtrans[4][(U.c[2])]| \
+               des_SPtrans[6][(U.c[3])];
+#else
+#define D_ENCRYPT(L,R,S)       \
+       u=(R^s[S  ]); \
+       t=R^s[S+1]; \
+       t=((t>>4)+(t<<28)); \
+       L^=     des_SPtrans[1][(t    )&0x3f]| \
+               des_SPtrans[3][(t>> 8)&0x3f]| \
+               des_SPtrans[5][(t>>16)&0x3f]| \
+               des_SPtrans[7][(t>>24)&0x3f]| \
+               des_SPtrans[0][(u    )&0x3f]| \
+               des_SPtrans[2][(u>> 8)&0x3f]| \
+               des_SPtrans[4][(u>>16)&0x3f]| \
+               des_SPtrans[6][(u>>24)&0x3f];
+#endif
+#endif
+
+       /* IP and FP
+        * The problem is more of a geometric problem that random bit fiddling.
+        0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
+        8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
+       16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
+       24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
+
+       32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
+       40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
+       48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
+       56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
+
+       The output has been subject to swaps of the form
+       0 1 -> 3 1 but the odd and even bits have been put into
+       2 3    2 0
+       different words.  The main trick is to remember that
+       t=((l>>size)^r)&(mask);
+       r^=t;
+       l^=(t<<size);
+       can be used to swap and move bits between words.
+
+       So l =  0  1  2  3  r = 16 17 18 19
+               4  5  6  7      20 21 22 23
+               8  9 10 11      24 25 26 27
+              12 13 14 15      28 29 30 31
+       becomes (for size == 2 and mask == 0x3333)
+          t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
+                6^20  7^21 -- --        4  5 20 21       6  7 22 23
+               10^24 11^25 -- --        8  9 24 25      10 11 24 25
+               14^28 15^29 -- --       12 13 28 29      14 15 28 29
+
+       Thanks for hints from Richard Outerbridge - he told me IP&FP
+       could be done in 15 xor, 10 shifts and 5 ands.
+       When I finally started to think of the problem in 2D
+       I first got ~42 operations without xors.  When I remembered
+       how to use xors :-) I got it to its final state.
+       */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+       (b)^=(t),\
+       (a)^=((t)<<(n)))
+
+
+#endif /*  __des_locl_h */
diff --git a/kerberosIV/des/ecb_enc.c b/kerberosIV/des/ecb_enc.c
new file mode 100644 (file)
index 0000000..87af76b
--- /dev/null
@@ -0,0 +1,111 @@
+/*     $Id: ecb_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+#include "spr.h"
+
+int des_ecb_encrypt(des_cblock (*input), des_cblock (*output), struct des_ks_struct *ks, int encrypt)
+{
+  register u_int32_t l0,l1;
+  register unsigned char *in,*out;
+  u_int32_t ll[2];
+
+  in=(unsigned char *)input;
+  out=(unsigned char *)output;
+  c2l(in,l0);
+  c2l(in,l1);
+  ll[0]=l0;
+  ll[1]=l1;
+  des_encrypt(ll,ll,ks,encrypt);
+  l0=ll[0];
+  l1=ll[1];
+  l2c(l0,out);
+  l2c(l1,out);
+  l0=l1=ll[0]=ll[1]=0;
+  return(0);
+}
+
+int des_encrypt(u_int32_t *input, u_int32_t *output, struct des_ks_struct *ks, int encrypt)
+{
+  register u_int32_t l,r,t,u;
+#ifdef ALT_ECB
+  register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifdef MSDOS
+  union fudge {
+    u_int32_t  l;
+    unsigned short s[2];
+    unsigned char  c[4];
+  } U,T;
+#endif
+  register int i;
+  register u_int32_t *s;
+
+  l=input[0];
+  r=input[1];
+
+  /* do IP */
+  PERM_OP(r,l,t, 4,0x0f0f0f0f);
+  PERM_OP(l,r,t,16,0x0000ffff);
+  PERM_OP(r,l,t, 2,0x33333333);
+  PERM_OP(l,r,t, 8,0x00ff00ff);
+  PERM_OP(r,l,t, 1,0x55555555);
+  /* r and l are reversed - remember that :-) - fix
+   * it in the next step */
+
+  /* Things have been modified so that the initial rotate is
+   * done outside the loop.  This required the
+   * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+   * One perl script later and things have a 5% speed up on a sparc2.
+   * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+   * for pointing this out. */
+  t=(r<<1)|(r>>31);
+  r=(l<<1)|(l>>31);
+  l=t;
+
+  /* clear the top bits on machines with 8byte longs */
+  l&=0xffffffff;
+  r&=0xffffffff;
+
+  s=(u_int32_t *)ks;
+  /* I don't know if it is worth the effort of loop unrolling the
+   * inner loop */
+  if (encrypt)
+    {
+      for (i=0; i<32; i+=4)
+       {
+         D_ENCRYPT(l,r,i+0);   /*  1 */
+         D_ENCRYPT(r,l,i+2);   /*  2 */
+       }
+    }
+  else
+    {
+      for (i=30; i>0; i-=4)
+       {
+         D_ENCRYPT(l,r,i-0);   /* 16 */
+         D_ENCRYPT(r,l,i-2);   /* 15 */
+       }
+    }
+  l=(l>>1)|(l<<31);
+  r=(r>>1)|(r<<31);
+  /* clear the top bits on machines with 8byte longs */
+  l&=0xffffffff;
+  r&=0xffffffff;
+
+  /* swap l and r
+   * we will not do the swap so just remember they are
+   * reversed for the rest of the subroutine
+   * luckily FP fixes this problem :-) */
+
+  PERM_OP(r,l,t, 1,0x55555555);
+  PERM_OP(l,r,t, 8,0x00ff00ff);
+  PERM_OP(r,l,t, 2,0x33333333);
+  PERM_OP(l,r,t,16,0x0000ffff);
+  PERM_OP(r,l,t, 4,0x0f0f0f0f);
+
+  output[0]=l;
+  output[1]=r;
+  l=r=t=u=0;
+  return(0);
+}
+
diff --git a/kerberosIV/des/enc_read.c b/kerberosIV/des/enc_read.c
new file mode 100644 (file)
index 0000000..233e078
--- /dev/null
@@ -0,0 +1,156 @@
+/*     $Id: enc_read.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+#include "des_locl.h"
+#include <unistd.h>
+#include <errno.h>
+
+/* This has some uglies in it but it works - even over sockets. */
+extern int errno;
+int des_rw_mode=DES_PCBC_MODE;
+
+int des_enc_read(int fd, char *buf, int len, struct des_ks_struct *sched, des_cblock (*iv))
+{
+  /* data to be unencrypted */
+  int net_num=0;
+  unsigned char net[BSIZE];
+  /* extra unencrypted data 
+   * for when a block of 100 comes in but is des_read one byte at
+   * a time. */
+  static char unnet[BSIZE];
+  static int unnet_start=0;
+  static int unnet_left=0;
+  int i;
+  long num=0,rnum;
+  unsigned char *p;
+
+  /* left over data from last decrypt */
+  if (unnet_left != 0)
+    {
+      if (unnet_left < len)
+       {
+         /* we still still need more data but will return
+          * with the number of bytes we have - should always
+          * check the return value */
+         memcpy(buf,&(unnet[unnet_start]),unnet_left);
+         /* eay 26/08/92 I had the next 2 lines
+          * reversed :-( */
+         i=unnet_left;
+         unnet_start=unnet_left=0;
+       }
+      else
+       {
+         memcpy(buf,&(unnet[unnet_start]),len);
+         unnet_start+=len;
+         unnet_left-=len;
+         i=len;
+       }
+      return(i);
+    }
+
+  /* We need to get more data. */
+  if (len > MAXWRITE) len=MAXWRITE;
+
+  /* first - get the length */
+  net_num=0;
+  while (net_num < HDRSIZE) 
+    {
+      i=read(fd,&(net[net_num]),HDRSIZE-net_num);
+      if ((i == -1) && (errno == EINTR)) continue;
+      if (i <= 0) return(0);
+      net_num+=i;
+    }
+
+  /* we now have at net_num bytes in net */
+  p=net;
+  num=0;
+  n2l(p,num);
+  /* num should be rounded up to the next group of eight
+   * we make sure that we have read a multiple of 8 bytes from the net.
+   */
+  if ((num > MAXWRITE) || (num < 0)) /* error */
+    return(-1);
+  rnum=(num < 8)?8:((num+7)/8*8);
+
+  net_num=0;
+  while (net_num < rnum)
+    {
+      i=read(fd,&(net[net_num]),rnum-net_num);
+      if ((i == -1) && (errno == EINTR)) continue;
+      if (i <= 0) return(0);
+      net_num+=i;
+    }
+
+  /* Check if there will be data left over. */
+  if (len < num)
+    {
+      if (des_rw_mode & DES_PCBC_MODE)
+       des_pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+                    num,sched,iv,DES_DECRYPT);
+      else
+       des_cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+                   num,sched,iv,DES_DECRYPT);
+      memcpy(buf,unnet,len);
+      unnet_start=len;
+      unnet_left=num-len;
+
+      /* The following line is done because we return num
+       * as the number of bytes read. */
+      num=len;
+    }
+  else
+    {
+      /* >output is a multiple of 8 byes, if len < rnum
+       * >we must be careful.  The user must be aware that this
+       * >routine will write more bytes than he asked for.
+       * >The length of the buffer must be correct.
+       * FIXED - Should be ok now 18-9-90 - eay */
+      if (len < rnum)
+       {
+         char tmpbuf[BSIZE];
+
+         if (des_rw_mode & DES_PCBC_MODE)
+           des_pcbc_encrypt((des_cblock *)net,
+                        (des_cblock *)tmpbuf,
+                        num,sched,iv,DES_DECRYPT);
+         else
+           des_cbc_encrypt((des_cblock *)net,
+                       (des_cblock *)tmpbuf,
+                       num,sched,iv,DES_DECRYPT);
+
+         /* eay 26/08/92 fix a bug that returned more
+          * bytes than you asked for (returned len bytes :-( */
+         memcpy(buf,tmpbuf,num);
+       }
+      else if (num >= 8)
+       {
+         if (des_rw_mode & DES_PCBC_MODE)
+           des_pcbc_encrypt((des_cblock *)net,
+                        (des_cblock *)buf,num,sched,iv,
+                        DES_DECRYPT);
+         else
+           des_cbc_encrypt((des_cblock *)net,
+                       (des_cblock *)buf,num,sched,iv,
+                       DES_DECRYPT);
+       }
+      else
+       {
+         if (des_rw_mode & DES_PCBC_MODE)
+           des_pcbc_encrypt((des_cblock *)net,
+                        (des_cblock *)buf,8,sched,iv,
+                        DES_DECRYPT);
+         else
+           des_cbc_encrypt((des_cblock *)net,
+                       (des_cblock *)buf,8,sched,iv,
+                       DES_DECRYPT);
+#ifdef LEFT_JUSTIFIED
+         memcpy(buf, buf, num);
+#else
+         memcpy(buf, buf+(8-num), num);
+#endif
+       }
+    }
+  return(num);
+}
+
diff --git a/kerberosIV/des/enc_writ.c b/kerberosIV/des/enc_writ.c
new file mode 100644 (file)
index 0000000..a547710
--- /dev/null
@@ -0,0 +1,95 @@
+/*     $Id: enc_writ.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+#include "des_locl.h"
+#include <unistd.h>
+#include <errno.h>
+
+int des_enc_write(int fd, char *buf, int len, struct des_ks_struct *sched, des_cblock (*iv))
+{
+  long rnum;
+  int i,j,k,outnum;
+  char outbuf[BSIZE+HDRSIZE];
+  char shortbuf[8];
+  char *p;
+  static int start=1;
+
+  /* If we are sending less than 8 bytes, the same char will look
+   * the same if we don't pad it out with random bytes */
+  if (start)
+    {
+      start=0;
+      srand(time(NULL));
+    }
+
+  /* lets recurse if we want to send the data in small chunks */
+  if (len > MAXWRITE)
+    {
+      j=0;
+      for (i=0; i<len; i+=k)
+       {
+         k=des_enc_write(fd,&(buf[i]),
+                         ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
+         if (k < 0)
+           return(k);
+         else
+           j+=k;
+       }
+      return(j);
+    }
+
+  /* write length first */
+  p=outbuf;
+  l2n(len,p);
+
+  /* pad short strings */
+  if (len < 8)
+    {
+#ifdef LEFT_JUSTIFIED
+      p=shortbuf;
+      memcpy(shortbuf,buf,len);
+      for (i=len; i<8; i++)
+       shortbuf[i]=rand();
+      rnum=8;
+#else
+      p=shortbuf;
+      for (i=0; i<8-len; i++)
+       shortbuf[i]=rand();
+      memcpy(shortbuf + 8 - len, buf, len);
+      rnum=8;
+#endif
+    }
+  else
+    {
+      p=buf;
+      rnum=((len+7)/8*8);      /* round up to nearest eight */
+    }
+
+  if (des_rw_mode & DES_PCBC_MODE)
+    des_pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+                (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); 
+  else
+    des_cbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+               (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); 
+
+  /* output */
+  outnum=rnum+HDRSIZE;
+
+  for (j=0; j<outnum; j+=i)
+    {
+      /* eay 26/08/92 I was not doing writing from where we
+       * got upto. */
+      i=write(fd,&(outbuf[j]),(int)(outnum-j));
+      if (i == -1)
+       {
+         if (errno == EINTR)
+           i=0;
+         else                  /* This is really a bad error - very bad
+                                * It will stuff-up both ends. */
+           return(-1);
+       }
+    }
+
+  return(len);
+}
diff --git a/kerberosIV/des/key_par.c b/kerberosIV/des/key_par.c
new file mode 100644 (file)
index 0000000..ab61990
--- /dev/null
@@ -0,0 +1,15 @@
+/*     $Id: key_par.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $        */
+
+#include "des_locl.h"
+
+/* MIT Link and source compatibility */
+
+#ifdef des_fixup_key_parity
+#undef des_fixup_key_parity
+#endif /* des_fixup_key_parity */
+
+void
+des_fixup_key_parity(des_cblock *key)
+{
+  des_set_odd_parity(key);
+}
diff --git a/kerberosIV/des/ofb_enc.c b/kerberosIV/des/ofb_enc.c
new file mode 100644 (file)
index 0000000..0a8883d
--- /dev/null
@@ -0,0 +1,63 @@
+/*     $Id: ofb_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+int des_ofb_encrypt(unsigned char *in, unsigned char *out, int numbits, long int length, struct des_ks_struct *schedule, des_cblock (*ivec))
+{
+  register u_int32_t d0,d1,v0,v1,n=(numbits+7)/8;
+  register u_int32_t mask0,mask1;
+  register long l=length;
+  register int num=numbits;
+  u_int32_t ti[2];
+  unsigned char *iv;
+
+  if (num > 64) return(0);
+  if (num > 32)
+    {
+      mask0=0xffffffff;
+      if (num >= 64)
+       mask1=mask0;
+      else
+       mask1=(1L<<(num-32))-1;
+    }
+  else
+    {
+      if (num == 32)
+       mask0=0xffffffff;
+      else
+       mask0=(1L<<num)-1;
+      mask1=0x00000000;
+    }
+
+  iv=(unsigned char *)ivec;
+  c2l(iv,v0);
+  c2l(iv,v1);
+  ti[0]=v0;
+  ti[1]=v1;
+  while (l-- > 0)
+    {
+      des_encrypt(ti,ti,
+                 schedule,DES_ENCRYPT);
+      c2ln(in,d0,d1,n);
+      in+=n;
+      d0=(d0^ti[0])&mask0;
+      d1=(d1^ti[1])&mask1;
+      l2cn(d0,d1,out,n);
+      out+=n;
+    }
+  v0=ti[0];
+  v1=ti[1];
+  iv=(unsigned char *)ivec;
+  l2c(v0,iv);
+  l2c(v1,iv);
+  v0=v1=d0=d1=ti[0]=ti[1]=0;
+  return(0);
+}
+
diff --git a/kerberosIV/des/pcbc_enc.c b/kerberosIV/des/pcbc_enc.c
new file mode 100644 (file)
index 0000000..3cc97a6
--- /dev/null
@@ -0,0 +1,68 @@
+/*     $Id: pcbc_enc.c,v 1.1.1.1 1995/12/14 06:52:44 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+int des_pcbc_encrypt(des_cblock (*input), des_cblock (*output), long int length, struct des_ks_struct *schedule, des_cblock (*ivec), int encrypt)
+{
+  register u_int32_t sin0,sin1,xor0,xor1,tout0,tout1;
+  u_int32_t tin[2],tout[2];
+  unsigned char *in,*out,*iv;
+
+  in=(unsigned char *)input;
+  out=(unsigned char *)output;
+  iv=(unsigned char *)ivec;
+
+  if (encrypt)
+    {
+      c2l(iv,xor0);
+      c2l(iv,xor1);
+      for (; length>0; length-=8)
+       {
+         if (length >= 8)
+           {
+             c2l(in,sin0);
+             c2l(in,sin1);
+           }
+         else
+           c2ln(in,sin0,sin1,length);
+         tin[0]=sin0^xor0;
+         tin[1]=sin1^xor1;
+         des_encrypt(tin,tout,
+                     schedule,encrypt);
+         tout0=tout[0];
+         tout1=tout[1];
+         xor0=sin0^tout[0];
+         xor1=sin1^tout[1];
+         l2c(tout0,out);
+         l2c(tout1,out);
+       }
+    }
+  else
+    {
+      c2l(iv,xor0); c2l(iv,xor1);
+      for (; length>0; length-=8)
+       {
+         c2l(in,sin0);
+         c2l(in,sin1);
+         tin[0]=sin0;
+         tin[1]=sin1;
+         des_encrypt(tin,tout,
+                     schedule,encrypt);
+         tout0=tout[0]^xor0;
+         tout1=tout[1]^xor1;
+         if (length >= 8)
+           {
+             l2c(tout0,out);
+             l2c(tout1,out);
+           }
+         else
+           l2cn(tout0,tout1,out,length);
+         xor0=tout0^sin0;
+         xor1=tout1^sin1;
+       }
+    }
+  tin[0]=tin[1]=tout[0]=tout[1]=0;
+  sin0=sin1=xor0=xor1=tout0=tout1=0;
+  return(0);
+}
diff --git a/kerberosIV/des/podd.h b/kerberosIV/des/podd.h
new file mode 100644 (file)
index 0000000..2e959b8
--- /dev/null
@@ -0,0 +1,20 @@
+/*     $Id: podd.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $   */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+static unsigned char odd_parity[256]={
+  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
diff --git a/kerberosIV/des/qud_cksm.c b/kerberosIV/des/qud_cksm.c
new file mode 100644 (file)
index 0000000..7ce5c35
--- /dev/null
@@ -0,0 +1,84 @@
+/* Copyright (C) 1993 Eric Young - see README for more details */
+/* From "Message Authentication"  R.R. Jueneman, S.M. Matyas, C.H. Meyer
+ * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40
+ * This module in only based on the code in this paper and is
+ * almost definitely not the same as the MIT implementation.
+ *
+ *     $Id: qud_cksm.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define B0(a)  (((u_int32_t)(a)))
+#define B1(a)  (((u_int32_t)(a))<<8)
+#define B2(a)  (((u_int32_t)(a))<<16)
+#define B3(a)  (((u_int32_t)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE  ((u_int32_t)83653421)
+
+u_int32_t des_quad_cksum(des_cblock (*input), des_cblock (*output), long int length, int out_count, des_cblock (*seed))
+{
+  u_int32_t z0,z1,t0,t1;
+  int i;
+  long l=0;
+  unsigned char *cp;
+  unsigned char *lp;
+
+  if (out_count < 1) out_count=1;
+  lp=(unsigned char *)output;
+
+  z0=B0((*seed)[0])|B1((*seed)[1])|B2((*seed)[2])|B3((*seed)[3]);
+  z1=B0((*seed)[4])|B1((*seed)[5])|B2((*seed)[6])|B3((*seed)[7]);
+
+  for (i=0; ((i<4)&&(i<out_count)); i++)
+    {
+      cp=(unsigned char *)input;
+      l=length;
+      while (l > 0)
+       {
+         if (l > 1)
+           {
+             t0= (u_int32_t)(*(cp++));
+             t0|=(u_int32_t)B1(*(cp++));
+             l--;
+           }
+         else
+           t0= (u_int32_t)(*(cp++));
+         l--;
+         /* add */
+         t0+=z0;
+         t0&=0xffffffff;
+         t1=z1;
+         /* square, well sort of square */
+         z0=((((t0*t0)&0xffffffff)+((t1*t1)&0xffffffff))
+             &0xffffffff)%0x7fffffff; 
+         z1=((t0*((t1+NOISE)&0xffffffff))&0xffffffff)%0x7fffffff;
+       }
+      if (lp != NULL)
+       {
+         /* I believe I finally have things worked out.
+          * The MIT library assumes that the checksum
+          * is one huge number and it is returned in a
+          * host dependant byte order.
+          */
+         static u_int32_t l=1;
+         static unsigned char *c=(unsigned char *)&l;
+
+         if (c[0])
+           {
+             l2c(z0,lp);
+             l2c(z1,lp);
+           }
+         else
+           {
+             lp=output[out_count-i-1];
+             l2n(z1,lp);
+             l2n(z0,lp);
+           }
+       }
+    }
+  return(z0);
+}
+
diff --git a/kerberosIV/des/random_key.c b/kerberosIV/des/random_key.c
new file mode 100644 (file)
index 0000000..d228741
--- /dev/null
@@ -0,0 +1,34 @@
+/*     $Id: random_key.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $     */
+
+/* Copyright (C) 1992 Eric Young - see COPYING for more details */
+#include "des_locl.h"
+
+void des_random_key(ret)
+des_cblock ret;
+       {
+       des_key_schedule ks;
+       static u_int32_t c=0;
+       static pid_t pid=0;
+       static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+       des_cblock key;
+
+#ifdef MSDOS
+       pid=1;
+#else
+       if (!pid) pid=getpid();
+#endif
+       ((u_int32_t *)key)[0]=(u_int32_t)time(NULL);
+       ((u_int32_t *)key)[1]=(u_int32_t)((pid)|((c++)<<16));
+
+       des_set_odd_parity((des_cblock *)data);
+       des_set_key((des_cblock *)data,ks);
+       des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+               (int32_t)sizeof(key),ks,(des_cblock *)data);
+       des_set_odd_parity((des_cblock *)key);
+       des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+               (int32_t)sizeof(key),ks,(des_cblock *)data);
+
+       bcopy(key,ret,sizeof(key));
+       bzero(key,sizeof(key));
+       bzero(ks,sizeof(ks));
+       }
diff --git a/kerberosIV/des/read_pwd.c b/kerberosIV/des/read_pwd.c
new file mode 100644 (file)
index 0000000..fd482ce
--- /dev/null
@@ -0,0 +1,285 @@
+/*     $Id: read_pwd.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+/* 06-Apr-92 Luke Brennan    Support for VMS */
+#include "des_locl.h"
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+
+/* Ick! */
+#if defined(__svr4__) || defined(__sgi) || defined(linux)
+#define TERMIO
+#endif
+
+#ifndef VMS
+#ifndef MSDOS
+#ifdef TERMIO
+#include <termio.h>
+#define sgttyb termio
+#define sg_flags c_lflag
+#define TIOCGETP TCGETA
+#define TIOCSETP TCSETA
+#else /* !TERMIO */
+#include <sgtty.h>
+#endif
+#include <sys/ioctl.h>
+#else /* MSDOS */
+#define fgets(a,b,c) noecho_fgets(a,b,c)
+#endif
+#else /* VMS */
+#include <ssdef.h>
+#include <iodef.h>
+#include <ttdef.h>
+#include <descrip.h>
+struct IOSB {
+       short iosb$w_value;
+       short iosb$w_count;
+       long  iosb$l_info;
+       };
+#endif
+#ifndef NSIG
+#define NSIG 32
+#endif
+
+static void read_till_nl();
+static int read_pw();
+static void recsig();
+static void pushsig();
+static void popsig();
+#ifdef MSDOS
+static int noecho_fgets();
+#endif
+
+static void (*savsig[NSIG])();
+static jmp_buf save;
+
+int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+       {
+       int ok;
+       char buf[BUFSIZ],buff[BUFSIZ];
+
+       if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+               des_string_to_key(buf,key);
+       bzero(buf,BUFSIZ);
+       bzero(buff,BUFSIZ);
+       return(ok);
+       }
+
+int des_read_2passwords(key1,key2,prompt,verify)
+des_cblock *key1;
+des_cblock *key2;
+char *prompt;
+int verify;
+       {
+       int ok;
+       char buf[BUFSIZ],buff[BUFSIZ];
+
+       if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+               des_string_to_2keys(buf,key1,key2);
+       bzero(buf,BUFSIZ);
+       bzero(buff,BUFSIZ);
+       return(ok);
+       }
+
+int des_read_pw_string(buf,length,prompt,verify)
+char *buf;
+int length;
+char *prompt;
+int verify;
+       {
+       char buff[BUFSIZ];
+       int ret;
+
+       ret=read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
+       bzero(buff,BUFSIZ);
+       return(ret);
+       }
+
+static void read_till_nl(in)
+FILE *in;
+       {
+#define SIZE 4
+       char buf[SIZE+1];
+
+       do      {
+               fgets(buf,SIZE,in);
+               } while (strchr(buf,'\n') == NULL);
+       }
+
+/* return 0 if ok, 1 (or -1) otherwise */
+static int read_pw(buf,buff,size,prompt,verify)
+char *buf,*buff;
+int size;
+char *prompt;
+int verify;
+       {
+#ifndef VMS
+#ifndef MSDOS
+       struct sgttyb tty_orig,tty_new;
+#endif /* !MSDOS */
+#else
+       struct IOSB iosb;
+       $DESCRIPTOR(terminal,"TT");
+       long tty_orig[3], tty_new[3];
+       long status;
+       unsigned short channel = 0;
+#endif
+       int ok=0;
+       char *p;
+       int ps=0;
+       FILE *tty;
+
+#ifndef MSDOS
+       if ((tty=fopen("/dev/tty","r")) == NULL)
+               tty=stdin;
+#else /* MSDOS */
+       if ((tty=fopen("con","r")) == NULL)
+               tty=stdin;
+#endif /* MSDOS */
+#ifndef VMS
+#ifdef TIOCGETP
+       if (ioctl(fileno(tty),TIOCGETP,(char *)&tty_orig) == -1)
+               return(-1);
+       bcopy(&(tty_orig),&(tty_new),sizeof(tty_orig));
+#endif
+#else /* VMS */
+       status = SYS$ASSIGN(&terminal,&channel,0,0);
+       if (status != SS$_NORMAL)
+               return(-1);
+       status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
+       if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+               return(-1);
+#endif
+
+       if (setjmp(save))
+               {
+               ok=0;
+               goto error;
+               }
+       pushsig();
+       ps=1;
+#ifndef VMS
+#ifndef MSDOS
+       tty_new.sg_flags &= ~ECHO;
+#endif /* !MSDOS */
+#ifdef TIOCSETP
+       if (ioctl(fileno(tty),TIOCSETP,(char *)&tty_new) == -1)
+               return(-1);
+#endif
+#else /* VMS */
+       tty_new[0] = tty_orig[0];
+       tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+       tty_new[2] = tty_orig[2];
+       status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
+       if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+               return(-1);
+#endif /* VMS */
+       ps=2;
+
+       while (!ok)
+               {
+               fputs(prompt,stderr);
+               fflush(stderr);
+
+               buf[0]='\0';
+               fgets(buf,size,tty);
+               if (feof(tty)) goto error;
+               if ((p=(char *)strchr(buf,'\n')) != NULL)
+                       *p='\0';
+               else    read_till_nl(tty);
+               if (verify)
+                       {
+                       fprintf(stderr,"\nVerifying password %s",prompt);
+                       fflush(stderr);
+                       buff[0]='\0';
+                       fgets(buff,size,tty);
+                       if (feof(tty)) goto error;
+                       if ((p=(char *)strchr(buff,'\n')) != NULL)
+                               *p='\0';
+                       else    read_till_nl(tty);
+                               
+                       if (strcmp(buf,buff) != 0)
+                               {
+                               fprintf(stderr,"\nVerify failure - try again\n");
+                               fflush(stderr);
+                               continue;
+                               }
+                       }
+               ok=1;
+               }
+
+error:
+       fprintf(stderr,"\n");
+       /* What can we do if there is an error? */
+#ifndef VMS
+#ifdef TIOCSETP
+       if (ps >= 2) ioctl(fileno(tty),TIOCSETP,(char *)&tty_orig);
+#endif
+#else /* VMS */
+       if (ps >= 2)
+               status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0
+                       ,tty_orig,12,0,0,0,0);
+#endif /* VMS */
+       
+       if (ps >= 1) popsig();
+       if (stdin != tty) fclose(tty);
+#ifdef VMS
+       status = SYS$DASSGN(channel);
+#endif
+       return(!ok);
+       }
+
+static void pushsig()
+       {
+       int i;
+
+       for (i=0; i<NSIG; i++)
+               savsig[i]=signal(i,recsig);
+       }
+
+static void popsig()
+       {
+       int i;
+
+       for (i=0; i<NSIG; i++)
+               signal(i,savsig[i]);
+       }
+
+static void recsig()
+       {
+       longjmp(save,1);
+       }
+
+#ifdef MSDOS
+static int noecho_fgets(buf,size,tty)
+char *buf;
+int size;
+FILE *tty;
+       {
+       int i;
+       char *p;
+
+       p=buf;
+       for (;;)
+               {
+               if (size == 0)
+                       {
+                       *p='\0';
+                       break;
+                       }
+               size--;
+               i=getch();
+               if (i == '\r') i='\n';
+               *(p++)=i;
+               if (i == '\n')
+                       {
+                       *p='\0';
+                       break;
+                       }
+               }
+       }
+#endif
diff --git a/kerberosIV/des/rnd_keys.c b/kerberosIV/des/rnd_keys.c
new file mode 100644 (file)
index 0000000..124428a
--- /dev/null
@@ -0,0 +1,125 @@
+/*     $Id: rnd_keys.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $       */
+
+/* Copyright (C) 1993 Eric Young - see COPYING for more details */
+#include "des_locl.h"
+#include <sys/time.h>
+
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+/*
+ * Create a sequence of random 64 bit blocks.
+ * The sequence is indexed with a long long and 
+ * based on an initial des key used as a seed.
+ */
+static des_key_schedule sequence_seed;
+static u_int32_t sequence_index[2];
+
+/*
+ * In case the generator does not get inited use this for backup.
+ */
+static int initialized;
+static des_cblock default_seed = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static void
+do_initialize()
+{
+  des_set_odd_parity(&default_seed);
+  des_set_random_generator_seed(&default_seed);
+}
+
+#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0)
+
+#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0)
+
+#define des_set_sequence_number(ll) \
+do { \
+       memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); \
+     } while (0)
+
+#define des_generate_random_block(ret) \
+do { \
+       des_ecb_encrypt((des_cblock *) sequence_index, (ret), sequence_seed, DES_ENCRYPT); \
+        incr_long_long(sequence_index); \
+     } while (0)
+
+void
+des_set_random_generator_seed(des_cblock *seed)
+{
+  des_key_sched(seed, sequence_seed);
+  zero_long_long(sequence_index);
+  initialized = 1;
+}
+
+/*
+ * Generate a sequence of random des keys
+ * using the random block sequence, fixup
+ * parity and skip weak keys.
+ */
+int
+des_new_random_key(des_cblock *key)
+{
+  if (!initialized)
+    do_initialize();
+
+ try_again:
+  des_generate_random_block(key);
+  /* random key must have odd parity and not be weak */
+  des_set_odd_parity(key);
+  if (des_is_weak_key(key))
+    goto try_again;
+  return(0);
+}
+
+/*
+ * des_init_random_number_generator:
+ *
+ *    This routine takes a secret key possibly shared by a number
+ * of servers and uses it to generate a random number stream that is
+ * not shared by any of the other servers.  It does this by using the current
+ * process id, host id, and the current time to the nearest second.  The
+ * resulting stream seed is not useful information for cracking the secret
+ * key.   Moreover, this routine keeps no copy of the secret key.
+ *
+ */
+void 
+des_init_random_number_generator(des_cblock *seed)
+{
+  struct timeval now;
+  static long uniq[2];
+  des_cblock new_key;
+  long gethostid(void);
+
+  gettimeofday(&now, (struct timezone *)0);
+  if (!uniq[0])
+    {
+      struct hostent *hent;
+      char hostname[100];
+      gethostname(hostname, sizeof(hostname));
+      hent = gethostbyname(hostname);
+      if (hent != NULL)
+       bcopy(hent->h_addr_list[0], &uniq[0], sizeof(uniq[0]));
+      else
+       uniq[0] = gethostid();
+#ifdef MSDOS
+      uniq[1] = 1;
+#else
+      uniq[1] = getpid();
+#endif
+    }
+
+  /* Pick a unique random key from the shared sequence. */
+  des_set_random_generator_seed(seed);
+  des_set_sequence_number((unsigned char *)uniq);
+  des_new_random_key(&new_key);
+
+  /* Select a new nonshared sequence, */
+  des_set_random_generator_seed(&new_key);
+
+  /* and use the current time to pick a key for the new sequence. */
+  des_set_sequence_number((unsigned char *)&now);
+  des_new_random_key(&new_key);
+  des_set_random_generator_seed(&new_key);
+}
diff --git a/kerberosIV/des/set_key.c b/kerberosIV/des/set_key.c
new file mode 100644 (file)
index 0000000..e7a0186
--- /dev/null
@@ -0,0 +1,179 @@
+/*     $Id: set_key.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include "des_locl.h"
+#include "podd.h"
+#include "sk.h"
+
+static int check_parity(des_cblock (*key));
+
+int des_check_key=0;
+
+void des_set_odd_parity(des_cblock (*key))
+{
+  int i;
+
+  for (i=0; i<DES_KEY_SZ; i++)
+    (*key)[i]=odd_parity[(*key)[i]];
+}
+
+static int check_parity(des_cblock (*key))
+{
+  int i;
+
+  for (i=0; i<DES_KEY_SZ; i++)
+    {
+      if ((*key)[i] != odd_parity[(*key)[i]])
+       return(0);
+    }
+  return(1);
+}
+
+/* Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY   16
+static des_cblock weak_keys[NUM_WEAK_KEY]={
+  /* weak keys */
+  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+  0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+  0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+  0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+  /* semi-weak keys */
+  0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,
+  0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,
+  0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1,
+  0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E,
+  0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,
+  0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01,
+  0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE,
+  0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,
+  0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,
+  0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01,
+  0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
+  0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1};
+
+int des_is_weak_key(des_cblock (*key))
+{
+  int i;
+
+  for (i=0; i<NUM_WEAK_KEY; i++)
+    /* Added == 0 to comparision, I obviously don't run
+     * this section very often :-(, thanks to
+     * engineering@MorningStar.Com for the fix
+     * eay 93/06/29 */
+    if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
+  return(0);
+}
+
+/* NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros. 
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+                              *        (b)^=(t),\
+                              *        (a)=((a)^((t)<<(n))))
+                              */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+                          (a)=(a)^(t)^(t>>(16-(n))))
+
+static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int des_set_key(des_cblock (*key), struct des_ks_struct *schedule)
+{
+  register u_int32_t c,d,t,s;
+  register unsigned char *in;
+  register u_int32_t *k;
+  register int i;
+
+  if (des_check_key)
+    {
+      if (!check_parity(key))
+       return(-1);
+
+      if (des_is_weak_key(key))
+       return(-2);
+    }
+
+  k=(u_int32_t *)schedule;
+  in=(unsigned char *)key;
+
+  c2l(in,c);
+  c2l(in,d);
+
+  /* do PC1 in 60 simple operations */ 
+  /*   PERM_OP(d,c,t,4,0x0f0f0f0f);
+       HPERM_OP(c,t,-2, 0xcccc0000);
+       HPERM_OP(c,t,-1, 0xaaaa0000);
+       HPERM_OP(c,t, 8, 0x00ff0000);
+       HPERM_OP(c,t,-1, 0xaaaa0000);
+       HPERM_OP(d,t,-8, 0xff000000);
+       HPERM_OP(d,t, 8, 0x00ff0000);
+       HPERM_OP(d,t, 2, 0x33330000);
+       d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55);
+       d=(d>>8)|((c&0xf0000000)>>4);
+       c&=0x0fffffff; */
+
+  /* I now do it in 47 simple operations :-)
+   * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+   * for the inspiration. :-) */
+  PERM_OP (d,c,t,4,0x0f0f0f0f);
+  HPERM_OP(c,t,-2,0xcccc0000);
+  HPERM_OP(d,t,-2,0xcccc0000);
+  PERM_OP (d,c,t,1,0x55555555);
+  PERM_OP (c,d,t,8,0x00ff00ff);
+  PERM_OP (d,c,t,1,0x55555555);
+  d=   (((d&0x000000ff)<<16)| (d&0x0000ff00)     |
+        ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
+  c&=0x0fffffff;
+
+  for (i=0; i<ITERATIONS; i++)
+    {
+      if (shifts2[i])
+       { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
+      else
+       { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
+      c&=0x0fffffff;
+      d&=0x0fffffff;
+      /* could be a few less shifts but I am to lazy at this
+       * point in time to investigate */
+      s=       des_skb[0][ (c    )&0x3f                ]|
+       des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
+         des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
+           des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
+                      ((c>>22)&0x38)];
+      t=       des_skb[4][ (d    )&0x3f                ]|
+       des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
+         des_skb[6][ (d>>15)&0x3f                ]|
+           des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
+
+      /* table contained 0213 4657 */
+      *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
+      s=     ((s>>16)|(t&0xffff0000));
+               
+      s=(s<<4)|(s>>28);
+      *(k++)=s&0xffffffff;
+    }
+  return(0);
+}
+
+int des_key_sched(des_cblock *key, des_key_schedule schedule)
+{
+  return(des_set_key(key, (struct des_ks_struct *)schedule));
+}
diff --git a/kerberosIV/des/shlib_version b/kerberosIV/des/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/des/sk.h b/kerberosIV/des/sk.h
new file mode 100644 (file)
index 0000000..31bec90
--- /dev/null
@@ -0,0 +1,141 @@
+/*     $Id: sk.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $     */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+static u_int32_t des_skb[8][64]={
+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x00000010,0x20000000,0x20000010,
+0x00010000,0x00010010,0x20010000,0x20010010,
+0x00000800,0x00000810,0x20000800,0x20000810,
+0x00010800,0x00010810,0x20010800,0x20010810,
+0x00000020,0x00000030,0x20000020,0x20000030,
+0x00010020,0x00010030,0x20010020,0x20010030,
+0x00000820,0x00000830,0x20000820,0x20000830,
+0x00010820,0x00010830,0x20010820,0x20010830,
+0x00080000,0x00080010,0x20080000,0x20080010,
+0x00090000,0x00090010,0x20090000,0x20090010,
+0x00080800,0x00080810,0x20080800,0x20080810,
+0x00090800,0x00090810,0x20090800,0x20090810,
+0x00080020,0x00080030,0x20080020,0x20080030,
+0x00090020,0x00090030,0x20090020,0x20090030,
+0x00080820,0x00080830,0x20080820,0x20080830,
+0x00090820,0x00090830,0x20090820,0x20090830,
+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+0x00000000,0x02000000,0x00002000,0x02002000,
+0x00200000,0x02200000,0x00202000,0x02202000,
+0x00000004,0x02000004,0x00002004,0x02002004,
+0x00200004,0x02200004,0x00202004,0x02202004,
+0x00000400,0x02000400,0x00002400,0x02002400,
+0x00200400,0x02200400,0x00202400,0x02202400,
+0x00000404,0x02000404,0x00002404,0x02002404,
+0x00200404,0x02200404,0x00202404,0x02202404,
+0x10000000,0x12000000,0x10002000,0x12002000,
+0x10200000,0x12200000,0x10202000,0x12202000,
+0x10000004,0x12000004,0x10002004,0x12002004,
+0x10200004,0x12200004,0x10202004,0x12202004,
+0x10000400,0x12000400,0x10002400,0x12002400,
+0x10200400,0x12200400,0x10202400,0x12202400,
+0x10000404,0x12000404,0x10002404,0x12002404,
+0x10200404,0x12200404,0x10202404,0x12202404,
+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+0x00000000,0x00000001,0x00040000,0x00040001,
+0x01000000,0x01000001,0x01040000,0x01040001,
+0x00000002,0x00000003,0x00040002,0x00040003,
+0x01000002,0x01000003,0x01040002,0x01040003,
+0x00000200,0x00000201,0x00040200,0x00040201,
+0x01000200,0x01000201,0x01040200,0x01040201,
+0x00000202,0x00000203,0x00040202,0x00040203,
+0x01000202,0x01000203,0x01040202,0x01040203,
+0x08000000,0x08000001,0x08040000,0x08040001,
+0x09000000,0x09000001,0x09040000,0x09040001,
+0x08000002,0x08000003,0x08040002,0x08040003,
+0x09000002,0x09000003,0x09040002,0x09040003,
+0x08000200,0x08000201,0x08040200,0x08040201,
+0x09000200,0x09000201,0x09040200,0x09040201,
+0x08000202,0x08000203,0x08040202,0x08040203,
+0x09000202,0x09000203,0x09040202,0x09040203,
+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+0x00000000,0x00100000,0x00000100,0x00100100,
+0x00000008,0x00100008,0x00000108,0x00100108,
+0x00001000,0x00101000,0x00001100,0x00101100,
+0x00001008,0x00101008,0x00001108,0x00101108,
+0x04000000,0x04100000,0x04000100,0x04100100,
+0x04000008,0x04100008,0x04000108,0x04100108,
+0x04001000,0x04101000,0x04001100,0x04101100,
+0x04001008,0x04101008,0x04001108,0x04101108,
+0x00020000,0x00120000,0x00020100,0x00120100,
+0x00020008,0x00120008,0x00020108,0x00120108,
+0x00021000,0x00121000,0x00021100,0x00121100,
+0x00021008,0x00121008,0x00021108,0x00121108,
+0x04020000,0x04120000,0x04020100,0x04120100,
+0x04020008,0x04120008,0x04020108,0x04120108,
+0x04021000,0x04121000,0x04021100,0x04121100,
+0x04021008,0x04121008,0x04021108,0x04121108,
+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x10000000,0x00010000,0x10010000,
+0x00000004,0x10000004,0x00010004,0x10010004,
+0x20000000,0x30000000,0x20010000,0x30010000,
+0x20000004,0x30000004,0x20010004,0x30010004,
+0x00100000,0x10100000,0x00110000,0x10110000,
+0x00100004,0x10100004,0x00110004,0x10110004,
+0x20100000,0x30100000,0x20110000,0x30110000,
+0x20100004,0x30100004,0x20110004,0x30110004,
+0x00001000,0x10001000,0x00011000,0x10011000,
+0x00001004,0x10001004,0x00011004,0x10011004,
+0x20001000,0x30001000,0x20011000,0x30011000,
+0x20001004,0x30001004,0x20011004,0x30011004,
+0x00101000,0x10101000,0x00111000,0x10111000,
+0x00101004,0x10101004,0x00111004,0x10111004,
+0x20101000,0x30101000,0x20111000,0x30111000,
+0x20101004,0x30101004,0x20111004,0x30111004,
+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+0x00000000,0x08000000,0x00000008,0x08000008,
+0x00000400,0x08000400,0x00000408,0x08000408,
+0x00020000,0x08020000,0x00020008,0x08020008,
+0x00020400,0x08020400,0x00020408,0x08020408,
+0x00000001,0x08000001,0x00000009,0x08000009,
+0x00000401,0x08000401,0x00000409,0x08000409,
+0x00020001,0x08020001,0x00020009,0x08020009,
+0x00020401,0x08020401,0x00020409,0x08020409,
+0x02000000,0x0A000000,0x02000008,0x0A000008,
+0x02000400,0x0A000400,0x02000408,0x0A000408,
+0x02020000,0x0A020000,0x02020008,0x0A020008,
+0x02020400,0x0A020400,0x02020408,0x0A020408,
+0x02000001,0x0A000001,0x02000009,0x0A000009,
+0x02000401,0x0A000401,0x02000409,0x0A000409,
+0x02020001,0x0A020001,0x02020009,0x0A020009,
+0x02020401,0x0A020401,0x02020409,0x0A020409,
+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+0x00000000,0x00000100,0x00080000,0x00080100,
+0x01000000,0x01000100,0x01080000,0x01080100,
+0x00000010,0x00000110,0x00080010,0x00080110,
+0x01000010,0x01000110,0x01080010,0x01080110,
+0x00200000,0x00200100,0x00280000,0x00280100,
+0x01200000,0x01200100,0x01280000,0x01280100,
+0x00200010,0x00200110,0x00280010,0x00280110,
+0x01200010,0x01200110,0x01280010,0x01280110,
+0x00000200,0x00000300,0x00080200,0x00080300,
+0x01000200,0x01000300,0x01080200,0x01080300,
+0x00000210,0x00000310,0x00080210,0x00080310,
+0x01000210,0x01000310,0x01080210,0x01080310,
+0x00200200,0x00200300,0x00280200,0x00280300,
+0x01200200,0x01200300,0x01280200,0x01280300,
+0x00200210,0x00200310,0x00280210,0x00280310,
+0x01200210,0x01200310,0x01280210,0x01280310,
+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+0x00000000,0x04000000,0x00040000,0x04040000,
+0x00000002,0x04000002,0x00040002,0x04040002,
+0x00002000,0x04002000,0x00042000,0x04042000,
+0x00002002,0x04002002,0x00042002,0x04042002,
+0x00000020,0x04000020,0x00040020,0x04040020,
+0x00000022,0x04000022,0x00040022,0x04040022,
+0x00002020,0x04002020,0x00042020,0x04042020,
+0x00002022,0x04002022,0x00042022,0x04042022,
+0x00000800,0x04000800,0x00040800,0x04040800,
+0x00000802,0x04000802,0x00040802,0x04040802,
+0x00002800,0x04002800,0x00042800,0x04042800,
+0x00002802,0x04002802,0x00042802,0x04042802,
+0x00000820,0x04000820,0x00040820,0x04040820,
+0x00000822,0x04000822,0x00040822,0x04040822,
+0x00002820,0x04002820,0x00042820,0x04042820,
+0x00002822,0x04002822,0x00042822,0x04042822,
+};
diff --git a/kerberosIV/des/spr.h b/kerberosIV/des/spr.h
new file mode 100644 (file)
index 0000000..aea087b
--- /dev/null
@@ -0,0 +1,147 @@
+/*     $Id: spr.h,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $    */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+static u_int32_t des_SPtrans[8][64]={
+/* nibble 0 */
+0x00820200, 0x00020000, 0x80800000, 0x80820200,
+0x00800000, 0x80020200, 0x80020000, 0x80800000,
+0x80020200, 0x00820200, 0x00820000, 0x80000200,
+0x80800200, 0x00800000, 0x00000000, 0x80020000,
+0x00020000, 0x80000000, 0x00800200, 0x00020200,
+0x80820200, 0x00820000, 0x80000200, 0x00800200,
+0x80000000, 0x00000200, 0x00020200, 0x80820000,
+0x00000200, 0x80800200, 0x80820000, 0x00000000,
+0x00000000, 0x80820200, 0x00800200, 0x80020000,
+0x00820200, 0x00020000, 0x80000200, 0x00800200,
+0x80820000, 0x00000200, 0x00020200, 0x80800000,
+0x80020200, 0x80000000, 0x80800000, 0x00820000,
+0x80820200, 0x00020200, 0x00820000, 0x80800200,
+0x00800000, 0x80000200, 0x80020000, 0x00000000,
+0x00020000, 0x00800000, 0x80800200, 0x00820200,
+0x80000000, 0x80820000, 0x00000200, 0x80020200,
+
+/* nibble 1 */
+0x10042004, 0x00000000, 0x00042000, 0x10040000,
+0x10000004, 0x00002004, 0x10002000, 0x00042000,
+0x00002000, 0x10040004, 0x00000004, 0x10002000,
+0x00040004, 0x10042000, 0x10040000, 0x00000004,
+0x00040000, 0x10002004, 0x10040004, 0x00002000,
+0x00042004, 0x10000000, 0x00000000, 0x00040004,
+0x10002004, 0x00042004, 0x10042000, 0x10000004,
+0x10000000, 0x00040000, 0x00002004, 0x10042004,
+0x00040004, 0x10042000, 0x10002000, 0x00042004,
+0x10042004, 0x00040004, 0x10000004, 0x00000000,
+0x10000000, 0x00002004, 0x00040000, 0x10040004,
+0x00002000, 0x10000000, 0x00042004, 0x10002004,
+0x10042000, 0x00002000, 0x00000000, 0x10000004,
+0x00000004, 0x10042004, 0x00042000, 0x10040000,
+0x10040004, 0x00040000, 0x00002004, 0x10002000,
+0x10002004, 0x00000004, 0x10040000, 0x00042000,
+
+/* nibble 2 */
+0x41000000, 0x01010040, 0x00000040, 0x41000040,
+0x40010000, 0x01000000, 0x41000040, 0x00010040,
+0x01000040, 0x00010000, 0x01010000, 0x40000000,
+0x41010040, 0x40000040, 0x40000000, 0x41010000,
+0x00000000, 0x40010000, 0x01010040, 0x00000040,
+0x40000040, 0x41010040, 0x00010000, 0x41000000,
+0x41010000, 0x01000040, 0x40010040, 0x01010000,
+0x00010040, 0x00000000, 0x01000000, 0x40010040,
+0x01010040, 0x00000040, 0x40000000, 0x00010000,
+0x40000040, 0x40010000, 0x01010000, 0x41000040,
+0x00000000, 0x01010040, 0x00010040, 0x41010000,
+0x40010000, 0x01000000, 0x41010040, 0x40000000,
+0x40010040, 0x41000000, 0x01000000, 0x41010040,
+0x00010000, 0x01000040, 0x41000040, 0x00010040,
+0x01000040, 0x00000000, 0x41010000, 0x40000040,
+0x41000000, 0x40010040, 0x00000040, 0x01010000,
+
+/* nibble 3 */
+0x00100402, 0x04000400, 0x00000002, 0x04100402,
+0x00000000, 0x04100000, 0x04000402, 0x00100002,
+0x04100400, 0x04000002, 0x04000000, 0x00000402,
+0x04000002, 0x00100402, 0x00100000, 0x04000000,
+0x04100002, 0x00100400, 0x00000400, 0x00000002,
+0x00100400, 0x04000402, 0x04100000, 0x00000400,
+0x00000402, 0x00000000, 0x00100002, 0x04100400,
+0x04000400, 0x04100002, 0x04100402, 0x00100000,
+0x04100002, 0x00000402, 0x00100000, 0x04000002,
+0x00100400, 0x04000400, 0x00000002, 0x04100000,
+0x04000402, 0x00000000, 0x00000400, 0x00100002,
+0x00000000, 0x04100002, 0x04100400, 0x00000400,
+0x04000000, 0x04100402, 0x00100402, 0x00100000,
+0x04100402, 0x00000002, 0x04000400, 0x00100402,
+0x00100002, 0x00100400, 0x04100000, 0x04000402,
+0x00000402, 0x04000000, 0x04000002, 0x04100400,
+
+/* nibble 4 */
+0x02000000, 0x00004000, 0x00000100, 0x02004108,
+0x02004008, 0x02000100, 0x00004108, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x00004100,
+0x02000108, 0x02004008, 0x02004100, 0x00000000,
+0x00004100, 0x02000000, 0x00004008, 0x00000108,
+0x02000100, 0x00004108, 0x00000000, 0x02000008,
+0x00000008, 0x02000108, 0x02004108, 0x00004008,
+0x02004000, 0x00000100, 0x00000108, 0x02004100,
+0x02004100, 0x02000108, 0x00004008, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x02000100,
+0x02000000, 0x00004100, 0x02004108, 0x00000000,
+0x00004108, 0x02000000, 0x00000100, 0x00004008,
+0x02000108, 0x00000100, 0x00000000, 0x02004108,
+0x02004008, 0x02004100, 0x00000108, 0x00004000,
+0x00004100, 0x02004008, 0x02000100, 0x00000108,
+0x00000008, 0x00004108, 0x02004000, 0x02000008,
+
+/* nibble 5 */
+0x20000010, 0x00080010, 0x00000000, 0x20080800,
+0x00080010, 0x00000800, 0x20000810, 0x00080000,
+0x00000810, 0x20080810, 0x00080800, 0x20000000,
+0x20000800, 0x20000010, 0x20080000, 0x00080810,
+0x00080000, 0x20000810, 0x20080010, 0x00000000,
+0x00000800, 0x00000010, 0x20080800, 0x20080010,
+0x20080810, 0x20080000, 0x20000000, 0x00000810,
+0x00000010, 0x00080800, 0x00080810, 0x20000800,
+0x00000810, 0x20000000, 0x20000800, 0x00080810,
+0x20080800, 0x00080010, 0x00000000, 0x20000800,
+0x20000000, 0x00000800, 0x20080010, 0x00080000,
+0x00080010, 0x20080810, 0x00080800, 0x00000010,
+0x20080810, 0x00080800, 0x00080000, 0x20000810,
+0x20000010, 0x20080000, 0x00080810, 0x00000000,
+0x00000800, 0x20000010, 0x20000810, 0x20080800,
+0x20080000, 0x00000810, 0x00000010, 0x20080010,
+
+/* nibble 6 */
+0x00001000, 0x00000080, 0x00400080, 0x00400001,
+0x00401081, 0x00001001, 0x00001080, 0x00000000,
+0x00400000, 0x00400081, 0x00000081, 0x00401000,
+0x00000001, 0x00401080, 0x00401000, 0x00000081,
+0x00400081, 0x00001000, 0x00001001, 0x00401081,
+0x00000000, 0x00400080, 0x00400001, 0x00001080,
+0x00401001, 0x00001081, 0x00401080, 0x00000001,
+0x00001081, 0x00401001, 0x00000080, 0x00400000,
+0x00001081, 0x00401000, 0x00401001, 0x00000081,
+0x00001000, 0x00000080, 0x00400000, 0x00401001,
+0x00400081, 0x00001081, 0x00001080, 0x00000000,
+0x00000080, 0x00400001, 0x00000001, 0x00400080,
+0x00000000, 0x00400081, 0x00400080, 0x00001080,
+0x00000081, 0x00001000, 0x00401081, 0x00400000,
+0x00401080, 0x00000001, 0x00001001, 0x00401081,
+0x00400001, 0x00401080, 0x00401000, 0x00001001,
+
+/* nibble 7 */
+0x08200020, 0x08208000, 0x00008020, 0x00000000,
+0x08008000, 0x00200020, 0x08200000, 0x08208020,
+0x00000020, 0x08000000, 0x00208000, 0x00008020,
+0x00208020, 0x08008020, 0x08000020, 0x08200000,
+0x00008000, 0x00208020, 0x00200020, 0x08008000,
+0x08208020, 0x08000020, 0x00000000, 0x00208000,
+0x08000000, 0x00200000, 0x08008020, 0x08200020,
+0x00200000, 0x00008000, 0x08208000, 0x00000020,
+0x00200000, 0x00008000, 0x08000020, 0x08208020,
+0x00008020, 0x08000000, 0x00000000, 0x00208000,
+0x08200020, 0x08008020, 0x08008000, 0x00200020,
+0x08208000, 0x00000020, 0x00200020, 0x08008000,
+0x08208020, 0x00200000, 0x08200000, 0x08000020,
+0x00208000, 0x00008020, 0x08008020, 0x08200000,
+0x00000020, 0x08208000, 0x00208020, 0x00000000,
+0x08000000, 0x08200020, 0x00008000, 0x00208020};
diff --git a/kerberosIV/des/str2key.c b/kerberosIV/des/str2key.c
new file mode 100644 (file)
index 0000000..115e26b
--- /dev/null
@@ -0,0 +1,113 @@
+/*     $Id: str2key.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $        */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include "des_locl.h"
+
+extern int des_check_key;
+
+int des_string_to_key(char *str, des_cblock (*key))
+{
+  des_key_schedule ks;
+  int i,length;
+  register unsigned char j;
+
+  memset(key,0,8);
+  length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+  for (i=0; i<length; i++)
+    (*key)[i%8]^=(str[i]<<1);
+#else  /* MIT COMPATIBLE */
+  for (i=0; i<length; i++)
+    {
+      j=str[i];
+      if ((i%16) < 8)
+       (*key)[i%8]^=(j<<1);
+      else
+       {
+         /* Reverse the bit order 05/05/92 eay */
+         j=((j<<4)&0xf0)|((j>>4)&0x0f);
+         j=((j<<2)&0xcc)|((j>>2)&0x33);
+         j=((j<<1)&0xaa)|((j>>1)&0x55);
+         (*key)[7-(i%8)]^=j;
+       }
+    }
+#endif
+  des_set_odd_parity((des_cblock *)key);
+  i=des_check_key;
+  des_check_key=0;
+  des_set_key((des_cblock *)key,ks);
+  des_check_key=i;
+  des_cbc_cksum((des_cblock *)str,(des_cblock *)key,(long)length,ks,
+               (des_cblock *)key);
+  memset(ks,0,sizeof(ks));
+  des_set_odd_parity((des_cblock *)key);
+  return(0);
+}
+
+int des_string_to_2keys(char *str, des_cblock (*key1), des_cblock (*key2))
+{
+  des_key_schedule ks;
+  int i,length;
+  register unsigned char j;
+
+  memset(key1,0,8);
+  memset(key2,0,8);
+  length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+  if (length <= 8)
+    {
+      for (i=0; i<length; i++)
+       {
+         (*key2)[i]=(*key1)[i]=(str[i]<<1);
+       }
+    }
+  else
+    {
+      for (i=0; i<length; i++)
+       {
+         if ((i/8)&1)
+           (*key2)[i%8]^=(str[i]<<1);
+         else
+           (*key1)[i%8]^=(str[i]<<1);
+       }
+    }
+#else  /* MIT COMPATIBLE */
+  for (i=0; i<length; i++)
+    {
+      j=str[i];
+      if ((i%32) < 16)
+       {
+         if ((i%16) < 8)
+           (*key1)[i%8]^=(j<<1);
+         else
+           (*key2)[i%8]^=(j<<1);
+       }
+      else
+       {
+         j=((j<<4)&0xf0)|((j>>4)&0x0f);
+         j=((j<<2)&0xcc)|((j>>2)&0x33);
+         j=((j<<1)&0xaa)|((j>>1)&0x55);
+         if ((i%16) < 8)
+           (*key1)[7-(i%8)]^=j;
+         else
+           (*key2)[7-(i%8)]^=j;
+       }
+    }
+  if (length <= 8) memcpy(key2,key1,8);
+#endif
+  des_set_odd_parity((des_cblock *)key1);
+  des_set_odd_parity((des_cblock *)key2);
+  i=des_check_key;
+  des_check_key=0;
+  des_set_key((des_cblock *)key1,ks);
+  des_cbc_cksum((des_cblock *)str,(des_cblock *)key1,(long)length,ks,
+               (des_cblock *)key1);
+  des_set_key((des_cblock *)key2,ks);
+  des_cbc_cksum((des_cblock *)str,(des_cblock *)key2,(long)length,ks,
+               (des_cblock *)key2);
+  des_check_key=i;
+  memset(ks,0,sizeof(ks));
+  des_set_odd_parity(key1);
+  des_set_odd_parity(key2);
+  return(0);
+}
diff --git a/kerberosIV/ext_srvtab/Makefile b/kerberosIV/ext_srvtab/Makefile
new file mode 100644 (file)
index 0000000..3b92c5f
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+
+PROG=  ext_srvtab
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   ext_srvtab.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/ext_srvtab/ext_srvtab.8 b/kerberosIV/ext_srvtab/ext_srvtab.8
new file mode 100644 (file)
index 0000000..1491e5e
--- /dev/null
@@ -0,0 +1,62 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: ext_srvtab.8,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ext_srvtab \- extract service key files from Kerberos key distribution center database
+.SH SYNOPSIS
+ext_srvtab [
+.B \-n
+] [
+.B \-r realm
+] [
+.B hostname ...
+]
+.SH DESCRIPTION
+.I ext_srvtab
+extracts service key files from the Kerberos key distribution center
+(KDC) database.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.  If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+For each
+.I hostname
+specified on the command line, 
+.I ext_srvtab
+creates the service key file
+.IR hostname -new-srvtab,
+containing all the entries in the database with an instance field of
+.I hostname.
+This new file contains all the keys registered for Kerberos-mediated
+service providing programs which use the 
+.IR krb_get_phost (3)
+principal and instance conventions to run on the host
+.IR hostname .
+If the
+.B \-r
+option is specified, the realm fields in the extracted file will
+match the given realm rather than the local realm.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+.IR hostname -new-srvtab
+Service key file generated for
+.I hostname
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH SEE ALSO
+read_service_key(3), krb_get_phost(3)
diff --git a/kerberosIV/ext_srvtab/ext_srvtab.c b/kerberosIV/ext_srvtab/ext_srvtab.c
new file mode 100644 (file)
index 0000000..13a8412
--- /dev/null
@@ -0,0 +1,158 @@
+/*     $Id: ext_srvtab.c,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $     */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <adm_locl.h>
+
+static des_cblock master_key;
+static des_cblock session_key;
+static des_key_schedule master_key_schedule;
+char progname[] = "ext_srvtab";
+static char realm[REALM_SZ];
+
+static void
+usage(void)
+{
+    fprintf(stderr, 
+           "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname);
+    exit(1);
+}
+
+static void
+StampOutSecrets(void)
+{
+    bzero(master_key, sizeof master_key);
+    bzero(session_key, sizeof session_key);
+    bzero(master_key_schedule, sizeof master_key_schedule);
+}
+
+static void
+Die(void)
+{
+    StampOutSecrets();
+    exit(1);
+}
+
+static void
+FWrite(char *p, int size, int n, FILE *f)
+{
+    if (fwrite(p, size, n, f) != n) {
+       printf("Error writing output file.  Terminating.\n");
+       Die();
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    FILE *fout;
+    char fname[1024];
+    int fopen_errs = 0;
+    int arg;
+    Principal princs[40];
+    int more; 
+    int prompt = TRUE;
+    register int n, i;
+    
+    bzero(realm, sizeof(realm));
+    
+    /* Parse commandline arguments */
+    if (argc < 2)
+       usage();
+    else {
+       for (i = 1; i < argc; i++) {
+           if (strcmp(argv[i], "-n") == 0)
+               prompt = FALSE;
+           else if (strcmp(argv[i], "-r") == 0) {
+               if (++i >= argc)
+                   usage();
+               else {
+                   strcpy(realm, argv[i]);
+                   /* 
+                    * This is to humor the broken way commandline
+                    * argument parsing is done.  Later, this
+                    * program ignores everything that starts with -.
+                    */
+                   argv[i][0] = '-';
+               }
+           }
+           else if (argv[i][0] == '-')
+               usage();
+           else
+               if (!k_isinst(argv[i])) {
+               fprintf(stderr, "%s: bad instance name: %s\n",
+                       progname, argv[i]);
+               usage();
+           }
+       }
+    }
+
+    if (kdb_get_master_key (prompt, &master_key, master_key_schedule) != 0) {
+      fprintf (stderr, "Couldn't read master key.\n");
+      fflush (stderr);
+      exit(1);
+    }
+
+    if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
+      exit(1);
+    }
+
+    /* For each arg, search for instances of arg, and produce */
+    /* srvtab file */
+    if (!realm[0])
+       if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+           fprintf(stderr, "%s: couldn't get local realm\n", progname);
+           exit(1);
+       }
+    (void) umask(077);
+
+    for (arg = 1; arg < argc; arg++) {
+       if (argv[arg][0] == '-')
+           continue;
+       sprintf(fname, "%s-new-srvtab", argv[arg]);
+       if ((fout = fopen(fname, "w")) == NULL) {
+           fprintf(stderr, "Couldn't create file '%s'.\n", fname);
+           fopen_errs++;
+           continue;
+       }
+       printf("Generating '%s'....\n", fname);
+       n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more);
+       if (more)
+           fprintf(stderr, "More than 40 found...\n");
+       for (i = 0; i < n; i++) {
+           FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout);
+           FWrite(princs[i].instance, strlen(princs[i].instance) + 1,
+                  1, fout);
+           FWrite(realm, strlen(realm) + 1, 1, fout);
+           FWrite((char*)&princs[i].key_version,
+               sizeof(princs[i].key_version), 1, fout);
+           bcopy(&princs[i].key_low, session_key, sizeof(long));
+           bcopy(&princs[i].key_high, session_key + sizeof(long),
+                 sizeof(long));
+           kdb_encrypt_key (&session_key, &session_key, 
+                            &master_key, master_key_schedule, DES_DECRYPT);
+           FWrite((char*)session_key, sizeof session_key, 1, fout);
+       }
+       fclose(fout);
+    }
+
+    StampOutSecrets();
+
+    exit(fopen_errs);          /* 0 errors if successful */
+
+}
diff --git a/kerberosIV/include/Makefile b/kerberosIV/include/Makefile
new file mode 100644 (file)
index 0000000..cf1fe5b
--- /dev/null
@@ -0,0 +1,5 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $
+
+SUBDIR=        kerberosIV ss
+
+.include <bsd.subdir.mk>
diff --git a/kerberosIV/include/adm_locl.h b/kerberosIV/include/adm_locl.h
new file mode 100644 (file)
index 0000000..6a1495c
--- /dev/null
@@ -0,0 +1,54 @@
+/*     $Id: adm_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#ifndef __adm_locl_h
+#define __adm_locl_h
+
+#define TRUE 1
+#define FALSE 0
+
+#include <sys/cdefs.h>
+#include <kerberosIV/site.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <netinet/in.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include "kdc.h"
+
+/* Utils */
+long maketime __P((struct tm *, int));
+
+#endif /*  __adm_locl_h */
diff --git a/kerberosIV/include/kadm_locl.h b/kerberosIV/include/kadm_locl.h
new file mode 100644 (file)
index 0000000..7653d9e
--- /dev/null
@@ -0,0 +1,86 @@
+/*     $Id: kadm_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $      */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <sys/cdefs.h>
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <pwd.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <syslog.h>
+
+#include "kerberosIV/com_err.h"
+#include <ss/ss.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "krb_err.h"
+#include <kerberosIV/krb_db.h>
+#include <kerberosIV/kadm.h>
+#include "kadm_err.h"
+#include "kerberosIV/acl.h"
+
+#include "kadm_server.h"
+
+/* GLOBALS */
+extern char *acldir;
+extern Kadm_Server server_parm;
+
+/* Utils */
+int kadm_change __P((char *, char *, char *, des_cblock));
+int kadm_add_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *));
+int kadm_mod_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *, Kadm_vals *));
+int kadm_get_entry __P((char *, char *, char *, Kadm_vals *, u_char *, Kadm_vals *));
+int kadm_ser_cpw __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_add __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_mod __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_get __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_init __P((int inter, char realm[]));
+int kadm_ser_in __P((u_char **, int *));
+
+long maketime __P((struct tm *, int));
+
+void change_password __P((int argc, char *argv[]));
+void change_admin_password __P((int argc, char *argv[]));
+void add_new_key __P((int argc, char *argv[]));
+void get_entry __P((int argc, char *argv[]));
+void mod_entry __P((int argc, char *argv[]));
+void help __P((int argc, char *argv[]));
+void clean_up __P((void));
+void quit __P((void));
diff --git a/kerberosIV/include/kadm_server.h b/kerberosIV/include/kadm_server.h
new file mode 100644 (file)
index 0000000..e742db5
--- /dev/null
@@ -0,0 +1,57 @@
+/*     $Id: kadm_server.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $    */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_SERVER_DEFS
+#define KADM_SERVER_DEFS
+
+/*
+ * kadm_server.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ *    ps. Yes that means this code belongs to athena etc...
+ *        as part of our ongoing attempt to copyright all greek names
+ */
+
+#include <sys/types.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/des.h>
+
+typedef struct {
+  struct sockaddr_in admin_addr;
+  struct sockaddr_in recv_addr;
+  int recv_addr_len;
+  int admin_fd;                        /* our link to clients */
+  char sname[ANAME_SZ];
+  char sinst[INST_SZ];
+  char krbrlm[REALM_SZ];
+  des_cblock master_key;
+  des_cblock session_key;
+  des_key_schedule master_key_schedule;
+  long master_key_version;
+} Kadm_Server;
+
+#endif /* KADM_SERVER_DEFS */
diff --git a/kerberosIV/include/kdc.h b/kerberosIV/include/kdc.h
new file mode 100644 (file)
index 0000000..e2f625d
--- /dev/null
@@ -0,0 +1,32 @@
+/*     $Id: kdc.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos Key Distribution Center. 
+ */
+
+#ifndef KDC_DEFS
+#define KDC_DEFS
+
+#define S_AD_SZ                sizeof(struct sockaddr_in)
+
+#define max(a,b)       (a>b ? a : b)
+#define min(a,b)       (a<b ? a : b)
+
+#define TRUE           1
+#define FALSE          0
+
+#define KRB_PROG       "./kerberos"
+
+#define ONE_MINUTE     60
+#define FIVE_MINUTES   (5 * ONE_MINUTE)
+#define ONE_HOUR       (60 * ONE_MINUTE)
+#define ONE_DAY                (24 * ONE_HOUR)
+#define THREE_DAYS     (3 * ONE_DAY)
+
+#endif /* KDC_DEFS */
+
diff --git a/kerberosIV/include/kerberosIV/Makefile b/kerberosIV/include/kerberosIV/Makefile
new file mode 100644 (file)
index 0000000..fa160af
--- /dev/null
@@ -0,0 +1,18 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+
+FILES= acl.h com_err.h des.h kadm.h kafs.h kparse.h krb.h krb_db.h site.h
+NOOBJ= noobj
+
+all include clean cleandir depend lint tags:
+
+realinstall:
+       @echo installing ${FILES}
+       @-for i in ${FILES}; do \
+               cmp -s $$i ${DESTDIR}/usr/include/kerberosIV/$$i || \
+                   install -c -m 444 $$i ${DESTDIR}/usr/include/kerberosIV/$$i; \
+       done
+
+beforeinstall:
+       install -d -o ${BINOWN} -g ${BINGRP} -m 755 ${DESTDIR}/usr/include/kerberosIV
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/include/kerberosIV/acl.h b/kerberosIV/include/kerberosIV/acl.h
new file mode 100644 (file)
index 0000000..0a3ce5c
--- /dev/null
@@ -0,0 +1,15 @@
+/*     $Id: acl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $    */
+
+#ifndef __ACL_H
+#define __ACL_H
+
+#include <sys/cdefs.h>
+
+void acl_canonicalize_principal __P((char *principal, char *canon));
+int acl_initialize __P((char *acl_file, int perm));
+int acl_exact_match __P((char *acl, char *principal));
+int acl_check __P((char *acl, char *principal));
+int acl_add __P((char *acl, char *principal));
+int acl_delete __P((char *acl, char *principal));
+
+#endif /* __ACL_H */
diff --git a/kerberosIV/include/kerberosIV/com_err.h b/kerberosIV/include/kerberosIV/com_err.h
new file mode 100644 (file)
index 0000000..0d7fb9a
--- /dev/null
@@ -0,0 +1,27 @@
+/*     $Id: com_err.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $        */
+
+/*-
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+#define __COM_ERR_H
+
+#include <stdarg.h>
+
+/* ANSI C -- use prototypes etc */
+void com_err __P((const char *, long, const char *, ...));
+char const *error_message __P((long));
+void (*com_err_hook) __P((const char *, long, const char *, va_list));
+void (*set_com_err_hook __P((void (*) (const char *, long, const char *, va_list))))
+    __P((const char *, long, const char *, va_list));
+void (*reset_com_err_hook __P((void)))
+    __P((const char *, long, const char *, va_list));
+
+#endif /* ! defined(__COM_ERR_H) */
diff --git a/kerberosIV/include/kerberosIV/des.h b/kerberosIV/include/kerberosIV/des.h
new file mode 100644 (file)
index 0000000..dd8c9ac
--- /dev/null
@@ -0,0 +1,86 @@
+/*     $Id: des.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $    */
+
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#ifndef DES_DEFS
+#define DES_DEFS
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct {
+       union {
+               des_cblock _;
+               /* make sure things are correct size on machines with
+                * 8 byte longs */
+               u_int32_t pad[2];
+       } ks;
+#define _      ks._
+} des_key_schedule[16];
+
+#define DES_KEY_SZ     (sizeof(des_cblock))
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#define DES_CBC_MODE   0
+#define DES_PCBC_MODE  1
+
+#if !defined(NCOMPAT)
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set_key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef struct des_ks_struct bit_64;
+#endif
+
+extern int des_check_key;      /* defaults to false */
+extern int des_rw_mode;                /* defaults to DES_PCBC_MODE */
+
+int des_3ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks1,des_key_schedule ks2,int encrypt));
+int des_3cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule sk1,des_key_schedule sk2,des_cblock *ivec1,des_cblock *ivec2,int encrypt));
+u_int32_t des_cbc_cksum __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec));
+int des_cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt));
+int des_cfb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt));
+int des_ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks,int encrypt));
+int des_encrypt __P((u_int32_t *input,u_int32_t *output,des_key_schedule ks, int encrypt));
+int des_enc_read __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv));
+int des_enc_write __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv));
+int des_ofb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec));
+int des_pcbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt));
+
+void des_set_odd_parity __P((des_cblock *key));
+int des_is_weak_key __P((des_cblock *key));
+int des_set_key __P((des_cblock *key,des_key_schedule schedule));
+int des_key_sched __P((des_cblock *key,des_key_schedule schedule));
+
+int des_string_to_key __P((char *str,des_cblock *key));
+int des_string_to_2keys __P((char *str,des_cblock *key1,des_cblock *key2));
+
+void des_set_random_generator_seed __P((des_cblock *seed));
+int des_new_random_key __P((des_cblock *key));
+void des_init_random_number_generator __P((des_cblock *seed));
+void des_random_key __P((des_cblock ret));
+int des_read_password __P((des_cblock *key,char *prompt,int verify));
+int des_read_2passwords __P((des_cblock *key1,des_cblock *key2,char *prompt,int verify));
+int des_read_pw_string __P((char *buf,int length,char *prompt,int verify));
+
+u_int32_t des_quad_cksum __P((des_cblock *input,des_cblock *output,long length,int out_count,des_cblock *seed));
+
+/* MIT Link and source compatibility */
+void des_fixup_key_parity __P((des_cblock *key));
+#define des_fixup_key_parity des_set_odd_parity
+
+#endif /* DES_DEFS */
diff --git a/kerberosIV/include/kerberosIV/kadm.h b/kerberosIV/include/kerberosIV/kadm.h
new file mode 100644 (file)
index 0000000..a649b0f
--- /dev/null
@@ -0,0 +1,138 @@
+/*     $Id: kadm.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $   */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_DEFS
+#define KADM_DEFS
+
+/*
+ * kadm.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ */
+
+/* The global structures for the client and server */
+typedef struct {
+  struct sockaddr_in admin_addr;
+  struct sockaddr_in my_addr;
+  int my_addr_len;
+  int admin_fd;                        /* file descriptor for link to admin server */
+  char sname[ANAME_SZ];                /* the service name */
+  char sinst[INST_SZ];         /* the services instance */
+  char krbrlm[REALM_SZ];
+} Kadm_Client;
+
+typedef struct {               /* status of the server, i.e the parameters */
+   int inter;                  /* Space for command line flags */
+   char *sysfile;              /* filename of server */
+} admin_params;                        /* Well... it's the admin's parameters */
+
+/* Largest password length to be supported */
+#define MAX_KPW_LEN    128
+
+/* Largest packet the admin server will ever allow itself to return */
+#define KADM_RET_MAX 2048
+
+/* That's right, versions are 8 byte strings */
+#define KADM_VERSTR    "KADM0.0A"
+#define KADM_ULOSE     "KYOULOSE"      /* sent back when server can't
+                                          decrypt client's msg */
+#define KADM_VERSIZE strlen(KADM_VERSTR)
+
+/* the lookups for the server instances */
+#define PWSERV_NAME  "changepw"
+#define KADM_SNAME   "kerberos_master"
+#define KADM_SINST   "kerberos"
+
+/* Attributes fields constants and macros */
+#define ALLOC        2
+#define RESERVED     3
+#define DEALLOC      4
+#define DEACTIVATED  5
+#define ACTIVE       6
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ        4
+
+typedef struct {
+    u_int8_t       fields[FLDSZ];     /* The active fields in this struct */
+    char           name[ANAME_SZ];
+    char           instance[INST_SZ];
+    u_int32_t  key_low;
+    u_int32_t  key_high;
+    u_int32_t  exp_date;
+    u_int16_t attributes;
+    u_int8_t  max_life;
+} Kadm_vals;                    /* The basic values structure in Kadm */
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ        4
+
+/* Need to define fields types here */
+#define KADM_NAME       31
+#define KADM_INST       30
+#define KADM_EXPDATE    29
+#define KADM_ATTR       28
+#define KADM_MAXLIFE    27
+#define KADM_DESKEY     26
+
+/* To set a field entry f in a fields structure d */
+#define SET_FIELD(f,d)  (d[3-(f/8)]|=(1<<(f%8)))
+
+/* To set a field entry f in a fields structure d */
+#define CLEAR_FIELD(f,d)  (d[3-(f/8)]&=(~(1<<(f%8))))
+
+/* Is field f in fields structure d */
+#define IS_FIELD(f,d)   (d[3-(f/8)]&(1<<(f%8)))
+
+/* Various return codes */
+#define KADM_SUCCESS    0
+
+#define WILDCARD_STR "*"
+
+enum acl_types {
+ADDACL,
+GETACL,
+MODACL
+};
+
+/* Various opcodes for the admin server's functions */
+#define CHANGE_PW    2
+#define ADD_ENT      3
+#define MOD_ENT      4
+#define GET_ENT      5
+
+void prin_vals __P((Kadm_vals *));
+int stv_long __P((u_char *, u_int32_t *, int, int));
+
+int stream_to_vals __P((u_char *, Kadm_vals *, int));
+int vals_to_stream __P((Kadm_vals *, u_char **));
+
+int kadm_init_link __P((char *, char *, char *));
+int kadm_change_pw __P((unsigned char *));
+int kadm_mod __P((Kadm_vals *, Kadm_vals *));
+int kadm_get __P((Kadm_vals *, u_char *));
+int kadm_add __P((Kadm_vals *));
+void kadm_vals_to_prin __P((u_char *, Principal *, Kadm_vals *));
+void kadm_prin_to_vals __P((u_char *, Kadm_vals *, Principal *));
+
+#endif /* KADM_DEFS */
diff --git a/kerberosIV/include/kerberosIV/kafs.h b/kerberosIV/include/kerberosIV/kafs.h
new file mode 100644 (file)
index 0000000..1a1bc1a
--- /dev/null
@@ -0,0 +1,47 @@
+/*     $Id: kafs.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $   */
+
+#ifndef __KAFS_H
+#define __KAFS_H
+
+#define AFSCALL_PIOCTL 20
+#define AFSCALL_SETPAG 21
+
+#ifndef _VICEIOCTL
+#if defined(__STDC__) || defined(sgi)
+#define _VICEIOCTL(id)  ((unsigned int ) _IOW('V', id, struct ViceIoctl))
+#else
+#define _VICEIOCTL(id)  ((unsigned int ) _IOW(V, id, struct ViceIoctl))
+#endif
+#endif /* _VICEIOCTL */
+
+#define VIOCSETTOK _VICEIOCTL(3)
+#define VIOCUNLOG  _VICEIOCTL(9)
+
+struct ViceIoctl {
+  caddr_t in, out;
+  short in_size;
+  short out_size;
+};
+
+struct ClearToken {
+  int32_t AuthHandle;
+  char HandShakeKey[8];
+  int32_t ViceId;
+  int32_t BeginTimestamp;
+  int32_t EndTimestamp;
+};
+
+/* Use k_hasafs() to probe if the machine supports AFS syscalls.
+   The other functions will generate a SIGSYS if AFS is not supported */
+
+int k_hasafs __P((void));
+
+int k_afsklog __P((char *realm));
+int k_pioctl __P((char *a_path,
+                 int o_opcode,
+                 struct ViceIoctl *a_paramsP,
+                 int a_followSymlinks));
+int k_unlog __P((void));
+int k_setpag __P((void));
+
+#endif /* __KAFS_H */
diff --git a/kerberosIV/include/kerberosIV/kparse.h b/kerberosIV/include/kerberosIV/kparse.h
new file mode 100644 (file)
index 0000000..ae72c84
--- /dev/null
@@ -0,0 +1,109 @@
+/*     $Id: kparse.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $ */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Include file for kparse routines.
+ */
+
+#ifndef KPARSE_DEFS
+#define KPARSE_DEFS
+
+/*
+ * values returned by fGetParameterSet() 
+ */
+
+#define PS_BAD_KEYWORD   -2    /* unknown or duplicate keyword */
+#define PS_SYNTAX        -1    /* syntax error */
+#define PS_OKAY                   0    /* got a complete parameter set */
+#define PS_EOF            1    /* nothing more in the file */
+
+/*
+ * values returned by fGetKeywordValue() 
+ */
+
+#define KV_SYNTAX       -2     /* syntax error */
+#define KV_EOF          -1     /* nothing more in the file */
+#define KV_OKAY                  0     /* got a keyword/value pair */
+#define KV_EOL           1     /* nothing more on this line */
+
+/*
+ * values returned by fGetToken() 
+ */
+
+#define GTOK_BAD_QSTRING -1    /* newline found in quoted string */
+#define GTOK_EOF         0     /* end of file encountered */
+#define GTOK_QSTRING     1     /* quoted string */
+#define GTOK_STRING      2     /* unquoted string */
+#define GTOK_NUMBER      3     /* one or more digits */
+#define GTOK_PUNK        4     /* punks are punctuation, newline,
+                                * etc. */
+#define GTOK_WHITE       5     /* one or more whitespace chars */
+
+/*
+ * extended character classification macros 
+ */
+
+#define ISOCTAL(CH)    ( (CH>='0')  && (CH<='7') )
+#define ISQUOTE(CH)    ( (CH=='\"') || (CH=='\'') || (CH=='`') )
+#define ISWHITESPACE(C) ( (C==' ')   || (C=='\t') )
+#define ISLINEFEED(C)  ( (C=='\n')  || (C=='\r')  || (C=='\f') )
+
+/*
+ * tokens consist of any printable charcacter except comma, equal, or
+ * whitespace 
+ */
+
+#define ISTOKENCHAR(C) ((C>040) && (C<0177) && (C != ',') && (C != '='))
+
+/*
+ * the parameter table defines the keywords that will be recognized by
+ * fGetParameterSet, and their default values if not specified. 
+ */
+
+typedef struct {
+    char *keyword;
+    char *defvalue;
+    char *value;
+}       parmtable;
+
+#define PARMCOUNT(P) (sizeof(P)/sizeof(P[0]))
+
+extern int LineNbr;            /* current line # in parameter file */
+
+extern char ErrorMsg[];                /*
+                                * meaningful only when KV_SYNTAX,
+                                * PS_SYNTAX,  or PS_BAD_KEYWORD is
+                                * returned by fGetKeywordValue or
+                                * fGetParameterSet
+                                */
+
+#include <stdio.h>
+
+int fGetParameterSet __P((FILE *fp, parmtable *parm, int parmcount));
+int ParmCompare __P((parmtable *parm, int parmcount, char *keyword, char *value));
+void FreeParameterSet __P((parmtable *parm, int parmcount));
+int fGetKeywordValue __P((FILE *fp, char *keyword, int klen, char *value, int vlen));
+int fGetToken __P((FILE *fp, char *dest, int maxlen));
+int fGetLiteral __P((FILE *fp));
+int fUngetChar __P((int ch, FILE *fp));
+int fGetChar __P((FILE *fp));
+char * strsave __P((char *p));
+char * strutol __P((char *start));
+
+#endif /* KPARSE_DEFS */
diff --git a/kerberosIV/include/kerberosIV/krb.h b/kerberosIV/include/kerberosIV/krb.h
new file mode 100644 (file)
index 0000000..dc8c043
--- /dev/null
@@ -0,0 +1,432 @@
+/*     $Id: krb.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Include file for the Kerberos library. 
+ */
+
+/* Only one time, please */
+#ifndef        KRB_DEFS
+#define KRB_DEFS
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* Include site.h file to define paths */
+#include <kerberosIV/site.h>
+
+/* Need some defs from des.h    */
+#include <kerberosIV/des.h>
+
+/* Global library variables. */
+extern int krbONE;
+#define         HOST_BYTE_ORDER (* (char *) &krbONE)
+extern int private_msg_ver; /* in rd_priv.c */
+extern int req_act_vno; /* this is defined in the kerberos server code */
+
+
+/* Text describing error codes */
+#define                MAX_KRB_ERRORS  256
+extern const char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* General definitions */
+#define                KSUCCESS        0
+#define                KFAILURE        255
+
+/*
+ * Kerberos specific definitions 
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database.  The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server.  Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm. 
+ */
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define        ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+/* include space for '.' and '@' */
+#define                MAX_K_NAME_SZ   (ANAME_SZ + INST_SZ + REALM_SZ + 2)
+#define                KKEY_SZ         100
+#define                VERSION_SZ      1
+#define                MSG_TYPE_SZ     1
+#define                DATE_SZ         26      /* RTI date output */
+
+#define                MAX_HSTNM       100
+
+#ifndef DEFAULT_TKT_LIFE       /* allow compile-time override */
+/* default lifetime for krb_mk_req & co., 10 hrs */
+#define        DEFAULT_TKT_LIFE 120
+#endif
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+    int     length;            /* Length of the text */
+    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */
+    u_int32_t mbz;             /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define        CLIENT_KRB_TIMEOUT      4       /* time between retries */
+#define CLIENT_KRB_RETRY       5       /* retry this many times */
+#define        CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define        R_TKT_FIL       0
+#define        W_TKT_FIL       1
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define        CLOCK_SKEW      5*60
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+    unsigned char k_flags;     /* Flags from ticket */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* His Instance */
+    char    prealm[REALM_SZ];  /* His Realm */
+    u_int32_t checksum;                /* Data checksum (opt) */
+    des_cblock session;                /* Session Key */
+    int     life;              /* Life of ticket */
+    u_int32_t time_sec;                /* Time ticket issued */
+    u_int32_t address;         /* Address in ticket */
+    KTEXT_ST reply;            /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+    char    service[ANAME_SZ]; /* Service name */
+    char    instance[INST_SZ]; /* Instance */
+    char    realm[REALM_SZ];   /* Auth domain */
+    des_cblock session;                /* Session key */
+    int     lifetime;          /* Lifetime */
+    int     kvno;              /* Key version number */
+    KTEXT_ST ticket_st;                /* The ticket itself */
+    int32_t    issue_date;     /* The issue time */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+    unsigned char *app_data;   /* pointer to appl data */
+    u_int32_t app_length;      /* length of appl data */
+    u_int32_t hash;            /* hash to lookup replay */
+    int     swap;              /* swap bytes? */
+    int32_t    time_sec;               /* msg timestamp seconds */
+    unsigned char time_5ms;    /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+
+/* Location of ticket file for save_cred and get_cred */
+#define TKT_FILE        tkt_string()
+#define TKT_ROOT        "/tmp/tkt"
+
+/* Error codes returned from the KDC */
+#define                KDC_OK          0       /* Request OK */
+#define                KDC_NAME_EXP    1       /* Principal expired */
+#define                KDC_SERVICE_EXP 2       /* Service expired */
+#define                KDC_AUTH_EXP    3       /* Auth expired */
+#define                KDC_PKT_VER     4       /* Protocol version unknown */
+#define                KDC_P_MKEY_VER  5       /* Wrong master key version */
+#define                KDC_S_MKEY_VER  6       /* Wrong master key version */
+#define                KDC_BYTE_ORDER  7       /* Byte order unknown */
+#define                KDC_PR_UNKNOWN  8       /* Principal unknown */
+#define                KDC_PR_N_UNIQUE 9       /* Principal not unique */
+#define                KDC_NULL_KEY   10       /* Principal has null key */
+#define                KDC_GEN_ERR    20       /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define                GC_OK           0       /* Retrieve OK */
+#define                RET_OK          0       /* Retrieve OK */
+#define                GC_TKFIL       21       /* Can't read ticket file */
+#define                RET_TKFIL      21       /* Can't read ticket file */
+#define                GC_NOTKT       22       /* Can't find ticket or TGT */
+#define                RET_NOTKT      22       /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req         */
+#define                MK_AP_OK        0       /* Success */
+#define                MK_AP_TGTEXP   26       /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define                RD_AP_OK        0       /* Request authentic */
+#define                RD_AP_UNDEC    31       /* Can't decode authenticator */
+#define                RD_AP_EXP      32       /* Ticket expired */
+#define                RD_AP_NYV      33       /* Ticket not yet valid */
+#define                RD_AP_REPEAT   34       /* Repeated request */
+#define                RD_AP_NOT_US   35       /* The ticket isn't for us */
+#define                RD_AP_INCON    36       /* Request is inconsistent */
+#define                RD_AP_TIME     37       /* delta_t too big */
+#define                RD_AP_BADD     38       /* Incorrect net address */
+#define                RD_AP_VERSION  39       /* protocol version mismatch */
+#define                RD_AP_MSG_TYPE 40       /* invalid msg type */
+#define                RD_AP_MODIFIED 41       /* message stream modified */
+#define                RD_AP_ORDER    42       /* message out of order */
+#define                RD_AP_UNAUTHOR 43       /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define                GT_PW_OK        0       /* Got password changing tkt */
+#define                GT_PW_NULL     51       /* Current PW is null */
+#define                GT_PW_BADPW    52       /* Incorrect current password */
+#define                GT_PW_PROT     53       /* Protocol Error */
+#define                GT_PW_KDCERR   54       /* Error returned by KDC */
+#define                GT_PW_NULLTKT  55       /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define                SKDC_OK         0       /* Response received */
+#define                SKDC_RETRY     56       /* Retry count exceeded */
+#define                SKDC_CANT      57       /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define                INTK_OK         0       /* Ticket obtained */
+#define                INTK_W_NOTALL  61       /* Not ALL tickets returned */
+#define                INTK_BADPW     62       /* Incorrect password */
+#define                INTK_PROT      63       /* Protocol Error */
+#define                INTK_ERR       70       /* Other error */
+
+/* Values returned by get_adtkt */
+#define         AD_OK           0      /* Ticket Obtained */
+#define         AD_NOTGT       71      /* Don't have tgt */
+
+/* Error codes returned by ticket file utilities */
+#define                NO_TKT_FIL      76      /* No ticket file found */
+#define                TKT_FIL_ACC     77      /* Couldn't access tkt file */
+#define                TKT_FIL_LCK     78      /* Couldn't lock ticket file */
+#define                TKT_FIL_FMT     79      /* Bad ticket file format */
+#define                TKT_FIL_INI     80      /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define                KNAME_FMT       81      /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define                SAFE_PRIV_ERROR -1      /* syscall error */
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad  0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_int32_t  0-->3, 1-->2, 2-->1, 3-->0
+ * u_int16_t 0-->1, 1-->0
+ */
+
+#define     swap_u_16(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(((char *) x) +0, ((char *)  _krb_swap_tmp) +14 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +12 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +8  ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +12,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +14,((char *)  _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,16);\
+                            }
+
+#define     swap_u_12(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) x,     ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,12);\
+                            }
+
+#define     swap_C_Block(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,8);\
+                            }
+#define     swap_u_quad(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) &x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) &x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)&x,8);\
+                            }
+
+#define     swap_u_long(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab((char *)  &x,    ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp),2); \
+ x = _krb_swap_tmp[0];   \
+                           }
+
+#define     swap_u_short(x) {\
+ u_int16_t     _krb_swap_sh_tmp; \
+ swab((char *)  &x,    ( &_krb_swap_sh_tmp) ,2); \
+ x = (u_int16_t) _krb_swap_sh_tmp; \
+                            }
+/* Kerberos ticket flag field bit definitions */
+#define K_FLAG_ORDER    0       /* bit 0 --> lsb */
+#define K_FLAG_1                /* reserved */
+#define K_FLAG_2                /* reserved */
+#define K_FLAG_3                /* reserved */
+#define K_FLAG_4                /* reserved */
+#define K_FLAG_5                /* reserved */
+#define K_FLAG_6                /* reserved */
+#define K_FLAG_7                /* reserved, bit 7 --> msb */
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define        KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define        KOPT_DO_MUTUAL   0x00000002 /* do mutual auth */
+
+#define        KOPT_DONT_CANON  0x00000004 /*
+                                    * don't canonicalize inst as
+                                    * a hostname
+                                    */
+
+#define        KRB_SENDAUTH_VLEN 8         /* length for version strings */
+
+#ifdef ATHENA_COMPAT
+#define        KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */
+#endif /* ATHENA_COMPAT */
+
+struct tm;
+struct tm *k_localtime __P((u_int32_t *));
+
+/* --- Random prototypes */
+#include <sys/types.h> /* to get u_char */
+
+/* Host address comparison */
+int krb_equiv __P((u_int32_t, u_int32_t));
+
+/* Password conversion */
+void mit_string_to_key __P((char *str, char *cell, des_cblock *key));
+void afs_string_to_key __P((char *str, char *cell, des_cblock *key));
+
+/* Lifetime conversion */
+u_int32_t krb_life_to_time __P((u_int32_t start, int life));
+int krb_time_to_life __P((u_int32_t start, u_int32_t end));
+char *krb_life_to_atime __P((int life));
+int krb_atime_to_life __P((char *atime));
+
+/* Ticket manipulation */
+int tf_get_cred __P((CREDENTIALS *));
+int tf_get_pinst __P((char *));
+int tf_get_pname __P((char *));
+int tf_init __P((char *, int));
+int tf_save_cred __P((char *, char *, char *, unsigned char *, int , int , KTEXT ticket, u_int32_t));
+void tf_close __P((void));
+
+/* Private communication */
+struct sockaddr_in;
+int32_t krb_mk_priv __P((u_char *, u_char *, u_int32_t , struct des_ks_struct *, des_cblock *, struct sockaddr_in *, struct sockaddr_in *));
+int32_t krb_rd_priv __P((u_char *, u_int32_t, struct des_ks_struct *, des_cblock *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
+
+/* Misc */
+KTEXT create_auth_reply __P((char *, char *, char *, int32_t, int, u_int32_t, int, KTEXT));
+
+char *krb_get_phost __P((char *));
+char *krb_realmofhost __P((char *));
+char *tkt_string __P((void));
+
+int create_ciph __P((KTEXT, unsigned char *, char *, char *, char *, u_int32_t, int, KTEXT, u_int32_t, des_cblock *));
+int decomp_ticket __P((KTEXT, unsigned char *, char *, char *, char *, u_int32_t *, unsigned char *, int *, u_int32_t *, char *, char *, des_cblock *, struct des_ks_struct *));
+int dest_tkt __P((void));
+int get_ad_tkt __P((char *, char *, char *, int));
+int get_pw_tkt __P((char *, char *, char *, char *));
+int get_request __P((KTEXT, int, char **, char **));
+int get_request __P((KTEXT, int, char **, char **));
+int in_tkt __P((char *, char *));
+int k_isinst __P((char *));
+int k_isname __P((char *));
+int k_isrealm __P((char *));
+int kname_parse __P((char *, char *, char *, char *));
+int krb_create_ticket __P((KTEXT, unsigned char, char *, char *, char *, int32_t, char *, int16_t, int32_t, char *, char *, des_cblock *));
+int krb_get_admhst __P((char *, char *, int));
+int krb_get_admhst __P((char *, char *, int));
+int krb_get_cred __P((char *, char *, char *, CREDENTIALS *));
+int krb_get_in_tkt __P((char *, char *, char *, char *, char *, int , int (*key_proc) (/* ??? */), int (*decrypt_proc) (/* ??? */), char *));
+int krb_get_krbhst __P((char *, char *, int));
+int krb_get_krbhst __P((char *, char *, int));
+int krb_get_krbhst __P((char *, char *, int));
+int krb_get_lrealm __P((char *, int));
+int krb_get_pw_in_tkt __P((char *, char *, char *, char *, char *, int, char *));
+int krb_get_svc_in_tkt __P((char *, char *, char *, char *, char *, int, char *));
+int krb_get_tf_fullname __P((char *, char *, char *, char *));
+int krb_get_tf_realm __P((char *, char *));
+int krb_kntoln __P((AUTH_DAT *, char *));
+int krb_mk_req __P((KTEXT , char *, char *, char *, int32_t));
+int krb_net_read __P((int , char *, int));
+int krb_net_write __P((int , char *, int));
+int krb_rd_err __P((u_char *, u_int32_t, int32_t *, MSG_DAT *));
+int krb_rd_req __P((KTEXT , char *, char *, int32_t, AUTH_DAT *, char *));
+int krb_recvauth __P((int32_t, int, KTEXT, char *, char *, struct sockaddr_in *, struct sockaddr_in *, AUTH_DAT *, char *, struct des_ks_struct *, char *));
+int krb_sendauth __P((int32_t, int, KTEXT, char *, char *, char *, u_int32_t, MSG_DAT *, CREDENTIALS *, struct des_ks_struct *, struct sockaddr_in *, struct sockaddr_in *, char *));
+int krb_set_key __P((char *, int));
+int krb_set_lifetime __P((int));
+int kuserok __P((AUTH_DAT *, char *));
+int read_service_key __P((char *, char *, char *, int , char *, char *));
+int save_credentials __P((char *, char *, char *, unsigned char *, int , int , KTEXT , int32_t));
+int send_to_kdc __P((KTEXT , KTEXT , char *));
+
+int32_t krb_mk_err __P((u_char *, int32_t, char *));
+int32_t krb_mk_safe __P((u_char *, u_char *, u_int32_t, des_cblock *, struct sockaddr_in *, struct sockaddr_in *));
+int32_t krb_rd_safe __P((u_char *, u_int32_t, des_cblock *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
+
+void ad_print __P((AUTH_DAT *));
+void cr_err_reply __P((KTEXT, char *, char *, char *, u_int32_t, u_int32_t, char *));
+void extract_ticket __P((KTEXT, int, char *, int *, int *, char *, KTEXT));
+void krb_set_tkt_string __P((char *));
+
+void kset_logfile __P((char *));
+void set_logfile __P((char *));
+
+void log ();
+char *klog ();
+
+int getst __P((int, char *, int));
+
+
+#endif /* KRB_DEFS */
diff --git a/kerberosIV/include/kerberosIV/krb_db.h b/kerberosIV/include/kerberosIV/krb_db.h
new file mode 100644 (file)
index 0000000..a463e99
--- /dev/null
@@ -0,0 +1,127 @@
+/*     $Id: krb_db.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $ */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/* spm         Project Athena  8/85 
+ *
+ * This file defines data structures for the kerberos
+ * authentication/authorization database. 
+ *
+ * They MUST correspond to those defined in *.rel 
+ */
+
+#ifndef KRB_DB_DEFS
+#define KRB_DB_DEFS
+
+#define KERB_M_NAME            "K"     /* Kerberos */
+#define KERB_M_INST            "M"     /* Master */
+#define KERB_DEFAULT_NAME      "default"
+#define KERB_DEFAULT_INST      ""
+
+/* this also defines the number of queue headers */
+#define KERB_DB_HASH_MODULO 64
+
+
+/* Arguments to kerb_dbl_lock() */
+
+#define KERB_DBL_EXCLUSIVE 1
+#define KERB_DBL_SHARED 0
+
+/* arguments to kerb_db_set_lockmode() */
+
+#define KERB_DBL_BLOCKING 0
+#define KERB_DBL_NONBLOCKING 1
+
+/* Principal defines the structure of a principal's name */
+
+typedef struct {
+    char    name[ANAME_SZ];
+    char    instance[INST_SZ];
+
+    u_int32_t key_low;
+    u_int32_t key_high;
+    u_int32_t exp_date;
+    char    exp_date_txt[DATE_SZ];
+    u_int32_t mod_date;
+    char    mod_date_txt[DATE_SZ];
+    u_int16_t attributes;
+    u_int8_t max_life;
+    u_int8_t kdc_key_ver;
+    u_int8_t key_version;
+
+    char    mod_name[ANAME_SZ];
+    char    mod_instance[INST_SZ];
+    char   *old;               /* cast to (Principal *); not in db,
+                                * ptr to old vals */
+}
+        Principal;
+
+typedef struct {
+    int32_t    cpu;
+    int32_t    elapsed;
+    int32_t    dio;
+    int32_t    pfault;
+    int32_t    t_stamp;
+    int32_t    n_retrieve;
+    int32_t    n_replace;
+    int32_t    n_append;
+    int32_t    n_get_stat;
+    int32_t    n_put_stat;
+}
+        DB_stat;
+
+/* Dba defines the structure of a database administrator */
+
+typedef struct {
+    char    name[ANAME_SZ];
+    char    instance[INST_SZ];
+    u_int16_t attributes;
+    u_int32_t exp_date;
+    char    exp_date_txt[DATE_SZ];
+    char   *old;       /*
+                        * cast to (Dba *); not in db, ptr to
+                        * old vals
+                        */
+}
+        Dba;
+
+int kerb_get_principal __P((char *, char *, Principal *, unsigned int, int *));
+int kerb_put_principal __P((Principal *, unsigned int));
+void kerb_db_get_stat __P((DB_stat *));
+void kerb_db_put_stat __P((DB_stat *));
+int kerb_get_dba __P((char *, char *, Dba *, unsigned int, int *));
+int kerb_db_get_dba __P(());
+int kerb_init __P((void));
+void kerb_fini __P((void));
+time_t kerb_get_db_age __P((void));
+
+void kdb_encrypt_key __P((des_cblock *, des_cblock *, des_cblock *, des_key_schedule, int));
+int kerb_db_set_name __P((char *));
+
+long kdb_get_master_key __P((int, des_cblock *, des_key_schedule));
+
+#include <stdio.h>
+long kdb_verify_master_key __P((des_cblock *, des_key_schedule, FILE *));
+
+int kerb_db_create __P((char *db_name));
+int kerb_db_put_principal __P((Principal *, unsigned int));
+int kerb_db_iterate __P((int (*)(char *, Principal *), char *));
+int kerb_db_rename __P((char *, char *));
+int kerb_db_set_lockmode __P((int));
+
+#endif /* KRB_DB_DEFS */
diff --git a/kerberosIV/include/kerberosIV/site.h b/kerberosIV/include/kerberosIV/site.h
new file mode 100644 (file)
index 0000000..d3191ed
--- /dev/null
@@ -0,0 +1,46 @@
+/*     $Id: site.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $   */
+
+/* 
+ * Site-specific definitions.
+ */
+
+#ifndef SITE_H
+#define SITE_H
+
+/*
+ * Location of common files.
+ */
+#define        KRB_CONF        "/etc/kerberosIV/krb.conf"
+#define        KRB_RLM_TRANS   "/etc/kerberosIV/krb.realms"
+#define        KRB_EQUIV       "/etc/kerberosIV/krb.equiv"
+#define KRB_ACL                "/etc/kerberosIV/kerberos.acl"
+#define MKEYFILE       "/etc/kerberosIV/master_key"
+#define KEYFILE                "/etc/kerberosIV/srvtab"
+#define        DBM_FILE        "/etc/kerberosIV/principal"
+
+#define K_LOGFIL       "/var/log/kpropd.log"
+#define KS_LOGFIL      "/var/log/kerberos_slave.log"
+#define KRBLOG                 "/var/log/kerberos.log"  /* master server  */
+#define KRBSLAVELOG    "/var/log/kerberos_slave.log" /* master (?) server  */
+
+#define        KRB_MASTER      "kerberos"
+#define        KRB_HOST        "kowande.bu.oz.au" 
+#define        KRB_REALM       "KOWANDE.BU.OZ.AU"
+
+/* from: kadm_server.h  */
+/* the default syslog file */
+#define KADM_SYSLOG    "/var/log/admin_server.log"
+
+#define DEFAULT_ACL_DIR        "/etc/kerberosIV/"
+/* These get appended to DEFAULT_ACL_DIR */
+#define        ADD_ACL_FILE            "admin_acl.add"
+#define        GET_ACL_FILE            "admin_acl.get"
+#define        MOD_ACL_FILE            "admin_acl.mod"
+
+/*
+ * Set ORGANIZATION to be the desired organization string printed
+ * by the 'kinit' program.  It may have spaces.
+ */
+#define ORGANIZATION   "The OpenBSD Project"
+
+#endif
diff --git a/kerberosIV/include/klog.h b/kerberosIV/include/klog.h
new file mode 100644 (file)
index 0000000..e8747f1
--- /dev/null
@@ -0,0 +1,37 @@
+/*     $Id: klog.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $   */
+
+/*-
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This file defines the types of log messages logged by klog.  Each
+ * type of message may be selectively turned on or off. 
+ */
+
+#ifndef KLOG_DEFS
+#define KLOG_DEFS
+
+#define        NLOGTYPE        100     /* Maximum number of log msg types  */
+
+#define L_NET_ERR        1     /* Error in network code            */
+#define L_NET_INFO       2     /* Info on network activity         */
+#define L_KRB_PERR       3     /* Kerberos protocol errors         */
+#define L_KRB_PINFO      4     /* Kerberos protocol info           */
+#define L_INI_REQ        5     /* Request for initial ticket       */
+#define L_NTGT_INTK       6    /* Initial request not for TGT      */
+#define L_DEATH_REQ       7    /* Request for server death         */
+#define L_TKT_REQ        8     /* All ticket requests using a tgt  */
+#define L_ERR_SEXP       9     /* Service expired                  */
+#define L_ERR_MKV       10     /* Master key version incorrect     */
+#define L_ERR_NKY       11     /* User's key is null               */
+#define L_ERR_NUN       12     /* Principal not unique             */
+#define L_ERR_UNK       13     /* Principal Unknown                */
+#define L_ALL_REQ       14     /* All requests                     */
+#define L_APPL_REQ      15     /* Application requests (using tgt) */
+#define L_KRB_PWARN      16    /* Protocol warning messages        */
+
+char   *klog();
+
+#endif /* KLOG_DEFS */
diff --git a/kerberosIV/include/kprop.h b/kerberosIV/include/kprop.h
new file mode 100644 (file)
index 0000000..ab480c6
--- /dev/null
@@ -0,0 +1,18 @@
+/*     $Id: kprop.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $  */
+
+/*-
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ */
+
+#define KPROP_SERVICE_NAME "rcmd"
+#define KPROP_SRVTAB "/etc/srvtab"
+#define TGT_SERVICE_NAME "krbtgt"
+#define KPROP_PROT_VERSION_LEN 8
+#define KPROP_PROT_VERSION "kprop01"
+#define KPROP_TRANSFER_PRIVATE 1
+#define KPROP_TRANSFER_SAFE 2
+#define KPROP_TRANSFER_CLEAR 3
+#define KPROP_BUFSIZ 32768
diff --git a/kerberosIV/include/kuser_locl.h b/kerberosIV/include/kuser_locl.h
new file mode 100644 (file)
index 0000000..f52b306
--- /dev/null
@@ -0,0 +1,19 @@
+/*     $Id: kuser_locl.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $     */
+
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/file.h>
+
+#include <pwd.h>
+
+#include <kerberosIV/krb.h>
+#include <prot.h>
diff --git a/kerberosIV/include/prot.h b/kerberosIV/include/prot.h
new file mode 100644 (file)
index 0000000..da9f106
--- /dev/null
@@ -0,0 +1,89 @@
+/*     $Id: prot.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $   */
+
+/*-
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file with authentication protocol information.
+ */
+
+#ifndef PROT_DEFS
+#define PROT_DEFS
+
+#define                KRB_PORT                750     /* PC's don't have
+                                                * /etc/services */
+#define                KRB_PROT_VERSION        4
+#define        MAX_PKT_LEN             1000
+#define                MAX_TXT_LEN             1000
+#define                TICKET_GRANTING_TICKET  "krbtgt"
+
+/* Macro's to obtain various fields from a packet */
+
+#define pkt_version(packet)  (unsigned int) *(packet->dat)
+#define pkt_msg_type(packet) (unsigned int) *(packet->dat+1)
+#define pkt_a_name(packet)   (packet->dat+2)
+#define pkt_a_inst(packet)   \
+       (packet->dat+3+strlen((char *)pkt_a_name(packet)))
+#define pkt_a_realm(packet)  \
+       (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet)))
+
+/* Macro to obtain realm from application request */
+#define apreq_realm(auth)     (auth->dat + 3)
+
+#define pkt_time_ws(packet) (char *) \
+        (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+#define pkt_no_req(packet) (unsigned short) \
+        *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+         strlen((char *)pkt_a_inst(packet)) + \
+         strlen((char *)pkt_a_realm(packet)))
+#define pkt_x_date(packet) (char *) \
+        (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+#define pkt_err_code(packet) ( (char *) \
+        (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet))))
+#define pkt_err_text(packet) \
+        (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+/* Routines to create and read packets may be found in prot.c */
+
+KTEXT create_auth_reply();
+KTEXT create_death_packet();
+
+/* Message types , always leave lsb for byte order */
+
+#define                AUTH_MSG_KDC_REQUEST                     1<<1
+#define        AUTH_MSG_KDC_REPLY                       2<<1
+#define                AUTH_MSG_APPL_REQUEST                    3<<1
+#define                AUTH_MSG_APPL_REQUEST_MUTUAL             4<<1
+#define                AUTH_MSG_ERR_REPLY                       5<<1
+#define                AUTH_MSG_PRIVATE                         6<<1
+#define                AUTH_MSG_SAFE                            7<<1
+#define                AUTH_MSG_APPL_ERR                        8<<1
+#define        AUTH_MSG_DIE                            63<<1
+
+/* values for kerb error codes */
+
+#define                KERB_ERR_OK                              0
+#define                KERB_ERR_NAME_EXP                        1
+#define                KERB_ERR_SERVICE_EXP                     2
+#define                KERB_ERR_AUTH_EXP                        3
+#define                KERB_ERR_PKT_VER                         4
+#define                KERB_ERR_NAME_MAST_KEY_VER               5
+#define                KERB_ERR_SERV_MAST_KEY_VER               6
+#define                KERB_ERR_BYTE_ORDER                      7
+#define                KERB_ERR_PRINCIPAL_UNKNOWN               8
+#define                KERB_ERR_PRINCIPAL_NOT_UNIQUE            9
+#define                KERB_ERR_NULL_KEY                       10
+
+#endif /* PROT_DEFS */
diff --git a/kerberosIV/include/slav_locl.h b/kerberosIV/include/slav_locl.h
new file mode 100644 (file)
index 0000000..36b6a3f
--- /dev/null
@@ -0,0 +1,34 @@
+/*     $Id: slav_locl.h,v 1.1.1.1 1995/12/14 06:52:34 tholo Exp $      */
+
+#ifndef __slav_locl_h
+#define __slav_locl_h
+
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/file.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include "klog.h"
+#include "prot.h"
+#include "kdc.h"
+
+#endif /*  __slav_locl_h */
diff --git a/kerberosIV/include/ss/Makefile b/kerberosIV/include/ss/Makefile
new file mode 100644 (file)
index 0000000..85986e8
--- /dev/null
@@ -0,0 +1,18 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+
+FILES= ss.h
+NOOBJ= noobj
+
+all include clean cleandir depend lint tags:
+
+realinstall:
+       @echo installing ${FILES}
+       @-for i in ${FILES}; do \
+               cmp -s $$i ${DESTDIR}/usr/include/ss/$$i || \
+                   install -c -m 444 $$i ${DESTDIR}/usr/include/ss/$$i; \
+       done
+
+beforeinstall:
+       install -d -o ${BINOWN} -g ${BINGRP} -m 755 ${DESTDIR}/usr/include/ss
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/include/ss/ss.h b/kerberosIV/include/ss/ss.h
new file mode 100644 (file)
index 0000000..f387fd4
--- /dev/null
@@ -0,0 +1,65 @@
+/*     $Id: ss.h,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $     */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#ifndef _SS_H
+#define _SS_H
+
+#include <sys/cdefs.h>
+
+#ifndef NO_SS_ERR_H
+#include <ss/ss_err.h>
+#endif
+
+typedef const struct _ss_request_entry {
+    const char * const *command_names; /* whatever */
+    void (* const function) __P((int, const char * const *, int, void *));
+    const char * const info_string;    /* NULL */
+    int flags;                 /* 0 */
+} ss_request_entry;
+
+typedef const struct _ss_request_table {
+    int version;
+    ss_request_entry *requests;
+} ss_request_table;
+
+#define SS_RQT_TBL_V2  2
+
+typedef struct _ss_rp_options {        /* DEFAULT VALUES */
+    int version;               /* SS_RP_V1 */
+    void (*unknown) __P((int, const char * const *, int, void *));     /* call for unknown command */
+    int allow_suspend;
+    int catch_int;
+} ss_rp_options;
+
+#define SS_RP_V1 1
+
+#define SS_OPT_DONT_LIST       0x0001
+#define SS_OPT_DONT_SUMMARIZE  0x0002
+
+void ss_help __P((int, const char * const *, int, void *));
+char *ss_current_request();
+char *ss_name();
+void ss_error __P((int, long, char const *, ...));
+void ss_perror __P((int, long, char const *));
+int ss_create_invocation __P((char *, char *, char *, ss_request_table *, int *));
+int ss_listen(int);
+void ss_abort_subsystem();
+
+extern ss_request_table ss_std_requests;
+#endif /* _SS_H */
diff --git a/kerberosIV/kadm/Makefile b/kerberosIV/kadm/Makefile
new file mode 100644 (file)
index 0000000..63aa3c3
--- /dev/null
@@ -0,0 +1,23 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $
+
+LIB=   kadm
+SRCS=  kadm_err.c kadm_cli_wrap.c kadm_stream.c kadm_supp.c
+CFLAGS+=-I. -I${.CURDIR}
+.if exists(${.CURDIR}/../krb/obj)
+CFLAGS+=-I${.CURDIR}/../krb/obj
+.else
+CFLAGS+=-I${.CURDIR}/../krb
+.endif
+LDADD+=        ${COM_ERR}
+CLEANFILES+=   kadm_err.c kadm_err.h
+
+kadm_err.c kadm_err.h: kadm_err.et
+       test -e kadm_err.et || ln -s ${.CURDIR}/kadm_err.et .
+       ${COMPILE_ET} kadm_err.et
+       -test -h kadm_err.et && rm kadm_err.et
+
+beforeinstall:
+       -cd ${.OBJDIR}; cmp -s kadm_err.h ${DESTDIR}/usr/include/kerberosIV/kadm_err.h || \
+           install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm_err.h ${DESTDIR}/usr/include/kerberosIV
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/kadm/kadm_cli_wrap.c b/kerberosIV/kadm/kadm_cli_wrap.c
new file mode 100644 (file)
index 0000000..bdba1a6
--- /dev/null
@@ -0,0 +1,509 @@
+/*     $Id: kadm_cli_wrap.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $  */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * Kerberos administration server client-side routines
+ */
+
+/*
+ * kadm_cli_wrap.c the client side wrapping of the calls to the admin server 
+ */
+
+#include "kadm_local.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static Kadm_Client client_parm;
+
+/* Macros for use in returning data... used in kadm_cli_send */
+#define RET_N_FREE(r) {clear_secrets(); free((char *)act_st); free((char *)priv_pak); return r;}
+
+/* Keys for use in the transactions */
+static des_cblock sess_key;           /* to be filled in by kadm_cli_keyd */
+static des_key_schedule sess_sched;
+
+static void
+clear_secrets()
+{
+       bzero((char *)sess_key, sizeof(sess_key));
+       bzero((char *)sess_sched, sizeof(sess_sched));
+       return;
+}
+
+static void (*opipe)();
+
+static void
+kadm_cli_disconn()
+{
+    (void) close(client_parm.admin_fd);
+    (void) signal(SIGPIPE, opipe);
+    return;
+}
+
+/*
+ * kadm_init_link
+ *     receives    : name, inst, realm
+ *
+ * initializes client parm, the Kadm_Client structure which holds the 
+ * data about the connection between the server and client, the services 
+ * used, the locations and other fun things 
+ */
+int
+kadm_init_link(n, i, r)
+       char *n;
+       char *i;
+       char *r;
+{
+       struct servent *sep;           /* service we will talk to */
+       struct hostent *hop;           /* host we will talk to */
+       char adm_hostname[MAXHOSTNAMELEN];
+
+       (void) init_kadm_err_tbl();
+       (void) init_krb_err_tbl();
+       (void) strcpy(client_parm.sname, n);
+       (void) strcpy(client_parm.sinst, i);
+       (void) strcpy(client_parm.krbrlm, r);
+       client_parm.admin_fd = -1;
+
+       /* set up the admin_addr - fetch name of admin host */
+       if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS)
+               return KADM_NO_HOST;
+       if ((hop = gethostbyname(adm_hostname)) == NULL)
+               return KADM_UNK_HOST;  /* couldnt find the admin servers
+                                       * address */
+       if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
+               return KADM_NO_SERV;   /* couldnt find the admin service */
+       bzero((char *) &client_parm.admin_addr,
+             sizeof(client_parm.admin_addr));
+       client_parm.admin_addr.sin_family = hop->h_addrtype;
+       bcopy((char *) hop->h_addr, (char *) &client_parm.admin_addr.sin_addr,
+             hop->h_length);
+       client_parm.admin_addr.sin_port = sep->s_port;
+
+       return KADM_SUCCESS;
+}                                     /* procedure kadm_init_link */
+
+static int
+kadm_cli_conn()
+{                                      /* this connects and sets my_addr */
+    int on = 1;
+
+    if ((client_parm.admin_fd =
+        socket(client_parm.admin_addr.sin_family, SOCK_STREAM,0)) < 0)
+       return KADM_NO_SOCK;            /* couldnt create the socket */
+    if (connect(client_parm.admin_fd,
+               (struct sockaddr *) & client_parm.admin_addr,
+               sizeof(client_parm.admin_addr))) {
+       (void) close(client_parm.admin_fd);
+       client_parm.admin_fd = -1;
+       return KADM_NO_CONN;            /* couldnt get the connect */
+    }
+    opipe = signal(SIGPIPE, SIG_IGN);
+    client_parm.my_addr_len = sizeof(client_parm.my_addr);
+    if (getsockname(client_parm.admin_fd,
+                   (struct sockaddr *) & client_parm.my_addr,
+                   &client_parm.my_addr_len) < 0) {
+       (void) close(client_parm.admin_fd);
+       client_parm.admin_fd = -1;
+       (void) signal(SIGPIPE, opipe);
+       return KADM_NO_HERE;            /* couldnt find out who we are */
+    }
+    if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, &on,
+                  sizeof(on)) < 0) {
+       (void) close(client_parm.admin_fd);
+       client_parm.admin_fd = -1;
+       (void) signal(SIGPIPE, opipe);
+       return KADM_NO_CONN;            /* XXX */
+    }
+    return KADM_SUCCESS;
+}
+
+/* takes in the sess_key and key_schedule and sets them appropriately */
+static int
+kadm_cli_keyd(s_k, s_s)
+       des_cblock *s_k;        /* session key */
+       struct des_ks_struct *s_s; /* session key schedule */
+{
+       CREDENTIALS cred;              /* to get key data */
+       int stat;
+
+       /* want .sname and .sinst here.... */
+       if ((stat = krb_get_cred(client_parm.sname, client_parm.sinst,
+                               client_parm.krbrlm, &cred)))
+               return stat + krb_err_base;
+       bcopy((char *) cred.session, (char *) s_k, sizeof(des_cblock));
+       bzero((char *) cred.session, sizeof(des_cblock));
+#ifdef NOENCRYPTION
+       bzero(s_s, sizeof(des_key_schedule));
+#else
+       if ((stat = des_key_sched(s_k,s_s)))
+               return(stat+krb_err_base);
+#endif
+       return KADM_SUCCESS;
+}                                     /* This code "works" */
+
+static int
+kadm_cli_out(dat, dat_len, ret_dat, ret_siz)
+       u_char *dat;
+       int dat_len;
+       u_char **ret_dat;
+       int *ret_siz;
+{
+       u_short dlen;
+       int retval;
+
+       dlen = (u_short) dat_len;
+
+       if (dat_len != (int)dlen)
+               return (KADM_NO_ROOM);
+
+       dlen = htons(dlen);
+       if (krb_net_write(client_parm.admin_fd, (char *) &dlen,
+                         sizeof(u_short)) < 0)
+               return (errno);        /* XXX */
+
+       if (krb_net_write(client_parm.admin_fd, (char *) dat, dat_len) < 0)
+               return (errno);        /* XXX */
+
+       if ((retval = krb_net_read(client_parm.admin_fd, (char *) &dlen,
+                                 sizeof(u_short)) != sizeof(u_short))) {
+           if (retval < 0)
+               return(errno);          /* XXX */
+           else
+               return(EPIPE);          /* short read ! */
+       }
+
+       dlen = ntohs(dlen);
+       *ret_dat = (u_char *)malloc((unsigned)dlen);
+       if (!*ret_dat)
+           return(KADM_NOMEM);
+
+       if ((retval = krb_net_read(client_parm.admin_fd, (char *) *ret_dat,
+                                 (int) dlen) != dlen)) {
+           if (retval < 0)
+               return(errno);          /* XXX */
+           else
+               return(EPIPE);          /* short read ! */
+       }
+       *ret_siz = (int) dlen;
+       return KADM_SUCCESS;
+}
+
+/*
+ * kadm_cli_send
+ *     recieves   : opcode, packet, packet length, serv_name, serv_inst
+ *     returns    : return code from the packet build, the server, or
+ *                      something else 
+ *
+ * It assembles a packet as follows:
+ *      8 bytes    : VERSION STRING
+ *      4 bytes    : LENGTH OF MESSAGE DATA and OPCODE
+ *                 : KTEXT
+ *                 : OPCODE       \
+ *                 : DATA          > Encrypted (with make priv)
+ *                 : ......       / 
+ *
+ * If it builds the packet and it is small enough, then it attempts to open the
+ * connection to the admin server.  If the connection is succesfully open
+ * then it sends the data and waits for a reply. 
+ */
+static int
+kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz)
+       u_char *st_dat;         /* the actual data */
+       int st_siz;             /* length of said data */
+       u_char **ret_dat;       /* to give return info */
+       int *ret_siz;           /* length of returned info */
+{
+       int act_len, retdat;           /* current offset into packet, return
+                                       * data */
+       KTEXT_ST authent;              /* the authenticator we will build */
+       u_char *act_st;                /* the pointer to the complete packet */
+       u_char *priv_pak;              /* private version of the packet */
+       int priv_len;                  /* length of private packet */
+       u_int32_t cksum;                       /* checksum of the packet */
+       MSG_DAT mdat;
+       u_char *return_dat;
+
+       act_st = (u_char *) malloc(KADM_VERSIZE); /* verstr stored first */
+       (void) strncpy((char *)act_st, KADM_VERSTR, KADM_VERSIZE);
+       act_len = KADM_VERSIZE;
+
+       if ((retdat = kadm_cli_keyd(&sess_key, sess_sched)) != KADM_SUCCESS) {
+               free((char *)act_st);
+               return retdat;         /* couldnt get key working */
+       }
+       priv_pak = (u_char *) malloc((unsigned)(st_siz + 200));
+       /* 200 bytes for extra info case */
+       if ((priv_len = krb_mk_priv(st_dat, priv_pak, (u_int32_t)st_siz,
+                                   sess_sched, &sess_key, &client_parm.my_addr,
+                                   &client_parm.admin_addr)) < 0)
+               RET_N_FREE(KADM_NO_ENCRYPT);    /* whoops... we got a lose
+                                                * here */
+       /* here is the length of priv data.  receiver calcs
+        size of authenticator by subtracting vno size, priv size, and
+        sizeof(u_int32_t) (for the size indication) from total size */
+
+       act_len += vts_long((u_int32_t) priv_len, &act_st, act_len);
+#ifdef NOENCRYPTION
+       cksum = 0;
+#else
+       cksum = des_quad_cksum((des_cblock *)priv_pak, (des_cblock *)0, (long)priv_len, 0,
+                          &sess_key);
+#endif
+       if ((retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst,
+                               client_parm.krbrlm, (long)cksum))) {
+           /* authenticator? */
+           RET_N_FREE(retdat + krb_err_base);
+       }
+
+       act_st = (u_char *) realloc((char *) act_st,
+                                   (unsigned) (act_len + authent.length
+                                               + priv_len));
+       if (!act_st) {
+           clear_secrets();
+           free((char *)priv_pak);
+           return(KADM_NOMEM);
+       }
+       bcopy((char *) authent.dat, (char *) act_st + act_len, authent.length);
+       bcopy((char *) priv_pak, (char *) act_st + act_len + authent.length,
+             priv_len);
+       free((char *)priv_pak);
+       if ((retdat = kadm_cli_out(act_st,
+                                  act_len + authent.length + priv_len,
+                                  ret_dat, ret_siz)) != KADM_SUCCESS)
+           RET_N_FREE(retdat);
+       free((char *)act_st);
+#define RET_N_FREE2(r) {free((char *)*ret_dat); clear_secrets(); return(r);}
+
+       /* first see if it's a YOULOUSE */
+       if ((*ret_siz >= KADM_VERSIZE) &&
+           !strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) {
+           u_int32_t errcode;
+           /* it's a youlose packet */
+           if (*ret_siz < KADM_VERSIZE + sizeof(u_int32_t))
+               RET_N_FREE2(KADM_BAD_VER);
+           bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode,
+                 sizeof(u_int32_t));
+           retdat = (int) ntohl(errcode);
+           RET_N_FREE2(retdat);
+       }
+       /* need to decode the ret_dat */
+       if ((retdat = krb_rd_priv(*ret_dat, (u_int32_t)*ret_siz, sess_sched,
+                                &sess_key, &client_parm.admin_addr,
+                                &client_parm.my_addr, &mdat)))
+           RET_N_FREE2(retdat+krb_err_base);
+       if (mdat.app_length < KADM_VERSIZE + 4)
+           /* too short! */
+           RET_N_FREE2(KADM_BAD_VER);
+       if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE))
+           /* bad version */
+           RET_N_FREE2(KADM_BAD_VER);
+       bcopy((char *)mdat.app_data+KADM_VERSIZE,
+             (char *)&retdat, sizeof(u_int32_t));
+       retdat = ntohl((u_int32_t)retdat);
+       if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length -
+                                           KADM_VERSIZE - sizeof(u_int32_t)))))
+           RET_N_FREE2(KADM_NOMEM);
+       bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_int32_t),
+             (char *)return_dat,
+             (int)mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t));
+       free((char *)*ret_dat);
+       clear_secrets();
+       *ret_dat = return_dat;
+       *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t);
+       return retdat;
+}
+
+/*
+ * kadm_change_pw
+ * recieves    : key 
+ *
+ * Replaces the password (i.e. des key) of the caller with that specified in
+ * key. Returns no actual data from the master server, since this is called
+ * by a user 
+ */
+int
+kadm_change_pw(newkey)
+       unsigned char *newkey;  /* The DES form of the users key */
+{
+       int stsize, retc;              /* stream size and return code */
+       u_char *send_st;               /* send stream */
+       u_char *ret_st;
+       int ret_sz;
+       u_int32_t keytmp;
+
+       if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+           return(retc);
+       /* possible problem with vts_long on a non-multiple of four boundary */
+
+       stsize = 0;                    /* start of our output packet */
+       send_st = (u_char *) malloc(1);/* to make it reallocable */
+       send_st[stsize++] = (u_char) CHANGE_PW;
+
+       /* change key to stream */
+
+       bcopy((char *) (((long *) newkey) + 1), (char *) &keytmp, 4);
+       keytmp = htonl(keytmp);
+       stsize += vts_long(keytmp, &send_st, stsize);
+
+       bcopy((char *) newkey, (char *) &keytmp, 4);
+       keytmp = htonl(keytmp);
+       stsize += vts_long(keytmp, &send_st, stsize);
+       
+       retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
+       free((char *)send_st);
+       if (retc == KADM_SUCCESS) {
+           free((char *)ret_st);
+       }
+       kadm_cli_disconn();
+       return(retc);
+}
+
+/*
+ * kadm_add
+ *     receives    : vals
+ *     returns     : vals 
+ *
+ * Adds and entry containing values to the database returns the values of the
+ * entry, so if you leave certain fields blank you will be able to determine
+ * the default values they are set to 
+ */
+int
+kadm_add(vals)
+       Kadm_vals *vals;
+{
+       u_char *st, *st2;              /* st will hold the stream of values */
+       int st_len;                    /* st2 the final stream with opcode */
+       int retc;                      /* return code from call */
+       u_char *ret_st;
+       int ret_sz;
+
+       if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+           return(retc);
+       st_len = vals_to_stream(vals, &st);
+       st2 = (u_char *) malloc((unsigned)(1 + st_len));
+       *st2 = (u_char) ADD_ENT;       /* here's the opcode */
+       bcopy((char *) st, (char *) st2 + 1, st_len);   /* append st on */
+       retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz);
+       free((char *)st);
+       free((char *)st2);
+       if (retc == KADM_SUCCESS) {
+           /* ret_st has vals */
+           if (stream_to_vals(ret_st, vals, ret_sz) < 0)
+               retc = KADM_LENGTH_ERROR;
+           free((char *)ret_st);
+       }
+       kadm_cli_disconn();
+       return(retc);
+}
+
+/*
+ * kadm_mod
+ *     receives    : KTEXT, {values, values}
+ *     returns     : CKSUM,  RETCODE, {values} 
+ *     acl         : su, sms (as register or dealloc) 
+ *
+ * Modifies all entries corresponding to the first values so they match the
+ * second values. returns the values for the changed entries in vals2
+ */
+int
+kadm_mod(vals1, vals2)
+       Kadm_vals *vals1;
+       Kadm_vals *vals2;
+{
+       u_char *st, *st2;              /* st will hold the stream of values */
+       int st_len, nlen;              /* st2 the final stream with opcode */
+       u_char *ret_st;
+       int ret_sz;
+
+       /* nlen is the length of second vals */
+       int retc;                      /* return code from call */
+
+       if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+           return(retc);
+
+       st_len = vals_to_stream(vals1, &st);
+       st2 = (u_char *) malloc((unsigned)(1 + st_len));
+       *st2 = (u_char) MOD_ENT;       /* here's the opcode */
+       bcopy((char *) st, (char *) st2 + 1, st_len++); /* append st on */
+       free((char *)st);
+       nlen = vals_to_stream(vals2, &st);
+       st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen));
+       bcopy((char *) st, (char *) st2 + st_len, nlen); /* append st on */
+       retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz);
+       free((char *)st);
+       free((char *)st2);
+       if (retc == KADM_SUCCESS) {
+           /* ret_st has vals */
+           if (stream_to_vals(ret_st, vals2, ret_sz) < 0)
+               retc = KADM_LENGTH_ERROR;
+           free((char *)ret_st);
+       }
+       kadm_cli_disconn();
+       return(retc);
+}
+
+/*
+ * kadm_get
+ *     receives   : KTEXT, {values, flags} 
+ *     returns    : CKSUM, RETCODE, {count, values, values, values}
+ *     acl        : su 
+ *
+ * gets the fields requested by flags from all entries matching values returns
+ * this data for each matching recipient, after a count of how many such
+ * matches there were 
+ */
+int
+kadm_get(vals, fl)
+       Kadm_vals *vals;
+       u_char *fl;
+{
+       int loop;                      /* for copying the fields data */
+       u_char *st, *st2;              /* st will hold the stream of values */
+       int st_len;                    /* st2 the final stream with opcode */
+       int retc;                      /* return code from call */
+       u_char *ret_st;
+       int ret_sz;
+
+       if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+           return(retc);
+       st_len = vals_to_stream(vals, &st);
+       st2 = (u_char *) malloc((unsigned)(1 + st_len + FLDSZ));
+       *st2 = (u_char) GET_ENT;       /* here's the opcode */
+       bcopy((char *) st, (char *) st2 + 1, st_len);   /* append st on */
+       for (loop = FLDSZ - 1; loop >= 0; loop--)
+               *(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */
+       retc = kadm_cli_send(st2, st_len + 1 + FLDSZ,  &ret_st, &ret_sz);
+       free((char *)st);
+       free((char *)st2);
+       if (retc == KADM_SUCCESS) {
+           /* ret_st has vals */
+           if (stream_to_vals(ret_st, vals, ret_sz) < 0)
+               retc = KADM_LENGTH_ERROR;
+           free((char *)ret_st);
+       }
+       kadm_cli_disconn();
+       return(retc);
+}
diff --git a/kerberosIV/kadm/kadm_err.et b/kerberosIV/kadm/kadm_err.et
new file mode 100644 (file)
index 0000000..495c365
--- /dev/null
@@ -0,0 +1,52 @@
+#      $Id: kadm_err.et,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $
+
+# Copyright 1988 by the Massachusetts Institute of Technology.
+#
+# For copying and distribution information, please see the file
+# <mit-copyright.h>.
+#
+# Kerberos administration server error table
+#
+       et      kadm
+
+# KADM_SUCCESS, as all success codes should be, is zero
+
+ec KADM_RCSID,         "$Header: /home/cvs/src/kerberosIV/kadm/Attic/kadm_err.et,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $"
+# /* Building and unbuilding the packet errors */
+ec KADM_NO_REALM,      "Cannot fetch local realm"
+ec KADM_NO_CRED,       "Unable to fetch credentials"
+ec KADM_BAD_KEY,       "Bad key supplied"
+ec KADM_NO_ENCRYPT,    "Can't encrypt data"
+ec KADM_NO_AUTH,       "Cannot encode/decode authentication info"
+ec KADM_WRONG_REALM,   "Principal attemping change is in wrong realm"
+ec KADM_NO_ROOM,       "Packet is too large"
+ec KADM_BAD_VER,       "Version number is incorrect"
+ec KADM_BAD_CHK,       "Checksum does not match"
+ec KADM_NO_READ,       "Unsealing private data failed"
+ec KADM_NO_OPCODE,     "Unsupported operation"
+ec KADM_NO_HOST,       "Could not find administrating host"
+ec KADM_UNK_HOST,      "Administrating host name is unknown"
+ec KADM_NO_SERV,       "Could not find service name in services database"
+ec KADM_NO_SOCK,       "Could not create socket"
+ec KADM_NO_CONN,       "Could not connect to server"
+ec KADM_NO_HERE,       "Could not fetch local socket address"
+ec KADM_NO_MAST,       "Could not fetch master key"
+ec KADM_NO_VERI,       "Could not verify master key"
+
+# /* From the server side routines */
+ec KADM_INUSE,         "Entry already exists in database"
+ec KADM_UK_SERROR,     "Database store error"
+ec KADM_UK_RERROR,     "Database read error"
+ec KADM_UNAUTH,                "Insufficient access to perform requested operation"
+# KADM_DATA isn't really an error, but...
+ec KADM_DATA,          "Data is available for return to client"
+ec KADM_NOENTRY,       "No such entry in the database"
+
+ec KADM_NOMEM,         "Memory exhausted"
+ec KADM_NO_HOSTNAME,   "Could not fetch system hostname"
+ec KADM_NO_BIND,       "Could not bind port"
+ec KADM_LENGTH_ERROR,  "Length mismatch problem"
+ec KADM_ILL_WILDCARD,  "Illegal use of wildcard"
+
+ec KADM_DB_INUSE,      "Database is locked or in use--try again later"
+end
diff --git a/kerberosIV/kadm/kadm_local.h b/kerberosIV/kadm/kadm_local.h
new file mode 100644 (file)
index 0000000..8133671
--- /dev/null
@@ -0,0 +1,31 @@
+/*     $Id: kadm_local.h,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $     */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "krb_err.h"
+#include <kerberosIV/krb_db.h>
+#include <kerberosIV/kadm.h>
+#include "kadm_err.h"
+
+int vts_long __P((u_int32_t, u_char **, int));
+int vals_to_stream __P((Kadm_vals *, u_char **));
+int stream_to_vals __P((u_char *, Kadm_vals *, int));
+
+int kadm_init_link __P((char n[], char i[], char r[]));
+int kadm_change_pw __P((des_cblock));
+int kadm_add __P((Kadm_vals *));
+int kadm_mod __P((Kadm_vals *, Kadm_vals *));
+int kadm_get __P((Kadm_vals *, u_char fl[4]));
diff --git a/kerberosIV/kadm/kadm_stream.c b/kerberosIV/kadm/kadm_stream.c
new file mode 100644 (file)
index 0000000..cdf291b
--- /dev/null
@@ -0,0 +1,294 @@
+/*     $Id: kadm_stream.c,v 1.1.1.1 1995/12/14 06:52:45 tholo Exp $    */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Stream conversion functions for Kerberos administration server
+ */
+
+/*
+  kadm_stream.c
+  this holds the stream support routines for the kerberos administration server
+
+    vals_to_stream: converts a vals struct to a stream for transmission
+       internals build_field_header, vts_[string, char, long, short]
+    stream_to_vals: converts a stream to a vals struct
+       internals check_field_header, stv_[string, char, long, short]
+    error: prints out a kadm error message, returns
+    fatal: prints out a kadm fatal error message, exits
+*/
+
+#include "kadm_local.h"
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+static int
+build_field_header(cont, st)
+       u_char *cont;           /* container for fields data */
+       u_char **st;            /* stream */
+{
+  *st = (u_char *) malloc (4);
+  bcopy((char *) cont, (char *) *st, 4);
+  return 4;                    /* return pointer to current stream location */
+}
+
+static int
+check_field_header(st, cont, maxlen)
+       u_char *st;             /* stream */
+       u_char *cont;           /* container for fields data */
+       int maxlen;
+{
+  if (4 > maxlen)
+      return(-1);
+  bcopy((char *) st, (char *) cont, 4);
+  return 4;                    /* return pointer to current stream location */
+}
+
+static int
+vts_string(dat, st, loc)
+       char *dat;              /* a string to put on the stream */
+       u_char **st;            /* base pointer to the stream */
+       int loc;                /* offset into the stream for current data */
+{
+  *st = (u_char *) realloc ((char *)*st, (unsigned) (loc + strlen(dat) + 1));
+  bcopy(dat, (char *)(*st + loc), strlen(dat)+1);
+  return strlen(dat)+1;
+}
+
+
+static int
+vts_short(dat, st, loc)
+       u_int16_t dat;          /* the attributes field */
+       u_char **st;            /* a base pointer to the stream */
+       int loc;                /* offset into the stream for current data */
+{
+  u_int16_t temp;                      /* to hold the net order short */
+
+  temp = htons(dat);           /* convert to network order */
+  *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int16_t)));
+  bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int16_t));
+  return sizeof(u_int16_t);
+}
+
+static int
+vts_char(dat, st, loc)
+       u_char dat;             /* the attributes field */
+       u_char **st;            /* a base pointer to the stream */
+       int loc;                /* offset into the stream for current data */
+{
+  *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_char)));
+  (*st)[loc] = (u_char) dat;
+  return 1;
+}
+
+int
+vts_long(dat, st, loc)
+       u_int32_t dat;          /* the attributes field */
+       u_char **st;            /* a base pointer to the stream */
+       int loc;                /* offset into the stream for current data */
+{
+  u_int32_t temp;                      /* to hold the net order short */
+
+  temp = htonl(dat);           /* convert to network order */
+  *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int32_t)));
+  bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int32_t));
+  return sizeof(u_int32_t);
+}
+    
+static int
+stv_string(st, dat, loc, stlen, maxlen)
+       register u_char *st;    /* base pointer to the stream */
+       char *dat;              /* a string to read from the stream */
+       register int loc;       /* offset into the stream for current data */
+       int stlen;              /* max length of string to copy in */
+       int maxlen;             /* max length of input stream */
+{
+  int maxcount;                                /* max count of chars to copy */
+
+  maxcount = min(maxlen - loc, stlen);
+
+  (void) strncpy(dat, (char *)st + loc, maxcount);
+
+  if (dat[maxcount-1]) /* not null-term --> not enuf room */
+      return(-1);
+  return strlen(dat)+1;
+}
+
+static int
+stv_short(st, dat, loc, maxlen)
+       u_char *st;             /* a base pointer to the stream */
+        u_int16_t *dat;                /* the attributes field */
+       int loc;                /* offset into the stream for current data */
+       int maxlen;
+{
+  u_int16_t temp;                      /* to hold the net order short */
+
+  if (loc + sizeof(temp) > maxlen)
+      return(-1);
+  /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));*/
+  bcopy(st + loc, (char *) &temp, sizeof(temp));
+  *dat = ntohs(temp);          /* convert to network order */
+  return sizeof(temp);
+}
+
+int
+stv_long(st, dat, loc, maxlen)
+       u_char *st;             /* a base pointer to the stream */
+       u_int32_t *dat;         /* the attributes field */
+       int loc;                /* offset into the stream for current data */
+       int maxlen;             /* maximum length of st */
+{
+  u_int32_t temp;                      /* to hold the net order short */
+
+  if (loc + sizeof(temp) > maxlen)
+      return(-1);
+  /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));*/
+  bcopy(st + loc, (char *) &temp, sizeof(temp));
+  *dat = ntohl(temp);          /* convert to network order */
+  return sizeof(temp);
+}
+    
+static int
+stv_char(st, dat, loc, maxlen)
+       u_char *st;             /* a base pointer to the stream */
+       u_char *dat;            /* the attributes field */
+       int loc;                /* offset into the stream for current data */
+       int maxlen;
+{
+  if (loc + 1 > maxlen)
+      return(-1);
+  *dat = *(st + loc);
+  return 1;
+}
+
+/* 
+vals_to_stream
+  recieves    : kadm_vals *, u_char *
+  returns     : a realloced and filled in u_char *
+     
+this function creates a byte-stream representation of the kadm_vals structure
+*/
+int
+vals_to_stream(dt_in, dt_out)
+       Kadm_vals *dt_in;
+       u_char **dt_out;
+{
+  int vsloop, stsize;          /* loop counter, stream size */
+
+  stsize = build_field_header(dt_in->fields, dt_out);
+  for (vsloop=31; vsloop>=0; vsloop--)
+    if (IS_FIELD(vsloop,dt_in->fields)) {
+      switch (vsloop) {
+      case KADM_NAME:
+         stsize+=vts_string(dt_in->name, dt_out, stsize);
+         break;
+      case KADM_INST:
+         stsize+=vts_string(dt_in->instance, dt_out, stsize);
+         break;
+      case KADM_EXPDATE:
+         stsize+=vts_long(dt_in->exp_date, dt_out, stsize);
+         break;
+      case KADM_ATTR:
+         stsize+=vts_short(dt_in->attributes, dt_out, stsize);
+         break;
+      case KADM_MAXLIFE:
+         stsize+=vts_char(dt_in->max_life, dt_out, stsize);
+         break;
+      case KADM_DESKEY: 
+         stsize+=vts_long(dt_in->key_high, dt_out, stsize); 
+         stsize+=vts_long(dt_in->key_low, dt_out, stsize); 
+         break;
+      default:
+         break;
+      }
+}
+  return(stsize);
+}  
+
+/* 
+stream_to_vals
+  recieves    : u_char *, kadm_vals *
+  returns     : a kadm_vals filled in according to u_char *
+     
+this decodes a byte stream represntation of a vals struct into kadm_vals
+*/
+int
+stream_to_vals(dt_in, dt_out, maxlen)
+       u_char *dt_in;
+       Kadm_vals *dt_out;
+       int maxlen;             /* max length to use */
+{
+  register int vsloop, stsize;         /* loop counter, stream size */
+  register int status;
+
+  bzero((char *) dt_out, sizeof(*dt_out));
+
+  stsize = check_field_header(dt_in, dt_out->fields, maxlen);
+  if (stsize < 0)
+      return(-1);
+  for (vsloop=31; vsloop>=0; vsloop--)
+    if (IS_FIELD(vsloop,dt_out->fields))
+      switch (vsloop) {
+      case KADM_NAME:
+         if ((status = stv_string(dt_in, dt_out->name, stsize,
+                                  sizeof(dt_out->name), maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      case KADM_INST:
+         if ((status = stv_string(dt_in, dt_out->instance, stsize,
+                                  sizeof(dt_out->instance), maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      case KADM_EXPDATE:
+         if ((status = stv_long(dt_in, &dt_out->exp_date, stsize,
+                                maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      case KADM_ATTR:
+         if ((status = stv_short(dt_in, &dt_out->attributes, stsize,
+                                 maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      case KADM_MAXLIFE:
+         if ((status = stv_char(dt_in, &dt_out->max_life, stsize,
+                                maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      case KADM_DESKEY:
+         if ((status = stv_long(dt_in, &dt_out->key_high, stsize,
+                                   maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         if ((status = stv_long(dt_in, &dt_out->key_low, stsize,
+                                   maxlen)) < 0)
+             return(-1);
+         stsize += status;
+         break;
+      default:
+         break;
+      }
+  return stsize;
+}  
diff --git a/kerberosIV/kadm/kadm_supp.c b/kerberosIV/kadm/kadm_supp.c
new file mode 100644 (file)
index 0000000..e195c51
--- /dev/null
@@ -0,0 +1,126 @@
+/*     $Id: kadm_supp.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $      */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Support functions for Kerberos administration server & clients
+ */
+
+/*
+  kadm_supp.c
+  this holds the support routines for the kerberos administration server
+
+    error: prints out a kadm error message, returns
+    fatal: prints out a kadm fatal error message, exits
+    prin_vals: prints out data associated with a Principal in the vals
+           structure
+*/
+
+#include "kadm_local.h"
+    
+/*
+prin_vals:
+  recieves    : a vals structure
+*/
+void
+prin_vals(vals)
+       Kadm_vals *vals;
+{
+   printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
+   printf("   Max Life: %d (%s)   Exp Date: %s\n",
+         vals->max_life,
+         krb_life_to_atime(vals->max_life), 
+         asctime(k_localtime(&vals->exp_date)));
+   printf("   Attribs: %.2x  key: %lu %lu\n",
+         vals->attributes,
+         (long)vals->key_low, (long)vals->key_high);
+}
+
+#ifdef notdef
+nierror(s)
+int s;
+{
+    printf("Kerberos admin server loses..... %s\n",error_message(s));
+    return(s);
+}
+#endif
+
+/* kadm_prin_to_vals takes a fields arguments, a Kadm_vals and a Principal,
+   it copies the fields in Principal specified by fields into Kadm_vals, 
+   i.e from old to new */
+
+void
+kadm_prin_to_vals(fields, new, old)
+       u_char *fields;
+       Kadm_vals *new;
+       Principal *old;
+{
+  bzero((char *)new, sizeof(*new));
+  if (IS_FIELD(KADM_NAME,fields)) {
+      (void) strncpy(new->name, old->name, ANAME_SZ); 
+      SET_FIELD(KADM_NAME, new->fields);
+  }
+  if (IS_FIELD(KADM_INST,fields)) {
+      (void) strncpy(new->instance, old->instance, INST_SZ); 
+      SET_FIELD(KADM_INST, new->fields);
+  }      
+  if (IS_FIELD(KADM_EXPDATE,fields)) {
+      new->exp_date   = old->exp_date; 
+      SET_FIELD(KADM_EXPDATE, new->fields);
+  }      
+  if (IS_FIELD(KADM_ATTR,fields)) {
+    new->attributes = old->attributes; 
+      SET_FIELD(KADM_ATTR, new->fields);
+  }      
+  if (IS_FIELD(KADM_MAXLIFE,fields)) {
+    new->max_life   = old->max_life; 
+      SET_FIELD(KADM_MAXLIFE, new->fields);
+  }      
+  if (IS_FIELD(KADM_DESKEY,fields)) {
+    new->key_low    = old->key_low; 
+    new->key_high   = old->key_high; 
+    SET_FIELD(KADM_DESKEY, new->fields);
+  }
+}
+
+void
+kadm_vals_to_prin(fields, new, old)
+       u_char *fields;
+       Principal *new;
+       Kadm_vals *old;
+{
+
+  bzero((char *)new, sizeof(*new));
+  if (IS_FIELD(KADM_NAME,fields))
+    (void) strncpy(new->name, old->name, ANAME_SZ); 
+  if (IS_FIELD(KADM_INST,fields))
+    (void) strncpy(new->instance, old->instance, INST_SZ); 
+  if (IS_FIELD(KADM_EXPDATE,fields))
+    new->exp_date   = old->exp_date; 
+  if (IS_FIELD(KADM_ATTR,fields))
+    new->attributes = old->attributes; 
+  if (IS_FIELD(KADM_MAXLIFE,fields))
+    new->max_life   = old->max_life; 
+  if (IS_FIELD(KADM_DESKEY,fields)) {
+    new->key_low    = old->key_low; 
+    new->key_high   = old->key_high; 
+  }
+}
diff --git a/kerberosIV/kadm/shlib_version b/kerberosIV/kadm/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/kadmin/Makefile b/kerberosIV/kadmin/Makefile
new file mode 100644 (file)
index 0000000..e24b6a2
--- /dev/null
@@ -0,0 +1,31 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $
+
+PROG=  kadmin
+SRCS=  kadmin.c kadmin_cmds.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+.if exists(${.CURDIR}/../kadm/obj)
+CFLAGS+=-I${.CURDIR}/../kadm/obj
+.else
+CFLAGS+=-I${.CURDIR}/../kadm
+.endif
+.if exists(${.CURDIR}/../krb/obj)
+CFLAGS+=-I${.CURDIR}/../krb/obj
+.else
+CFLAGS+=-I${.CURDIR}/../krb
+.endif
+.if exists(${.CURDIR}/../ss/obj)
+CFLAGS+=-I${.CURDIR}/../ss/obj
+.else
+CFLAGS+=-I${.CURDIR}/../ss
+.endif
+LDADD+=        -lkadm -lkrb -ldes -lss -lcom_err
+DPADD+=        ${LIBKADM} ${LIBKRB} ${LIBDES} ${LIBSS} ${LIBCOM_ERR}
+CLEANFILES+= kadmin_cmds.c
+MAN=   kadmin.8
+
+kadmin_cmds.c:  kadmin_cmds.ct
+       test -e kadmin_cmds.ct || ln -s ${.CURDIR}/kadmin_cmds.ct .
+       ${MK_CMDS} kadmin_cmds.ct
+       -test -h kadmin_cmds.ct && rm kadmin_cmds.ct
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kadmin/kadmin.8 b/kerberosIV/kadmin/kadmin.8
new file mode 100644 (file)
index 0000000..8b22c75
--- /dev/null
@@ -0,0 +1,157 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kadmin.8,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $
+.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmin \- network utility for Kerberos database administration
+.SH SYNOPSIS
+.B kadmin [-u user] [-r default_realm] [-m]
+.SH DESCRIPTION
+This utility provides a unified administration interface to
+the
+Kerberos
+master database.
+Kerberos
+administrators
+use
+.I kadmin
+to register new users and services to the master database,
+and to change information about existing database entries.
+For instance, an administrator can use
+.I kadmin
+to change a user's
+Kerberos
+password.
+A Kerberos administrator is a user with an ``admin'' instance
+whose name appears on one of the Kerberos administration access control
+lists.  If the \-u option is used, 
+.I user 
+will be used as the administrator instead of the local user.
+If the \-r option is used, 
+.I default_realm
+will be used as the default realm for transactions.  Otherwise,
+the local realm will be used by default.
+If the \-m option is used, multiple requests will be permitted 
+on only one entry of the admin password.  Some sites won't
+support this option.
+
+The
+.I kadmin
+program communicates over the network with the
+.I kadmind
+program, which runs on the machine housing the Kerberos master
+database.
+The
+.I kadmind
+creates new entries and makes modifications to the database.
+
+When you enter the
+.I kadmin
+command,
+the program displays a message that welcomes you and explains
+how to ask for help.
+Then
+.I kadmin
+waits for you to enter commands (which are described below).
+It then asks you for your
+.I admin
+password before accessing the database.
+
+Use the
+.I add_new_key
+(or
+.I ank
+for short)
+command to register a new principal
+with the master database.
+The command requires one argument,
+the principal's name.  The name
+given can be fully qualified using 
+the standard 
+.I name.instance@realm
+convention.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's
+new password.  If no realm is specified, 
+the local realm is used unless another was
+given on the commandline with the \-r flag.  
+If no instance is
+specified, a null instance is used.  If
+a realm other than the default realm is specified,
+you will need to supply your admin password for
+the other realm.
+
+Use the
+.I change_password (cpw)
+to change a principal's
+Kerberos
+password.
+The command requires one argument,
+the principal's
+name.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's new password.
+The name
+given can be fully qualified using 
+the standard 
+.I name.instance@realm
+convention.
+
+Use the
+.I change_admin_password (cap)
+to change your
+.I admin
+instance password.
+This command requires no arguments.
+It prompts you for your old
+.I admin
+password, then prompts you twice to enter the new
+.I admin
+password.  If this is your first command, 
+the default realm is used.  Otherwise, the realm
+used in the last command is used.
+
+Use the
+.I destroy_tickets (dest)
+command to destroy your admin tickets explicitly.
+
+Use the
+.I list_requests (lr)
+command to get a list of possible commands.
+
+Use the
+.I help
+command to display
+.IR kadmin's
+various help messages.
+If entered without an argument,
+.I help
+displays a general help message.
+You can get detailed information on specific
+.I kadmin
+commands
+by entering 
+.I help
+.IR command_name .
+
+To quit the program, type
+.IR quit .
+
+.SH BUGS
+The user interface is primitive, and the command names could be better.
+
+.SH "SEE ALSO"
+kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8)
+.br
+``A Subsystem Utilities Package for UNIX'' by Ken Raeburn
+.SH AUTHORS
+Jeffrey I. Schiller, MIT Project Athena
+.br
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/kerberosIV/kadmin/kadmin.c b/kerberosIV/kadmin/kadmin.c
new file mode 100644 (file)
index 0000000..e5581f5
--- /dev/null
@@ -0,0 +1,765 @@
+/*     $Id: kadmin.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $ */
+
+/* 
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Kerberos database administrator's tool.  
+ * 
+ * The default behavior of kadmin is if the -m option is given 
+ * on the commandline, multiple requests are allowed to be given
+ * with one entry of the admin password (until the tickets expire).
+ * If you do not want this to be an available option, compile with
+ * NO_MULTIPLE defined.
+ */
+
+#include <kadm_locl.h>
+#include <sys/param.h>
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15         /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+/* for get_password, whether it should do the swapping...necessary for
+   using vals structure, unnecessary for change_pw requests */
+#define DONTSWAP 0
+#define SWAP 1
+
+extern ss_request_table admin_cmds;
+
+static char myname[ANAME_SZ];
+static char default_realm[REALM_SZ]; /* default kerberos realm */
+static char krbrlm[REALM_SZ];  /* current realm being administered */
+static int multiple = 0;       /* Allow multiple requests per ticket */
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+
+static void
+get_maxlife(Kadm_vals *vals)
+{
+    char buff[BUFSIZ];
+    time_t life;
+    int l;
+
+    do {
+       printf("Maximum ticket lifetime?  (%d)  [%s]  ",
+            vals->max_life, krb_life_to_atime(vals->max_life));
+       fflush(stdout);
+       if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+           clearerr(stdin);
+           return;
+       }
+       life = krb_atime_to_life(buff);
+    } while (life <= 0);
+
+    l = strlen(buff);
+    if (buff[l-2] == 'm')
+       life = krb_time_to_life(0L, life*60);
+    if (buff[l-2] == 'h')
+       life = krb_time_to_life(0L, life*60*60);
+
+    vals->max_life = life;
+    SET_FIELD(KADM_MAXLIFE,vals->fields);
+}
+
+static void
+get_attr(Kadm_vals *vals)
+{
+    char buff[BUFSIZ], *out;
+    int attr;
+
+    do {
+       printf("Attributes?  [0x%.2x]  ", vals->attributes);
+       fflush(stdout);
+       if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+           clearerr(stdin);
+           return;
+       }
+        attr = strtol(buff, &out, 0);
+       if (attr == 0 && out == buff)
+         attr = -1;
+    } while (attr < 0 || attr > 0xffff);
+
+    vals->attributes = attr;
+    SET_FIELD(KADM_ATTR,vals->fields);
+}
+
+static void
+get_expdate(Kadm_vals *vals)
+{
+    char buff[BUFSIZ];
+    time_t when;
+    struct tm edate;
+
+    bzero(&edate, sizeof(edate));
+    do {
+        printf("Expiration date (enter yyyy-mm-dd) ?  [%.24s]  ",
+             asctime(k_localtime(&vals->exp_date)));
+        fflush(stdout);
+        if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+            clearerr(stdin);
+            return;
+        }
+        if (sscanf(buff, "%d-%d-%d",
+                   &edate.tm_year, &edate.tm_mon, &edate.tm_mday) == 3) {
+            edate.tm_mon--;     /* January is 0, not 1 */
+            edate.tm_hour = 23; /* nearly midnight at the end of the */
+            edate.tm_min = 59;  /* specified day */
+            when = maketime(&edate, 1);
+        }
+    } while (when <= 0);
+
+    vals->exp_date = when;
+    SET_FIELD(KADM_EXPDATE,vals->fields);
+}
+
+static int
+princ_exists(char *name, char *instance, char *realm)
+{
+    int status;
+
+    status = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm, 1, "");
+
+    if ((status == KSUCCESS) || (status == INTK_BADPW))
+       return(PE_YES);
+    else if (status == KDC_PR_UNKNOWN)
+       return(PE_NO);
+    else
+       return(PE_UNSURE);
+}
+
+static int
+get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap)
+{
+    char new_passwd[MAX_KPW_LEN];      /* new password */
+    des_cblock newkey;
+
+    if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1))
+       return(BAD_PW);
+    if (strlen(new_passwd) == 0) {
+       printf("Using random password.\n");
+#ifdef NOENCRYPTION
+       bzero((char *) newkey, sizeof(newkey));
+#else
+       des_new_random_key(&newkey);
+#endif
+    } else {
+#ifdef NOENCRYPTION
+      bzero((char *) newkey, sizeof(newkey));
+#else
+      des_string_to_key(new_passwd, &newkey);
+#endif
+      bzero(new_passwd, sizeof(new_passwd));
+    }
+
+    bcopy((char *) newkey,(char *)low,4);
+    bcopy((char *)(((int32_t *) newkey) + 1), (char *)high,4);
+
+    bzero((char *) newkey, sizeof(newkey));
+
+#ifdef NOENCRYPTION
+    *low = 1;
+#endif
+
+    if (byteswap != DONTSWAP) {
+       *low = htonl(*low);
+       *high = htonl(*high);
+    }
+    return(GOOD_PW);
+}
+
+static int
+get_admin_password(void)
+{
+    int status;
+    char admin_passwd[MAX_KPW_LEN];    /* Admin's password */
+    int ticket_life = 1;       /* minimum ticket lifetime */
+    CREDENTIALS c;
+
+    if (multiple) {
+       /* If admin tickets exist and are valid, just exit. */
+       bzero(&c, sizeof(c));
+       if (krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c) == KSUCCESS)
+           /* 
+            * If time is less than lifetime - FUDGE_VALUE after issue date,
+            * tickets will probably last long enough for the next 
+            * transaction.
+            */
+           if (time(0) < (c.issue_date + (5 * 60 * c.lifetime) - FUDGE_VALUE))
+               return(KADM_SUCCESS);
+       ticket_life = DEFAULT_TKT_LIFE;
+    }
+    
+    if (princ_exists(myname, "admin", krbrlm) != PE_NO) {
+       if (read_long_pw_string(admin_passwd, sizeof(admin_passwd)-1,
+                               "Admin password:", 0)) {
+           fprintf(stderr, "Error reading admin password.\n");
+           goto bad;
+       }
+       status = krb_get_pw_in_tkt(myname, "admin", krbrlm, PWSERV_NAME, 
+                                  KADM_SINST, ticket_life, admin_passwd);
+       bzero(admin_passwd, sizeof(admin_passwd));
+
+       /* Initialize non shared random sequence from session key. */
+       bzero(&c, sizeof(c));
+       krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c);
+       des_init_random_number_generator(&c.session);
+    }
+    else
+       status = KDC_PR_UNKNOWN;
+
+    switch(status) {
+    case GT_PW_OK:
+       return(GOOD_PW);
+    case KDC_PR_UNKNOWN:
+       printf("Principal %s.admin@%s does not exist.\n", myname, krbrlm);
+       goto bad;
+    case GT_PW_BADPW:
+       printf("Incorrect admin password.\n");
+       goto bad;
+    default:
+       com_err("kadmin", status+krb_err_base,
+               "while getting password tickets");
+       goto bad;
+    }
+    
+ bad:
+    bzero(admin_passwd, sizeof(admin_passwd));
+    (void) dest_tkt();
+    return(BAD_PW);
+}
+
+static void
+usage(void)
+{
+    fprintf(stderr, "Usage: kadmin [-u admin_name] [-r default_realm]");
+    fprintf(stderr, " [-m]");
+    fprintf(stderr, "\n");
+    fprintf(stderr, "   -m allows multiple admin requests to be ");
+    fprintf(stderr, "serviced with one entry of admin\n");
+    fprintf(stderr, "   password.\n");
+    exit(1);
+}
+
+/* GLOBAL */
+void
+clean_up(void)
+{
+    (void) dest_tkt();
+    return;
+}
+
+/* GLOBAL */
+void 
+quit(void)
+{
+    printf("Cleaning up and exiting.\n");
+    clean_up();
+    exit(0);
+}
+
+static int inited = 0;
+
+static void
+do_init(int argc, char **argv)
+{
+    struct passwd *pw;
+    int c;
+#define OPTION_STRING "u:r:m"
+    
+    bzero(myname, sizeof(myname));
+
+    if (!inited) {
+       /* 
+        * This is only as a default/initial realm; we don't care 
+        * about failure.
+        */
+       if (krb_get_lrealm(default_realm, 1) != KSUCCESS)
+           strcpy(default_realm, KRB_REALM);
+
+       /* 
+        * If we can reach the local realm, initialize to it.  Otherwise,
+        * don't initialize.
+        */
+       if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS)
+           bzero(krbrlm, sizeof(krbrlm));
+       else
+           strcpy(krbrlm, default_realm);
+
+       while ((c = getopt(argc, argv, OPTION_STRING)) != EOF) 
+           switch (c) {
+             case 'u':
+               strncpy(myname, optarg, sizeof(myname) - 1);
+               break;
+             case 'r':
+               bzero(default_realm, sizeof(default_realm));
+               strncpy(default_realm, optarg, sizeof(default_realm) - 1);
+               break;
+             case 'm':
+               multiple++;
+               break;
+             default:
+               usage();
+               break;
+           }
+       if (optind < argc)
+           usage();
+       if (!myname[0]) {
+           pw = getpwuid((int) getuid());
+           if (!pw) {
+               fprintf(stderr,
+                       "You aren't in the password file.  Who are you?\n");
+               exit(1);
+           }
+           (void) strcpy(myname, pw->pw_name);
+       }
+       inited = 1;
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    int     sci_idx;
+    int     code;
+    char tktstring[MAXPATHLEN];
+
+    sci_idx = ss_create_invocation("admin", "2.0", (char *) NULL,
+                                  &admin_cmds, &code);
+    if (code) {
+       ss_perror(sci_idx, code, "creating invocation");
+       exit(1);
+    }
+    (void) sprintf(tktstring, "/tmp/tkt_adm_%d",(int)getpid());
+    krb_set_tkt_string(tktstring);
+
+    do_init(argc, argv);
+
+    printf("Welcome to the Kerberos Administration Program, version 2\n");
+    printf("Type \"help\" if you need it.\n");
+    code = ss_listen(sci_idx);
+    printf("\n");
+    quit();
+    exit(0);
+}
+
+static int
+setvals(Kadm_vals *vals, char *string)
+{
+    char realm[REALM_SZ];
+    int status = KADM_SUCCESS;
+
+    bzero(vals, sizeof(*vals));
+    bzero(realm, sizeof(realm));
+
+    SET_FIELD(KADM_NAME,vals->fields);
+    SET_FIELD(KADM_INST,vals->fields);
+    if ((status = kname_parse(vals->name, vals->instance, realm, string))) {
+       printf("kerberos error: %s\n", krb_err_txt[status]);
+       return status;
+    }
+    if (!realm[0])
+       strcpy(realm, default_realm);
+    if (strcmp(realm, krbrlm)) {
+       strcpy(krbrlm, realm);
+       if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm)) 
+           != KADM_SUCCESS)
+           printf("kadm error for realm %s: %s\n", 
+                  krbrlm, error_message(status));
+    }
+    if (status) 
+       return 1;
+    else
+       return KADM_SUCCESS;
+}    
+
+void 
+change_password(int argc, char **argv)
+{
+    Kadm_vals old, new;
+    int status;
+    char pw_prompt[BUFSIZ];
+
+    if (argc != 2) {
+       printf("Usage: change_password loginname\n");
+       return;
+    }
+
+    if (setvals(&old, argv[1]) != KADM_SUCCESS)
+       return;
+
+    new = old;
+
+    SET_FIELD(KADM_DESKEY,new.fields);
+
+    if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+       /* get the admin's password */
+        if (get_admin_password() != GOOD_PW)
+           return;
+
+       /* get the new password */
+       (void) sprintf(pw_prompt, "New password for %s:", argv[1]);
+       
+       if (get_password(&new.key_low, &new.key_high,
+                        pw_prompt, SWAP) == GOOD_PW) {
+           status = kadm_mod(&old, &new);
+           if (status == KADM_SUCCESS) {
+               printf("Password changed for %s.\n", argv[1]);
+           } else {
+               printf("kadmin: %s\nwhile changing password for %s",
+                      error_message(status), argv[1]);
+           }
+       } else
+           printf("Error reading password; password unchanged\n");
+       bzero((char *)&new, sizeof(new));
+       if (!multiple)
+           clean_up();
+    }
+    else 
+       printf("kadmin: Principal does not exist.\n");
+    return;
+}
+
+/*ARGSUSED*/
+void 
+change_admin_password(int argc, char **argv)
+{
+    des_cblock newkey;
+    u_int32_t low, high;
+    int status;
+    char prompt_pw[BUFSIZ];
+
+    if (argc != 1) {
+       printf("Usage: change_admin_password\n");
+       return;
+    }
+    /* get the admin's password */
+    if (get_admin_password() != GOOD_PW)
+       return;
+
+    (void) sprintf(prompt_pw, "New password for %s.admin:",myname);
+    if (get_password(&low, &high, prompt_pw, DONTSWAP) == GOOD_PW) {
+       bcopy((char *)&low,(char *) newkey,4);
+       bcopy((char *)&high, (char *)(((int32_t *) newkey) + 1),4);
+       low = high = 0L;
+       if ((status = kadm_change_pw(newkey)) == KADM_SUCCESS)
+           printf("Admin password changed\n");
+       else
+           printf("kadm error: %s\n",error_message(status));
+       bzero((char *)newkey, sizeof(newkey));
+    } else
+       printf("Error reading password; password unchanged\n");
+    if (!multiple)
+       clean_up();
+    return;
+}
+
+void 
+add_new_key(int argc, char **argv)
+{
+    Kadm_vals new;
+    char pw_prompt[BUFSIZ];
+    int status;
+
+    if (argc != 2) {
+       printf("Usage: add_new_key user_name.\n");
+       return;
+    }
+    if (setvals(&new, argv[1]) != KADM_SUCCESS)
+       return;
+
+    SET_FIELD(KADM_DESKEY,new.fields);
+
+    if (princ_exists(new.name, new.instance, krbrlm) != PE_YES) {
+       /* get the admin's password */
+       if (get_admin_password() != GOOD_PW)
+           return;
+       
+       /* This is the default maximum lifetime for new principals. */
+       if (krb_life_to_time(0, 162) >= 24*60*60)
+         new.max_life = 162;     /* ca 100 hours */
+       else
+         new.max_life = 255;     /* ca 21 hours (maximum) */
+       new.exp_date = time(0) + 2*(365*24*60*60); /* + ca 2 years */
+       new.attributes = 0;
+       get_maxlife(&new);
+       get_attr(&new);
+       get_expdate(&new);
+
+       /* get the new password */
+       (void) sprintf(pw_prompt, "Password for %s:", argv[1]);
+       
+       if (get_password(&new.key_low, &new.key_high,
+                        pw_prompt, SWAP) == GOOD_PW) {
+           status = kadm_add(&new);
+           if (status == KADM_SUCCESS) {
+               printf("%s added to database.\n", argv[1]);
+           } else {
+               printf("kadm error: %s\n",error_message(status));
+           }
+       } else
+           printf("Error reading password; %s not added\n",argv[1]);
+       bzero((char *)&new, sizeof(new));
+       if (!multiple)
+           clean_up();
+    }
+    else
+       printf("kadmin: Principal already exists.\n");
+    return;
+}
+
+void 
+get_entry(int argc, char **argv)
+{
+    int status;
+    u_char fields[4];
+    Kadm_vals vals;
+
+    if (argc != 2) {
+       printf("Usage: get_entry username\n");
+       return;
+    }
+
+    bzero(fields, sizeof(fields));
+
+    SET_FIELD(KADM_NAME,fields);
+    SET_FIELD(KADM_INST,fields);
+    SET_FIELD(KADM_EXPDATE,fields);
+    SET_FIELD(KADM_ATTR,fields);
+    SET_FIELD(KADM_MAXLIFE,fields);
+
+    if (setvals(&vals, argv[1]) != KADM_SUCCESS)
+       return;
+
+
+    if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+       /* get the admin's password */
+       if (get_admin_password() != GOOD_PW)
+           return;
+       
+       if ((status = kadm_get(&vals, fields)) == KADM_SUCCESS)
+           prin_vals(&vals);
+       else
+           printf("kadm error: %s\n",error_message(status));
+       
+       if (!multiple)
+           clean_up();
+    }
+    else
+       printf("kadmin: Principal does not exist.\n");
+    return;
+}
+
+void 
+mod_entry(int argc, char **argv)
+{
+    int status;
+    u_char fields[4];
+    Kadm_vals ovals, nvals;
+
+    if (argc != 2) {
+       printf("Usage: mod_entry username\n");
+       return;
+    }
+
+    bzero(fields, sizeof(fields));
+
+    SET_FIELD(KADM_NAME,fields);
+    SET_FIELD(KADM_INST,fields);
+    SET_FIELD(KADM_EXPDATE,fields);
+    SET_FIELD(KADM_ATTR,fields);
+    SET_FIELD(KADM_MAXLIFE,fields);
+
+    if (setvals(&ovals, argv[1]) != KADM_SUCCESS)
+       return;
+
+    nvals = ovals;
+
+    if (princ_exists(ovals.name, ovals.instance, krbrlm) == PE_NO) {
+       printf("kadmin: Principal does not exist.\n");
+       return;
+    }
+
+    /* get the admin's password */
+    if (get_admin_password() != GOOD_PW)
+       return;
+       
+    if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+       printf("[ unable to retrieve current settings: %s ]\n",
+           error_message(status));
+       nvals.max_life = DEFAULT_TKT_LIFE;
+       nvals.exp_date = 0;
+       nvals.attributes = 0;
+    } else {
+       nvals.max_life = ovals.max_life;
+       nvals.exp_date = ovals.exp_date;
+       nvals.attributes = ovals.attributes;
+    }
+
+    get_maxlife(&nvals);
+    get_attr(&nvals);
+    get_expdate(&nvals);
+    
+    if (IS_FIELD(KADM_MAXLIFE, nvals.fields) || IS_FIELD(KADM_ATTR, nvals.fields) || IS_FIELD(KADM_EXPDATE, nvals.fields)) {
+       if ((status = kadm_mod(&ovals, &nvals)) != KADM_SUCCESS) {
+           printf("kadm error: %s\n",error_message(status));
+           goto out;
+       }
+       if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+           printf("kadm error: %s\n",error_message(status));
+           goto out;
+       }
+    }
+    prin_vals(&ovals);
+
+out:
+    if (!multiple)
+       clean_up();
+    return;
+}
+
+void 
+help(int argc, char **argv)
+{
+    if (argc == 1) {
+       printf("Welcome to the Kerberos administration program.");
+       printf("Type \"?\" to get\n");
+       printf("a list of requests that are available. You can");
+       printf(" get help on each of\n");
+       printf("the commands by typing \"help command_name\".");
+       printf(" Some functions of this\n");
+       printf("program will require an \"admin\" password");
+       printf(" from you. This is a password\n");
+       printf("private to you, that is used to authenticate");
+       printf(" requests from this\n");
+       printf("program. You can change this password with");
+       printf(" the \"change_admin_password\"\n");
+       printf("(or short form \"cap\") command. Good Luck!    \n");
+    } else if (!strcmp(argv[1], "change_password") ||
+              !strcmp(argv[1], "cpw")) {
+       printf("Usage: change_password user_name.\n");
+       printf("\n");
+       printf("user_name is the name of the user whose password");
+       printf(" you wish to change. \n");
+       printf("His/her password is changed in the kerberos database\n");
+       printf("When this command is issued, first the \"Admin\"");
+       printf(" password will be prompted\n");
+       printf("for and if correct the user's new password will");
+       printf(" be prompted for (twice with\n");
+       printf("appropriate comparison). Note: No minimum password");
+       printf(" length restrictions apply, but\n");
+       printf("longer passwords are more secure.\n");
+    } else if (!strcmp(argv[1], "change_admin_password") ||
+              !strcmp(argv[1], "cap")) {
+       printf("Usage: change_admin_password.\n");
+       printf("\n");
+       printf("This command takes no arguments and is used");
+       printf(" to change your private\n");
+       printf("\"Admin\" password. It will first prompt for");
+       printf(" the (current) \"Admin\"\n");
+       printf("password and then ask for the new password");
+       printf(" by prompting:\n");
+       printf("\n");
+       printf("New password for <Your User Name>.admin:\n");
+       printf("\n");
+       printf("Enter the new admin password that you desire");
+       printf(" (it will be asked for\n");
+       printf("twice to avoid errors).\n");
+    } else if (!strcmp(argv[1], "add_new_key") ||
+              !strcmp(argv[1], "ank")) {
+       printf("Usage: add_new_key user_name.\n");
+       printf("\n");
+       printf("user_name is the name of a new user to put");
+       printf(" in the kerberos database. Your\n");
+       printf("\"Admin\" password and the user's password");
+       printf(" are prompted for. The user's\n");
+       printf("password will be asked for");
+       printf(" twice to avoid errors.\n");
+       printf("You are also prompted for the default ticket");
+       printf(" lifetime, attributes\n");
+       printf("and expiration date (see the 'mod_entry' command).\n");
+    } else if (!strcmp(argv[1], "get_entry") ||
+              !strcmp(argv[1], "get")) {
+       printf("Usage: get_entry user_name.\n");
+       printf("\n");
+       printf("user_name is the name of a user whose");
+       printf(" entry you wish to review.  Your\n");
+       printf("\"Admin\" password is prompted for. ");
+       printf(" The key field is not filled in, for\n");
+       printf("security reasons.\n");
+    } else if (!strcmp(argv[1], "mod_entry") ||
+              !strcmp(argv[1], "mod")) {
+       printf("Usage: mod_entry user_name.\n");
+       printf("\n");
+       printf("user_name is the name of a user whose");
+       printf(" entry you wish to modify.  Your\n");
+       printf("\"Admin\" password is prompted for.");
+       printf(" You will also be prompted for the new\n");
+       printf("default ticket lifetime, attributes");
+       printf(" and expiration date. Attributes may\n");
+       printf("be entered in decimal by default,");
+       printf(" octal if begun with '0', or hexadecimal\n");
+       printf("if begun with '0x'. End the lifetime");
+       printf(" with 'm' to specify minutes, 'h'\n");
+       printf("to specify hours.\n");
+    } else if (!strcmp(argv[1], "destroy_tickets") ||
+              !strcmp(argv[1], "dest")) {
+       printf("Usage: destroy_tickets\n");
+       printf("\n");
+       printf("Destroy your admin tickets.  This will");
+       printf(" cause you to be prompted for your\n");
+       printf("admin password on your next request.\n");
+    } else if (!strcmp(argv[1], "list_requests") ||
+              !strcmp(argv[1], "lr") ||
+              !strcmp(argv[1], "?")) {
+       printf("Usage: list_requests\n");
+       printf("\n");
+       printf("This command lists what other commands are");
+       printf(" currently available.\n");
+    } else if (!strcmp(argv[1], "exit") ||
+              !strcmp(argv[1], "quit") ||
+              !strcmp(argv[1], "q")) {
+       printf("Usage: quit\n");
+       printf("\n");
+       printf("This command exits this program.\n");
+    } else {
+       printf("Sorry there is no such command as %s.", argv[1]);
+       printf(" Type \"help\" for more information.    \n");
+    }
+    return;
+}
+#if 0
+static void
+go_home(str,x)
+char *str;
+int x;
+{
+    fprintf(stderr, "%s: %s\n", str, error_message(x));
+    clean_up();
+    exit(1);
+}
+#endif
diff --git a/kerberosIV/kadmin/kadmin_cmds.ct b/kerberosIV/kadmin/kadmin_cmds.ct
new file mode 100644 (file)
index 0000000..af62021
--- /dev/null
@@ -0,0 +1,52 @@
+#      $Id: kadmin_cmds.ct,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $
+
+#-
+# Copyright 1988 by the Massachusetts Institute of Technology.
+#
+# Permission to use, copy, modify, and distribute this software
+# and its documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice
+# appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation,
+# and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+# used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# M.I.T. and the M.I.T. S.I.P.B. make no representations about
+# the suitability of this software for any purpose.  It is
+# provided "as is" without express or implied warranty.
+
+# Command table for Kerberos administration tool
+
+       command_table   admin_cmds;
+
+       request change_password,
+               "Change a user's password",
+               change_password, cpw;
+
+       request change_admin_password, "Change your admin password",
+               change_admin_password, cap;
+
+       request add_new_key, "Add new user to kerberos database",
+               add_new_key, ank;
+
+       request get_entry, "Get entry from kerberos database",
+               get_entry, get;
+
+       request mod_entry, "Modify entry in kerberos database",
+               mod_entry, mod;
+
+       request clean_up, "Destroy admin tickets",
+               destroy_tickets, dest;
+
+       request help,"Request help with this program",
+               help;
+
+# list_requests is generic -- unrelated to Kerberos
+
+       request ss_list_requests, "List available requests.",
+               list_requests, lr, "?";
+
+       request quit, "Exit program.",
+               quit, exit, q;
+
+       end;
diff --git a/kerberosIV/kadmind/Makefile b/kerberosIV/kadmind/Makefile
new file mode 100644 (file)
index 0000000..0d008ee
--- /dev/null
@@ -0,0 +1,25 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $
+
+PROG=   kadmind
+SRCS=   admin_server.c kadm_funcs.c kadm_ser_wrap.c kadm_server.c
+.if exists(${.CURDIR}/../kadm/obj)
+CFLAGS+=-I${.CURDIR}/../kadm/obj
+.else
+CFLAGS+=-I${.CURDIR}/../kadm
+.endif
+.if exists(${.CURDIR}/../krb/obj)
+CFLAGS+=-I${.CURDIR}/../krb/obj
+.else
+CFLAGS+=-I${.CURDIR}/../krb
+.endif
+.if exists(${.CURDIR}/../ss/obj)
+CFLAGS+=-I${.CURDIR}/../ss/obj
+.else
+CFLAGS+=-I${.CURDIR}/../ss
+.endif
+LDADD+=        -lkadm -lkdb -lkrb -ldes -lacl -lcom_err
+DPADD= ${LIBKADM} ${LIBKDB} ${LIBKRB} ${LIBDES} ${LIBACL} ${LIBCOM_ERR}
+MAN=   kadmind.8
+BINDIR=/usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kadmind/admin_server.c b/kerberosIV/kadmind/admin_server.c
new file mode 100644 (file)
index 0000000..d184f92
--- /dev/null
@@ -0,0 +1,448 @@
+/*     $Id: admin_server.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $   */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Top-level loop of the kerberos Administration server
+ */
+
+/*
+  admin_server.c
+  this holds the main loop and initialization and cleanup code for the server
+*/
+
+#include <kadm_locl.h>
+
+/* Almost all procs and such need this, so it is global */
+admin_params prm;              /* The command line parameters struct */
+
+static char prog[32];                  /* WHY IS THIS NEEDED??????? */
+char *progname = prog;
+/* GLOBAL */
+char *acldir = DEFAULT_ACL_DIR;
+static char krbrlm[REALM_SZ];
+
+static unsigned pidarraysize = 0;
+static int *pidarray = (int *)0;
+
+static exit_now = 0;
+
+static void
+doexit()
+{
+    exit_now = 1;
+#ifndef sgi                    /* Sigh -- sgi cc balks at this... */
+    return (void)(0);
+#endif
+}
+   
+static void
+do_child()
+{
+    /* SIGCHLD brings us here */
+    int pid;
+    register int i, j;
+
+    int status;
+
+    pid = wait(&status);
+
+    for (i = 0; i < pidarraysize; i++)
+       if (pidarray[i] == pid) {
+           /* found it */
+           for (j = i; j < pidarraysize-1; j++)
+               /* copy others down */
+               pidarray[j] = pidarray[j+1];
+           pidarraysize--;
+           if (WIFEXITED(status) || WIFSIGNALED(status))
+               log("child %d: termsig %d, retcode %d", pid,
+                   WTERMSIG(status), WEXITSTATUS(status));
+#ifndef sgi
+           return (void)(0);
+#endif
+       }
+    log("child %d not in list: termsig %d, retcode %d", pid,
+       WTERMSIG(status), WEXITSTATUS(status));
+#ifndef sgi
+    return (void)(0);
+#endif
+}
+
+static int nSIGCHLD = 0;
+
+static void
+count_SIGCHLD()
+{
+  nSIGCHLD++;
+#ifndef sgi
+  return (void)(0);
+#endif
+}
+
+static void
+kill_children(void)
+{
+    int i;
+    void (*ofunc)();
+
+    ofunc = signal(SIGCHLD, count_SIGCHLD);
+
+    for (i = 0; i < pidarraysize; i++) {
+       kill(pidarray[i], SIGINT);
+       log("killing child %d", pidarray[i]);
+    }
+
+    (void) signal(SIGCHLD, ofunc);
+    
+    for (; nSIGCHLD != 0; nSIGCHLD--)
+        do_child();
+
+    return;
+}
+
+/* close the system log file */
+static void
+close_syslog(void)
+{
+   log("Shutting down admin server");
+}
+
+static void
+byebye(void)                   /* say goodnight gracie */
+{
+   printf("Admin Server (kadm server) has completed operation.\n");
+}
+
+static void
+clear_secrets(void)
+{
+    bzero((char *)server_parm.master_key, sizeof(server_parm.master_key));
+    bzero((char *)server_parm.master_key_schedule,
+         sizeof(server_parm.master_key_schedule));
+    server_parm.master_key_version = 0L;
+    return;
+}
+
+#ifdef DEBUG
+#define cleanexit(code) {kerb_fini(); return;}
+#endif
+
+#ifndef DEBUG
+static void
+cleanexit(int val)
+{
+    kerb_fini();
+    clear_secrets();
+    exit(val);
+}
+#endif
+
+static void
+process_client(int fd, struct sockaddr_in *who)
+{
+    u_char *dat;
+    int dat_len;
+    u_short dlen;
+    int retval;
+    int on = 1;
+    Principal service;
+    des_cblock skey;
+    int more;
+    int status;
+
+    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
+       log("setsockopt keepalive: %d",errno);
+
+    server_parm.recv_addr = *who;
+
+    if (kerb_init()) {                 /* Open as client */
+       log("can't open krb db");
+       cleanexit(1);
+    }
+    /* need to set service key to changepw.KRB_MASTER */
+
+    status = kerb_get_principal(server_parm.sname, server_parm.sinst, &service,
+                           1, &more);
+    if (status == -1) {
+      /* db locked */
+      u_long retcode = KADM_DB_INUSE;
+      char *pdat;
+      
+      dat_len = KADM_VERSIZE + sizeof(u_long);
+      dat = (u_char *) malloc((unsigned)dat_len);
+      pdat = (char *) dat;
+      retcode = htonl((u_long) KADM_DB_INUSE);
+      (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+      bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_long));
+      goto out;
+    } else if (!status) {
+      log("no service %s.%s",server_parm.sname, server_parm.sinst);
+      cleanexit(2);
+    }
+
+    bcopy((char *)&service.key_low, (char *)skey, 4);
+    bcopy((char *)&service.key_high, (char *)(((long *) skey) + 1), 4);
+    bzero((char *)&service, sizeof(service));
+    kdb_encrypt_key (&skey, &skey, &server_parm.master_key,
+                    server_parm.master_key_schedule, DES_DECRYPT);
+    (void) krb_set_key((char *)skey, 0); /* if error, will show up when
+                                           rd_req fails */
+    bzero((char *)skey, sizeof(skey));
+
+    while (1) {
+       if ((retval = krb_net_read(fd, (char *)&dlen, sizeof(u_short))) !=
+           sizeof(u_short)) {
+           if (retval < 0)
+               log("dlen read: %s",error_message(errno));
+           else if (retval)
+               log("short dlen read: %d",retval);
+           (void) close(fd);
+           cleanexit(retval ? 3 : 0);
+       }
+       if (exit_now) {
+           cleanexit(0);
+       }
+       dat_len = (int) ntohs(dlen);
+       dat = (u_char *) malloc((unsigned)dat_len);
+       if (!dat) {
+           log("malloc: No memory");
+           (void) close(fd);
+           cleanexit(4);
+       }
+       if ((retval = krb_net_read(fd, (char *)dat, dat_len)) != dat_len) {
+           if (retval < 0)
+               log("data read: %s",error_message(errno));
+           else
+               log("short read: %d vs. %d", dat_len, retval);
+           (void) close(fd);
+           cleanexit(5);
+       }
+       if (exit_now) {
+           cleanexit(0);
+       }
+       if ((retval = kadm_ser_in(&dat,&dat_len)) != KADM_SUCCESS)
+           log("processing request: %s", error_message(retval));
+    
+       /* kadm_ser_in did the processing and returned stuff in
+          dat & dat_len , return the appropriate data */
+    
+    out:
+       dlen = (u_short) dat_len;
+
+       if (dat_len != (int)dlen) {
+           clear_secrets();
+           abort();                    /* XXX */
+       }
+       dlen = htons(dlen);
+    
+       if (krb_net_write(fd, (char *)&dlen, sizeof(u_short)) < 0) {
+           log("writing dlen to client: %s",error_message(errno));
+           (void) close(fd);
+           cleanexit(6);
+       }
+    
+       if (krb_net_write(fd, (char *)dat, dat_len) < 0) {
+           log(LOG_ERR, "writing to client: %s",error_message(errno));
+           (void) close(fd);
+           cleanexit(7);
+       }
+       free((char *)dat);
+    }
+    /*NOTREACHED*/
+}
+
+/*
+kadm_listen
+listen on the admin servers port for a request
+*/
+static int
+kadm_listen(void)
+{
+    int found;
+    int admin_fd;
+    int peer_fd;
+    fd_set mask, readfds;
+    struct sockaddr_in peer;
+    int addrlen;
+    int pid;
+
+    (void) signal(SIGINT, doexit);
+    (void) signal(SIGTERM, doexit);
+    (void) signal(SIGHUP, doexit);
+    (void) signal(SIGQUIT, doexit);
+    (void) signal(SIGPIPE, SIG_IGN); /* get errors on write() */
+    (void) signal(SIGALRM, doexit);
+    (void) signal(SIGCHLD, do_child);
+
+    if ((admin_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+       return KADM_NO_SOCK;
+    if (bind(admin_fd, (struct sockaddr *)&server_parm.admin_addr,
+            sizeof(struct sockaddr_in)) < 0)
+       return KADM_NO_BIND;
+    (void) listen(admin_fd, 1);
+    FD_ZERO(&mask);
+    FD_SET(admin_fd, &mask);
+
+    for (;;) {                         /* loop nearly forever */
+       if (exit_now) {
+           clear_secrets();
+           kill_children();
+           return(0);
+       }
+       readfds = mask;
+       if ((found = select(admin_fd+1,&readfds,(fd_set *)0,
+                           (fd_set *)0, (struct timeval *)0)) == 0)
+           continue;                   /* no things read */
+       if (found < 0) {
+           if (errno != EINTR)
+               log("select: %s",error_message(errno));
+           continue;
+       }      
+       if (FD_ISSET(admin_fd, &readfds)) {
+           /* accept the conn */
+           addrlen = sizeof(peer);
+           if ((peer_fd = accept(admin_fd, (struct sockaddr *)&peer,
+                                 &addrlen)) < 0) {
+               log("accept: %s",error_message(errno));
+               continue;
+           }
+#ifndef DEBUG
+           /* if you want a sep daemon for each server */
+           if ((pid = fork())) {
+               /* parent */
+               if (pid < 0) {
+                   log("fork: %s",error_message(errno));
+                   (void) close(peer_fd);
+                   continue;
+               }
+               /* fork succeded: keep tabs on child */
+               (void) close(peer_fd);
+               if (pidarray) {
+                   pidarray = (int *)realloc((char *)pidarray, ++pidarraysize);
+                   pidarray[pidarraysize-1] = pid;
+               } else {
+                   pidarray = (int *)malloc(pidarraysize = 1);
+                   pidarray[0] = pid;
+               }
+           } else {
+               /* child */
+               (void) close(admin_fd);
+#endif /* DEBUG */
+               /* do stuff */
+               process_client (peer_fd, &peer);
+#ifndef DEBUG
+           }
+#endif
+       } else {
+           log("something else woke me up!");
+           return(0);
+       }
+    }
+    /*NOTREACHED*/
+}
+
+/*
+** Main does the logical thing, it sets up the database and RPC interface,
+**  as well as handling the creation and maintenance of the syslog file...
+*/
+int
+main(int argc, char **argv)            /* admin_server main routine */
+         
+             
+{
+    int errval;
+    int c;
+
+    prog[sizeof(prog)-1]='\0';         /* Terminate... */
+    (void) strncpy(prog, argv[0], sizeof(prog)-1);
+
+    /* initialize the admin_params structure */
+    prm.sysfile = KADM_SYSLOG;         /* default file name */
+    prm.inter = 1;
+
+    bzero(krbrlm, sizeof(krbrlm));
+
+    while ((c = getopt(argc, argv, "f:hnd:a:r:")) != EOF)
+       switch(c) {
+       case 'f':                       /* Syslog file name change */
+           prm.sysfile = optarg;
+           break;
+       case 'n':
+           prm.inter = 0;
+           break;
+       case 'a':                       /* new acl directory */
+           acldir = optarg;
+           break;
+       case 'd':
+           /* put code to deal with alt database place */
+           if ((errval = kerb_db_set_name(optarg))) {
+               fprintf(stderr, "opening database %s: %s",
+                       optarg, error_message(errval));
+               exit(1);
+           }
+           break;
+       case 'r':
+           (void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1);
+           break;
+       case 'h':                       /* get help on using admin_server */
+       default:
+           printf("Usage: admin_server [-h] [-n] [-r realm] [-d dbname] [-f filename] [-a acldir]\n");
+           exit(-1);                   /* failure */
+       }
+
+    if (krbrlm[0] == 0)
+       if (krb_get_lrealm(krbrlm, 0) != KSUCCESS) {
+           fprintf(stderr, 
+                   "Unable to get local realm.  Fix krb.conf or use -r.\n");
+           exit(1);
+       }
+
+    printf("KADM Server %s initializing\n",KADM_VERSTR);
+    printf("Please do not use 'kill -9' to kill this job, use a\n");
+    printf("regular kill instead\n\n");
+
+    set_logfile(prm.sysfile);
+    log("Admin server starting");
+
+    (void) kerb_db_set_lockmode(KERB_DBL_NONBLOCKING);
+    errval = kerb_init();              /* Open the Kerberos database */
+    if (errval) {
+       fprintf(stderr, "error: kerb_init() failed");
+       close_syslog();
+       byebye();
+    }
+    /* set up the server_parm struct */
+    if ((errval = kadm_ser_init(prm.inter, krbrlm))==KADM_SUCCESS) {
+       kerb_fini();                    /* Close the Kerberos database--
+                                          will re-open later */
+       errval = kadm_listen();         /* listen for calls to server from
+                                          clients */
+    }
+    if (errval != KADM_SUCCESS) {
+       fprintf(stderr,"error:  %s\n",error_message(errval));
+       kerb_fini();                    /* Close if error */
+    }
+    close_syslog();                    /* Close syslog file, print
+                                          closing note */
+    byebye();                          /* Say bye bye on the terminal
+                                          in use */
+    exit(1);
+}                                      /* procedure main */
diff --git a/kerberosIV/kadmind/kadm_funcs.c b/kerberosIV/kadmind/kadm_funcs.c
new file mode 100644 (file)
index 0000000..5bed94d
--- /dev/null
@@ -0,0 +1,371 @@
+/*     $Id: kadm_funcs.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $     */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Kerberos administration server-side database manipulation routines
+ */
+
+/*
+kadm_funcs.c
+the actual database manipulation code
+*/
+
+#include <kadm_locl.h>
+#include <sys/param.h>
+
+static int
+check_access(char *pname, char *pinst, char *prealm, enum acl_types acltype)
+{
+    char checkname[MAX_K_NAME_SZ];
+    char filename[MAXPATHLEN];
+
+    (void) sprintf(checkname, "%s.%s@%s", pname, pinst, prealm);
+    
+    switch (acltype) {
+    case ADDACL:
+       (void) sprintf(filename, "%s%s", acldir, ADD_ACL_FILE);
+       break;
+    case GETACL:
+       (void) sprintf(filename, "%s%s", acldir, GET_ACL_FILE);
+       break;
+    case MODACL:
+       (void) sprintf(filename, "%s%s", acldir, MOD_ACL_FILE);
+       break;
+    }
+    return(acl_check(filename, checkname));
+}
+
+static int
+wildcard(char *str)
+{
+    if (!strcmp(str, WILDCARD_STR))
+       return(1);
+    return(0);
+}
+
+#define failadd(code) {  (void) log("FAILED addding '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; }
+
+int
+kadm_add_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin, Kadm_vals *valsout)
+                                       /* requestors name */
+                                       /* requestors instance */
+                                       /* requestors realm */
+                  
+                   
+{
+  long numfound;               /* check how many we get written */
+  int more;                    /* pointer to more grabbed records */
+  Principal data_i, data_o;            /* temporary principal */
+  u_char flags[4];
+  des_cblock newpw;
+  Principal default_princ;
+
+  if (!check_access(rname, rinstance, rrealm, ADDACL)) {
+    (void) log("WARNING: '%s.%s@%s' tried to add an entry for '%s.%s'",
+              rname, rinstance, rrealm, valsin->name, valsin->instance);
+    return KADM_UNAUTH;
+  }
+  
+  /* Need to check here for "legal" name and instance */
+  if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+      failadd(KADM_ILL_WILDCARD);
+  }
+
+  (void) log("request to add an entry for '%s.%s' from '%s.%s@%s'",
+                valsin->name, valsin->instance, rname, rinstance, rrealm);
+  
+  numfound = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+                               &default_princ, 1, &more);
+  if (numfound == -1) {
+      failadd(KADM_DB_INUSE);
+  } else if (numfound != 1) {
+      failadd(KADM_UK_RERROR);
+  }
+
+  kadm_vals_to_prin(valsin->fields, &data_i, valsin);
+  (void) strncpy(data_i.name, valsin->name, ANAME_SZ);
+  (void) strncpy(data_i.instance, valsin->instance, INST_SZ);
+
+  if (!IS_FIELD(KADM_EXPDATE,valsin->fields))
+         data_i.exp_date = default_princ.exp_date;
+  if (!IS_FIELD(KADM_ATTR,valsin->fields))
+      data_i.attributes = default_princ.attributes;
+  if (!IS_FIELD(KADM_MAXLIFE,valsin->fields))
+      data_i.max_life = default_princ.max_life; 
+
+  bzero((char *)&default_princ, sizeof(default_princ));
+
+  /* convert to host order */
+  data_i.key_low = ntohl(data_i.key_low);
+  data_i.key_high = ntohl(data_i.key_high);
+
+
+  bcopy(&data_i.key_low,newpw,4);
+  bcopy(&data_i.key_high,(char *)(((long *) newpw) + 1),4);
+
+  /* encrypt new key in master key */
+  kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key,
+                    server_parm.master_key_schedule, DES_ENCRYPT);
+  bcopy(newpw,&data_i.key_low,4);
+  bcopy((char *)(((long *) newpw) + 1), &data_i.key_high,4);
+  bzero((char *)newpw, sizeof(newpw));
+
+  data_o = data_i;
+  numfound = kerb_get_principal(valsin->name, valsin->instance, 
+                               &data_o, 1, &more);
+  if (numfound == -1) {
+      failadd(KADM_DB_INUSE);
+  } else if (numfound) {
+      failadd(KADM_INUSE);
+  } else {
+    data_i.key_version++;
+    data_i.kdc_key_ver = server_parm.master_key_version;
+    (void) strncpy(data_i.mod_name, rname, sizeof(data_i.mod_name)-1);
+    (void) strncpy(data_i.mod_instance, rinstance,
+                  sizeof(data_i.mod_instance)-1);
+
+    numfound = kerb_put_principal(&data_i, 1);
+    if (numfound == -1) {
+       failadd(KADM_DB_INUSE);
+    } else if (numfound) {
+       failadd(KADM_UK_SERROR);
+    } else {
+      numfound = kerb_get_principal(valsin->name, valsin->instance, 
+                                   &data_o, 1, &more);
+      if ((numfound!=1) || (more!=0)) {
+         failadd(KADM_UK_RERROR);
+      }
+      bzero((char *)flags, sizeof(flags));
+      SET_FIELD(KADM_NAME,flags);
+      SET_FIELD(KADM_INST,flags);
+      SET_FIELD(KADM_EXPDATE,flags);
+      SET_FIELD(KADM_ATTR,flags);
+      SET_FIELD(KADM_MAXLIFE,flags);
+      kadm_prin_to_vals(flags, valsout, &data_o);
+      (void) log("'%s.%s' added.", valsin->name, valsin->instance);
+      return KADM_DATA;                /* Set all the appropriate fields */
+    }
+  }
+}
+#undef failadd
+
+#define failget(code) {  (void) log("FAILED retrieving '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; }
+
+int
+kadm_get_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin, u_char *flags, Kadm_vals *valsout)
+                                       /* requestors name */
+                                       /* requestors instance */
+                                       /* requestors realm */
+                                       /* what they wannt to get */
+                                       /* which fields we want */
+                                       /* what data is there */
+{
+  long numfound;               /* check how many were returned */
+  int more;                    /* To point to more name.instances */
+  Principal data_o;            /* Data object to hold Principal */
+
+  
+  if (!check_access(rname, rinstance, rrealm, GETACL)) {
+    (void) log("WARNING: '%s.%s@%s' tried to get '%s.%s's entry",
+           rname, rinstance, rrealm, valsin->name, valsin->instance);
+    return KADM_UNAUTH;
+  }
+  
+  if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+      failget(KADM_ILL_WILDCARD);
+  }
+
+  (void) log("retrieve '%s.%s's entry for '%s.%s@%s'",
+            valsin->name, valsin->instance, rname, rinstance, rrealm);
+  
+  /* Look up the record in the database */
+  numfound = kerb_get_principal(valsin->name, valsin->instance, 
+                               &data_o, 1, &more);
+  if (numfound == -1) {
+      failget(KADM_DB_INUSE);
+  }  else if (numfound) {      /* We got the record, let's return it */
+    kadm_prin_to_vals(flags, valsout, &data_o);
+    (void) log("'%s.%s' retrieved.", valsin->name, valsin->instance);
+    return KADM_DATA;          /* Set all the appropriate fields */
+  } else {
+      failget(KADM_NOENTRY);   /* Else whimper and moan */
+  }
+}
+#undef failget
+
+#define failmod(code) {  (void) log("FAILED modifying '%s.%s' (%s)", valsin1->name, valsin1->instance, error_message(code)); return code; }
+
+int
+kadm_mod_entry (char *rname, char *rinstance, char *rrealm, Kadm_vals *valsin1, Kadm_vals *valsin2, Kadm_vals *valsout)
+                                       /* requestors name */
+                                       /* requestors instance */
+                                       /* requestors realm */
+                                       /* holds the parameters being
+                                          passed in */
+                               /* the actual record which is returned */
+{
+  long numfound;
+  int more;
+  Principal data_o, temp_key;
+  u_char fields[4];
+  des_cblock newpw;
+
+  if (wildcard(valsin1->name) || wildcard(valsin1->instance)) {
+      failmod(KADM_ILL_WILDCARD);
+  }
+  
+  if (!check_access(rname, rinstance, rrealm, MODACL)) {
+    (void) log("WARNING: '%s.%s@%s' tried to change '%s.%s's entry",
+              rname, rinstance, rrealm, valsin1->name, valsin1->instance);
+    return KADM_UNAUTH;
+  }
+  
+  (void) log("request to modify '%s.%s's entry from '%s.%s@%s' ",
+            valsin1->name, valsin1->instance, rname, rinstance, rrealm);
+  
+  numfound = kerb_get_principal(valsin1->name, valsin1->instance, 
+                               &data_o, 1, &more);
+  if (numfound == -1) {
+      failmod(KADM_DB_INUSE);
+  } else if (numfound) {
+      kadm_vals_to_prin(valsin2->fields, &temp_key, valsin2);
+      (void) strncpy(data_o.name, valsin1->name, ANAME_SZ);
+      (void) strncpy(data_o.instance, valsin1->instance, INST_SZ);
+      if (IS_FIELD(KADM_EXPDATE,valsin2->fields))
+         data_o.exp_date = temp_key.exp_date;
+      if (IS_FIELD(KADM_ATTR,valsin2->fields))
+         data_o.attributes = temp_key.attributes;
+      if (IS_FIELD(KADM_MAXLIFE,valsin2->fields))
+         data_o.max_life = temp_key.max_life; 
+      if (IS_FIELD(KADM_DESKEY,valsin2->fields)) {
+         data_o.key_version++;
+         data_o.kdc_key_ver = server_parm.master_key_version;
+
+
+         /* convert to host order */
+         temp_key.key_low = ntohl(temp_key.key_low);
+         temp_key.key_high = ntohl(temp_key.key_high);
+
+
+         bcopy(&temp_key.key_low,newpw,4);
+         bcopy(&temp_key.key_high,(char *)(((long *) newpw) + 1),4);
+
+         /* encrypt new key in master key */
+         kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key,
+                          server_parm.master_key_schedule, DES_ENCRYPT);
+         bcopy(newpw,&data_o.key_low,4);
+         bcopy((char *)(((long *) newpw) + 1), &data_o.key_high,4);
+         bzero((char *)newpw, sizeof(newpw));
+      }
+      bzero((char *)&temp_key, sizeof(temp_key));
+
+      (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+      (void) strncpy(data_o.mod_instance, rinstance,
+                    sizeof(data_o.mod_instance)-1);
+      more = kerb_put_principal(&data_o, 1);
+
+      bzero((char *)&data_o, sizeof(data_o));
+
+      if (more == -1) {
+         failmod(KADM_DB_INUSE);
+      } else if (more) {
+         failmod(KADM_UK_SERROR);
+      } else {
+         numfound = kerb_get_principal(valsin1->name, valsin1->instance, 
+                                       &data_o, 1, &more);
+         if ((more!=0)||(numfound!=1)) {
+             failmod(KADM_UK_RERROR);
+         }
+         bzero((char *) fields, sizeof(fields));
+         SET_FIELD(KADM_NAME,fields);
+         SET_FIELD(KADM_INST,fields);
+         SET_FIELD(KADM_EXPDATE,fields);
+         SET_FIELD(KADM_ATTR,fields);
+         SET_FIELD(KADM_MAXLIFE,fields);
+         kadm_prin_to_vals(fields, valsout, &data_o);
+         (void) log("'%s.%s' modified.", valsin1->name, valsin1->instance);
+         return KADM_DATA;             /* Set all the appropriate fields */
+      }
+  }
+  else {
+      failmod(KADM_NOENTRY);
+  }
+}
+#undef failmod
+
+#define failchange(code) {  (void) log("FAILED changing key for '%s.%s@%s' (%s)", rname, rinstance, rrealm, error_message(code)); return code; }
+
+int
+kadm_change (char *rname, char *rinstance, char *rrealm, unsigned char *newpw)
+{
+  long numfound;
+  int more;
+  Principal data_o;
+  des_cblock local_pw;
+
+  if (strcmp(server_parm.krbrlm, rrealm)) {
+      (void) log("change key request from wrong realm, '%s.%s@%s'!\n",
+                rname, rinstance, rrealm);
+      return(KADM_WRONG_REALM);
+  }
+
+  if (wildcard(rname) || wildcard(rinstance)) {
+      failchange(KADM_ILL_WILDCARD);
+  }
+  (void) log("'%s.%s@%s' wants to change its password",
+            rname, rinstance, rrealm);
+  
+  bcopy(newpw, local_pw, sizeof(local_pw));
+  
+  /* encrypt new key in master key */
+  kdb_encrypt_key (&local_pw, &local_pw, &server_parm.master_key,
+                    server_parm.master_key_schedule, DES_ENCRYPT);
+
+  numfound = kerb_get_principal(rname, rinstance, 
+                               &data_o, 1, &more);
+  if (numfound == -1) {
+      failchange(KADM_DB_INUSE);
+  } else if (numfound) {
+    bcopy(local_pw,&data_o.key_low,4);
+    bcopy((char *)(((long *) local_pw) + 1), &data_o.key_high,4);
+    data_o.key_version++;
+    data_o.kdc_key_ver = server_parm.master_key_version;
+    (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+    (void) strncpy(data_o.mod_instance, rinstance,
+                  sizeof(data_o.mod_instance)-1);
+    more = kerb_put_principal(&data_o, 1);
+    bzero((char *) local_pw, sizeof(local_pw));
+    bzero((char *) &data_o, sizeof(data_o));
+    if (more == -1) {
+       failchange(KADM_DB_INUSE);
+    } else if (more) {
+       failchange(KADM_UK_SERROR);
+    } else {
+       (void) log("'%s.%s@%s' password changed.", rname, rinstance, rrealm);
+       return KADM_SUCCESS;
+    }
+  }
+  else {
+      failchange(KADM_NOENTRY);
+  }
+}
+#undef failchange
diff --git a/kerberosIV/kadmind/kadm_ser_wrap.c b/kerberosIV/kadmind/kadm_ser_wrap.c
new file mode 100644 (file)
index 0000000..6243041
--- /dev/null
@@ -0,0 +1,210 @@
+/*     $Id: kadm_ser_wrap.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $  */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Kerberos administration server-side support functions
+ */
+
+/* 
+kadm_ser_wrap.c
+unwraps wrapped packets and calls the appropriate server subroutine
+*/
+
+#include <kadm_locl.h>
+#include <sys/param.h>
+
+/* GLOBAL */
+Kadm_Server server_parm;
+
+/* 
+kadm_ser_init
+set up the server_parm structure
+*/
+int
+kadm_ser_init(int inter, char *realm)
+                               /* interactive or from file */
+             
+{
+  struct servent *sep;
+  struct hostent *hp;
+  char hostname[MAXHOSTNAMELEN];
+
+  (void) init_kadm_err_tbl();
+  (void) init_krb_err_tbl();
+  if (gethostname(hostname, sizeof(hostname)))
+      return KADM_NO_HOSTNAME;
+
+  (void) strcpy(server_parm.sname, PWSERV_NAME);
+  (void) strcpy(server_parm.sinst, KRB_MASTER);
+  (void) strcpy(server_parm.krbrlm, realm);
+
+  server_parm.admin_fd = -1;
+                               /* setting up the addrs */
+  if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
+    return KADM_NO_SERV;
+  bzero((char *)&server_parm.admin_addr,sizeof(server_parm.admin_addr));
+  server_parm.admin_addr.sin_family = AF_INET;
+  if ((hp = gethostbyname(hostname)) == NULL)
+      return KADM_NO_HOSTNAME;
+  bcopy(hp->h_addr, (char *) &server_parm.admin_addr.sin_addr.s_addr,
+       hp->h_length);
+  server_parm.admin_addr.sin_port = sep->s_port;
+                               /* setting up the database */
+  if (kdb_get_master_key((inter==1), &server_parm.master_key,
+                        server_parm.master_key_schedule) != 0)
+    return KADM_NO_MAST;
+  if ((server_parm.master_key_version =
+       kdb_verify_master_key(&server_parm.master_key,
+                            server_parm.master_key_schedule,stderr))<0)
+      return KADM_NO_VERI;
+  return KADM_SUCCESS;
+}
+
+static void errpkt(u_char **dat, int *dat_len, int code)
+{
+    u_int32_t retcode;
+    char *pdat;
+
+    free((char *)*dat);                        /* free up req */
+    *dat_len = KADM_VERSIZE + sizeof(u_int32_t);
+    *dat = (u_char *) malloc((unsigned)*dat_len);
+    pdat = (char *) *dat;
+    retcode = htonl((u_int32_t) code);
+    (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+    bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_int32_t));
+    return;
+}
+
+/*
+kadm_ser_in
+unwrap the data stored in dat, process, and return it.
+*/
+int
+kadm_ser_in(u_char **dat, int *dat_len)
+{
+    u_char *in_st;                     /* pointer into the sent packet */
+    int in_len,retc;                   /* where in packet we are, for
+                                          returns */
+    u_int32_t r_len;                   /* length of the actual packet */
+    KTEXT_ST authent;                  /* the authenticator */
+    AUTH_DAT ad;                       /* who is this, klink */
+    u_int32_t ncksum;                  /* checksum of encrypted data */
+    des_key_schedule sess_sched;       /* our schedule */
+    MSG_DAT msg_st;
+    u_char *retdat, *tmpdat;
+    int retval, retlen;
+
+    if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) {
+       errpkt(dat, dat_len, KADM_BAD_VER);
+       return KADM_BAD_VER;
+    }
+    in_len = KADM_VERSIZE;
+    /* get the length */
+    if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0)
+       return KADM_LENGTH_ERROR;
+    in_len += retc;
+    authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(u_int32_t);
+    bcopy((char *)(*dat) + in_len, (char *)authent.dat, authent.length);
+    authent.mbz = 0;
+    /* service key should be set before here */
+    if ((retc = krb_rd_req(&authent, server_parm.sname, server_parm.sinst,
+                         server_parm.recv_addr.sin_addr.s_addr, &ad, (char *)0)))
+    {
+       errpkt(dat, dat_len,retc + krb_err_base);
+       return retc + krb_err_base;
+    }
+
+#define clr_cli_secrets() {bzero((char *)sess_sched, sizeof(sess_sched)); bzero((char *)ad.session, sizeof(ad.session));}
+
+    in_st = *dat + *dat_len - r_len;
+#ifdef NOENCRYPTION
+    ncksum = 0;
+#else
+    ncksum = des_quad_cksum((des_cblock *)in_st, (des_cblock *)0, (long) r_len, 0, &ad.session);
+#endif
+    if (ncksum!=ad.checksum) {         /* yow, are we correct yet */
+       clr_cli_secrets();
+       errpkt(dat, dat_len,KADM_BAD_CHK);
+       return KADM_BAD_CHK;
+    }
+#ifdef NOENCRYPTION
+    bzero(sess_sched, sizeof(sess_sched));
+#else
+    des_key_sched(&ad.session, sess_sched);
+#endif
+    if ((retc = (int) krb_rd_priv(in_st, r_len, sess_sched, &ad.session, 
+                                &server_parm.recv_addr,
+                                &server_parm.admin_addr, &msg_st))) {
+       clr_cli_secrets();
+       errpkt(dat, dat_len,retc + krb_err_base);
+       return retc + krb_err_base;
+    }
+    switch (msg_st.app_data[0]) {
+    case CHANGE_PW:
+       retval = kadm_ser_cpw(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+                             &retdat, &retlen);
+       break;
+    case ADD_ENT:
+       retval = kadm_ser_add(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+                             &retdat, &retlen);
+       break;
+    case GET_ENT:
+       retval = kadm_ser_get(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+                             &retdat, &retlen);
+       break;
+    case MOD_ENT:
+       retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+                             &retdat, &retlen);
+       break;
+    default:
+       clr_cli_secrets();
+       errpkt(dat, dat_len, KADM_NO_OPCODE);
+       return KADM_NO_OPCODE;
+    }
+    /* Now seal the response back into a priv msg */
+    free((char *)*dat);
+    tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE +
+                                         sizeof(u_int32_t)));
+    (void) strncpy((char *)tmpdat, KADM_VERSTR, KADM_VERSIZE);
+    retval = htonl((u_int32_t)retval);
+    bcopy((char *)&retval, (char *)tmpdat + KADM_VERSIZE, sizeof(u_int32_t));
+    if (retlen) {
+       bcopy((char *)retdat, (char *)tmpdat + KADM_VERSIZE + sizeof(u_int32_t),
+             retlen);
+       free((char *)retdat);
+    }
+    /* slop for mk_priv stuff */
+    *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE +
+                                        sizeof(u_int32_t) + 200));
+    if ((*dat_len = krb_mk_priv(tmpdat, *dat,
+                               (u_int32_t) (retlen + KADM_VERSIZE +
+                                         sizeof(u_int32_t)),
+                               sess_sched,
+                               &ad.session, &server_parm.admin_addr,
+                               &server_parm.recv_addr)) < 0) {
+       clr_cli_secrets();
+       errpkt(dat, dat_len, KADM_NO_ENCRYPT);
+       return KADM_NO_ENCRYPT;
+    }
+    clr_cli_secrets();
+    return KADM_SUCCESS;
+}
diff --git a/kerberosIV/kadmind/kadm_server.c b/kerberosIV/kadmind/kadm_server.c
new file mode 100644 (file)
index 0000000..1f15820
--- /dev/null
@@ -0,0 +1,154 @@
+/*     $Id: kadm_server.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $    */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Kerberos administration server-side subroutines
+ */
+
+#include <kadm_locl.h>
+
+/* 
+kadm_ser_cpw - the server side of the change_password routine
+  recieves    : KTEXT, {key}
+  returns     : CKSUM, RETCODE
+  acl         : caller can change only own password
+
+Replaces the password (i.e. des key) of the caller with that specified in key.
+Returns no actual data from the master server, since this is called by a user
+*/
+int
+kadm_ser_cpw(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+    u_int32_t keylow, keyhigh;
+    des_cblock newkey;
+    int stvlen;
+
+    /* take key off the stream, and change the database */
+
+    if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0)
+       return(KADM_LENGTH_ERROR);
+    if (stv_long(dat, &keylow, stvlen, len) < 0)
+       return(KADM_LENGTH_ERROR);
+
+    keylow = ntohl(keylow);
+    keyhigh = ntohl(keyhigh);
+    bcopy((char *)&keyhigh, (char *)(((int32_t *)newkey) + 1), 4);
+    bcopy((char *)&keylow, (char *)newkey, 4);
+    *datout = 0;
+    *outlen = 0;
+
+    return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
+}
+
+/*
+kadm_ser_add - the server side of the add_entry routine
+  recieves    : KTEXT, {values}
+  returns     : CKSUM, RETCODE, {values}
+  acl         : su, sms (as alloc)
+
+Adds and entry containing values to the database
+returns the values of the entry, so if you leave certain fields blank you will
+   be able to determine the default values they are set to
+*/
+int
+kadm_ser_add(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+  Kadm_vals values, retvals;
+  long status;
+
+  if ((status = stream_to_vals(dat, &values, len)) < 0)
+      return(KADM_LENGTH_ERROR);
+  if ((status = kadm_add_entry(ad->pname, ad->pinst, ad->prealm,
+                             &values, &retvals)) == KADM_DATA) {
+      *outlen = vals_to_stream(&retvals,datout);
+      return KADM_SUCCESS;
+  } else {
+      *outlen = 0;
+      return status;
+  }
+}
+
+/*
+kadm_ser_mod - the server side of the mod_entry routine
+  recieves    : KTEXT, {values, values}
+  returns     : CKSUM, RETCODE, {values}
+  acl         : su, sms (as register or dealloc)
+
+Modifies all entries corresponding to the first values so they match the
+   second values.
+returns the values for the changed entries
+*/
+int
+kadm_ser_mod(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+  Kadm_vals vals1, vals2, retvals;
+  int wh;
+  long status;
+
+  if ((wh = stream_to_vals(dat, &vals1, len)) < 0)
+      return KADM_LENGTH_ERROR;
+  if ((status = stream_to_vals(dat+wh,&vals2, len-wh)) < 0)
+      return KADM_LENGTH_ERROR;
+  if ((status = kadm_mod_entry(ad->pname, ad->pinst, ad->prealm, &vals1,
+                              &vals2, &retvals)) == KADM_DATA) {
+      *outlen = vals_to_stream(&retvals,datout);
+      return KADM_SUCCESS;
+  } else {
+      *outlen = 0;
+      return status;
+  }
+}
+
+/*
+kadm_ser_get
+  recieves   : KTEXT, {values, flags}
+  returns    : CKSUM, RETCODE, {count, values, values, values}
+  acl        : su
+
+gets the fields requested by flags from all entries matching values
+returns this data for each matching recipient, after a count of how many such
+  matches there were
+*/
+int
+kadm_ser_get(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+  Kadm_vals values, retvals;
+  u_char fl[FLDSZ];
+  int loop,wh;
+  long status;
+
+  if ((wh = stream_to_vals(dat, &values, len)) < 0)
+      return KADM_LENGTH_ERROR;
+  if (wh + FLDSZ > len)
+      return KADM_LENGTH_ERROR;
+  for (loop=FLDSZ-1; loop>=0; loop--)
+    fl[loop] = dat[wh++];
+  if ((status = kadm_get_entry(ad->pname, ad->pinst, ad->prealm,
+                             &values, fl, &retvals)) == KADM_DATA) {
+      *outlen = vals_to_stream(&retvals,datout);
+      return KADM_SUCCESS;
+  } else {
+      *outlen = 0;
+      return status;
+  }
+}
+
diff --git a/kerberosIV/kadmind/kadmind.8 b/kerberosIV/kadmind/kadmind.8
new file mode 100644 (file)
index 0000000..88f4e7e
--- /dev/null
@@ -0,0 +1,126 @@
+.\" Copyright 1987, 1988, 1989 by the Student Information Processing Board
+.\"    of the Massachusetts Institute of Technology
+.\" 
+.\" Permission to use, copy, modify, and distribute this software
+.\" and its documentation for any purpose and without fee is
+.\" hereby granted, provided that the above copyright notice
+.\" appear in all copies and that both that copyright notice and
+.\" this permission notice appear in supporting documentation,
+.\" and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+.\" used in advertising or publicity pertaining to distribution
+.\" of the software without specific, written prior permission.
+.\" M.I.T. and the M.I.T. S.I.P.B. make no representations about
+.\" the suitability of this software for any purpose.  It is
+.\" provided "as is" without express or implied warranty.
+.\" 
+.\"    $Id: kadmind.8,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $
+.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmind \- Kerberos database administration daemon
+.SH SYNOPSIS
+.B kadmind
+[
+.B \-n
+] [
+.B \-h
+] [
+.B \-r realm
+] [
+.B \-f filename
+] [
+.B \-d dbname
+] [
+.B \-a acldir
+]
+.SH DESCRIPTION
+.I kadmind
+is the network database server for the Kerberos password-changing and
+administration tools.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.
+.PP
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+If the
+.B \-r
+.I realm
+option is specified, the admin server will pretend that its
+local realm is 
+.I realm
+instead of the actual local realm of the host it is running on.
+This makes it possible to run a server for a foreign kerberos
+realm.
+.PP
+If the
+.B \-f
+.I filename
+option is specified, then that file is used to hold the log information
+instead of the default.
+.PP
+If the
+.B \-d
+.I dbname
+option is specified, then that file is used as the database name instead
+of the default.
+.PP
+If the
+.B \-a
+.I acldir
+option is specified, then
+.I acldir
+is used as the directory in which to search for access control lists
+instead of the default.
+.PP
+If the
+.B \-h
+option is specified,
+.I kadmind
+prints out a short summary of the permissible control arguments, and
+then exits.
+.PP
+When performing requests on behalf of clients,
+.I kadmind
+checks access control lists (ACLs) to determine the authorization of the client
+to perform the requested action.
+Currently three distinct access types are supported:
+.TP 1i
+Addition
+(.add ACL file).  If a principal is on this list, it may add new
+principals to the database.
+.TP
+Retrieval
+(.get ACL file).  If a principal is on this list, it may retrieve
+database entries.  NOTE:  A principal's private key is never returned by
+the get functions.
+.TP
+Modification
+(.mod ACL file).  If a principal is on this list, it may modify entries
+in the database.
+.PP
+A principal is always granted authorization to change its own password.
+.SH FILES
+.TP 20n
+/kerberos/admin_server.syslog
+Default log file.
+.TP 
+/kerberos
+Default access control list directory.
+.TP
+admin_acl.{add,get,mod}
+Access control list files (within the directory)
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+Default DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH "SEE ALSO"
+kerberos(1), kpasswd(1), kadmin(8), acl_check(3)
+.SH AUTHORS
+Douglas A. Church, MIT Project Athena
+.br
+John T. Kohl, Project Athena/Digital Equipment Corporation
diff --git a/kerberosIV/kafs/Makefile b/kerberosIV/kafs/Makefile
new file mode 100644 (file)
index 0000000..3a7a911
--- /dev/null
@@ -0,0 +1,6 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $
+
+LIB=   kafs
+SRCS=  afssys.c
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/kafs/afssys.c b/kerberosIV/kafs/afssys.c
new file mode 100644 (file)
index 0000000..546b6cd
--- /dev/null
@@ -0,0 +1,300 @@
+/*     $Id: afssys.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#include <kerberosIV/krb.h>
+#include <kerberosIV/kafs.h>
+
+#include "afssysdefs.h"
+
+#define AUTH_SUPERUSER "afs"
+
+/*
+ * Here only ASCII characters are relevant.
+ */
+
+#define IsAsciiUpper(c) ('A' <= (c) && (c) <= 'Z')
+
+#define ToAsciiLower(c) ((c) - 'A' + 'a')
+
+static void
+folddown(a, b)
+     char *a, *b;
+{
+  for (; *b; a++, b++)
+    if (IsAsciiUpper(*b))
+      *a = ToAsciiLower(*b);
+    else
+      *a = *b;
+  *a = '\0';
+}
+
+#if !defined(linux)            /* won't work there -- no SIGSYS, no syscall */
+
+int
+k_afsklog(realm)
+       char *realm;
+{
+  int k_errno;
+  CREDENTIALS c;
+  KTEXT_ST ticket;
+  char username[256];
+  char krealm[REALM_SZ];
+
+  if (!k_hasafs())
+    return KSUCCESS;
+
+  if (realm == 0 || realm[0] == 0)
+    {
+      k_errno = krb_get_lrealm(krealm, 0);
+      if (k_errno != KSUCCESS)
+       return k_errno;
+      realm = krealm;
+    }
+
+  k_errno = krb_get_cred(AUTH_SUPERUSER, "", realm, &c);
+  if (k_errno != KSUCCESS)
+    {
+      k_errno = krb_mk_req(&ticket, AUTH_SUPERUSER, "", realm, 0);
+      if (k_errno == KSUCCESS)
+       k_errno = krb_get_cred(AUTH_SUPERUSER, "", realm, &c);
+    }
+
+  if (k_errno == KSUCCESS)
+    {
+      char cell[256];
+      struct ViceIoctl parms;
+      struct ClearToken ct;
+      int32_t sizeof_x;
+      char buf[2048], *t;
+
+      folddown(cell, realm);
+
+      /*
+       * Build a struct ClearToken
+       */
+      ct.AuthHandle = c.kvno;
+      bcopy((char *)c.session, ct.HandShakeKey, sizeof(c.session));
+      ct.ViceId = getuid();    /* is this always valid? */
+      ct.BeginTimestamp = 1 + c.issue_date;
+      ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime);
+
+      t = buf;
+      /*
+       * length of secret token followed by secret token
+       */
+      sizeof_x = c.ticket_st.length;
+      bcopy((char *)&sizeof_x, t, sizeof(sizeof_x));
+      t += sizeof(sizeof_x);
+      bcopy((char *)c.ticket_st.dat, t, sizeof_x);
+      t += sizeof_x;
+      /*
+       * length of clear token followed by clear token
+       */
+      sizeof_x = sizeof(ct);
+      bcopy((char *)&sizeof_x, t, sizeof(sizeof_x));
+      t += sizeof(sizeof_x);
+      bcopy((char *)&ct, t, sizeof_x);
+      t += sizeof_x;
+
+      /*
+       * do *not* mark as primary cell
+       */
+      sizeof_x = 0;
+      bcopy((char *)&sizeof_x, t, sizeof(sizeof_x));
+      t += sizeof(sizeof_x);
+      /*
+       * follow with cell name
+       */
+      sizeof_x = strlen(cell) + 1;
+      bcopy(cell, t, sizeof_x);
+      t += sizeof_x;
+
+      /*
+       * Build argument block
+       */
+      parms.in = buf;
+      parms.in_size = t - buf;
+      parms.out = 0;
+      parms.out_size = 0;
+      (void) k_pioctl(0, VIOCSETTOK, &parms, 0);
+    }
+  return k_errno;
+}
+
+#define NO_ENTRY_POINT         0
+#define SINGLE_ENTRY_POINT     1
+#define MULTIPLE_ENTRY_POINT   2
+#define SINGLE_ENTRY_POINT2    3
+#define AIX_ENTRY_POINTS       4
+#define UNKNOWN_ENTRY_POINT    5
+static int afs_entry_point = UNKNOWN_ENTRY_POINT;
+
+int
+k_pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks)
+       char *a_path;
+       int o_opcode;
+       struct ViceIoctl *a_paramsP;
+       int a_followSymlinks;
+{
+#ifdef AFS_SYSCALL
+  if (afs_entry_point == SINGLE_ENTRY_POINT)
+    return syscall(AFS_SYSCALL, AFSCALL_PIOCTL,
+                  a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+
+#ifdef AFS_PIOCTL
+    if (afs_entry_point == MULTIPLE_ENTRY_POINT)
+      return syscall(AFS_PIOCTL,
+                    a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+
+#ifdef AFS_SYSCALL2
+  if (afs_entry_point == SINGLE_ENTRY_POINT2)
+    return syscall(AFS_SYSCALL2, AFSCALL_PIOCTL,
+                  a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+
+#ifdef _AIX
+  if (afs_entry_point == AIX_ENTRY_POINTS)
+    return lpioctl(a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+
+  errno = ENOSYS;
+  kill(getpid(), SIGSYS);      /* You loose! */
+  return -1;
+}
+
+int
+k_unlog()
+{
+  struct ViceIoctl parms;
+  bzero((char *)&parms, sizeof(parms));
+  return k_pioctl(0, VIOCUNLOG, &parms, 0);
+}
+
+int
+k_setpag()
+{
+#ifdef AFS_SYSCALL
+  if (afs_entry_point == SINGLE_ENTRY_POINT)
+    return syscall(AFS_SYSCALL, AFSCALL_SETPAG);
+#endif
+
+#ifdef AFS_SETPAG
+  if (afs_entry_point == MULTIPLE_ENTRY_POINT)
+    return syscall(AFS_SETPAG);
+#endif
+
+#ifdef AFS_SYSCALL2
+  if (afs_entry_point == SINGLE_ENTRY_POINT2)
+    return syscall(AFS_SYSCALL2, AFSCALL_SETPAG);
+#endif
+
+#ifdef _AIX
+  if (afs_entry_point == AIX_ENTRY_POINTS)
+    return lsetpag();
+#endif
+
+  errno = ENOSYS;
+  kill(getpid(), SIGSYS);      /* You loose! */
+  return -1;
+}
+#endif /* defined(linux) */
+static jmp_buf catch_SIGSYS;
+
+static void
+SIGSYS_handler()
+{
+  errno = 0;
+  longjmp(catch_SIGSYS, 1);
+}
+
+int
+k_hasafs()
+{
+  int saved_errno;
+  void (*saved_func)();
+  struct ViceIoctl parms;
+  
+#if defined(linux)
+  return 0;
+#else
+  /*
+   * Already checked presence of AFS syscalls?
+   */
+  if (afs_entry_point != UNKNOWN_ENTRY_POINT)
+    return afs_entry_point != NO_ENTRY_POINT;
+
+  /*
+   * Probe kernel for AFS specific syscalls,
+   * they (currently) come in two flavors.
+   * If the syscall is absent we recive a SIGSYS.
+   */
+  afs_entry_point = NO_ENTRY_POINT;
+  bzero(&parms, sizeof(parms));
+  
+  saved_errno = errno;
+  saved_func = signal(SIGSYS, SIGSYS_handler);
+
+#ifdef AFS_SYSCALL
+  if (setjmp(catch_SIGSYS) == 0)
+    {
+      syscall(AFS_SYSCALL, AFSCALL_PIOCTL,
+             0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+      if (errno == EINVAL)
+       {
+         afs_entry_point = SINGLE_ENTRY_POINT;
+         goto done;
+       }
+    }
+#endif /* AFS_SYSCALL */
+
+#ifdef AFS_PIOCTL
+  if (setjmp(catch_SIGSYS) == 0)
+    {
+      syscall(AFS_PIOCTL,
+             0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+      if (errno == EINVAL)
+       {
+         afs_entry_point = MULTIPLE_ENTRY_POINT;
+         goto done;
+       }
+    }
+#endif /* AFS_PIOCTL */
+
+#ifdef AFS_SYSCALL2
+  if (setjmp(catch_SIGSYS) == 0)
+    {
+      syscall(AFS_SYSCALL2, AFSCALL_PIOCTL,
+             0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+      if (errno == EINVAL)
+       {
+         afs_entry_point = SINGLE_ENTRY_POINT2;
+         goto done;
+       }
+    }
+#endif /* AFS_SYSCALL */
+
+#ifdef _AIX
+  if (setjmp(catch_SIGSYS) == 0)
+    {
+      lpioctl(0, 0, 0, 0);
+      if (errno == EINVAL)
+       {
+         afs_entry_point = AIX_ENTRY_POINTS;
+         goto done;
+       }
+    }
+#endif
+
+ done:
+  (void) signal(SIGSYS, saved_func);
+  errno = saved_errno;
+  return afs_entry_point != NO_ENTRY_POINT;
+#endif /* linux */
+}
diff --git a/kerberosIV/kafs/afssysdefs.h b/kerberosIV/kafs/afssysdefs.h
new file mode 100644 (file)
index 0000000..cc712d9
--- /dev/null
@@ -0,0 +1,34 @@
+/*     $Id: afssysdefs.h,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $     */
+
+/*
+ * This section is for machines using single entry point AFS syscalls!
+ * or
+ * This section is for machines using multiple entry point AFS syscalls!
+ */
+
+#if defined(sun) && !defined(__svr4__)
+#define AFS_SYSCALL    31
+#endif
+
+#if defined(sun) && defined(__svr4__)
+#define AFS_SYSCALL    105
+#endif
+
+#if defined(hpux)
+#define AFS_SYSCALL    50
+#define AFS_SYSCALL2   49
+#endif
+
+#if defined(_AIX)
+/* _AIX is too weird */
+#endif
+
+#if defined(sgi)
+#define AFS_PIOCTL      (64+1000)
+#define AFS_SETPAG      (65+1000)
+#endif
+
+#if defined(__osf__)
+#define AFS_SYSCALL    232
+#define AFS_SYSCALL2   258
+#endif
diff --git a/kerberosIV/kafs/shlib_version b/kerberosIV/kafs/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/kdb/Makefile b/kerberosIV/kdb/Makefile
new file mode 100644 (file)
index 0000000..cbd1af5
--- /dev/null
@@ -0,0 +1,8 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $
+
+LIB=   kdb
+CFLAGS+=-I${.CURDIR}
+SRCS=  krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/kdb/kdb_locl.h b/kerberosIV/kdb/kdb_locl.h
new file mode 100644 (file)
index 0000000..df18f9e
--- /dev/null
@@ -0,0 +1,60 @@
+/*     $Id: kdb_locl.h,v 1.1.1.1 1995/12/14 06:52:37 tholo Exp $       */
+
+#ifndef __kdb_locl_h
+#define __kdb_locl_h
+
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <sys/file.h>
+
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+
+/* --- */
+
+/* Globals! */
+
+/* Utils */
+
+int kerb_db_set_lockmode __P((int));
+void kerb_db_fini __P((void));
+int kerb_db_init __P((void));
+int kerb_db_set_name __P((char *name));
+time_t kerb_get_db_age __P((void));
+int kerb_db_create __P((char *db_name));
+int kerb_db_rename __P((char *from, char *to));
+
+int kerb_db_get_principal __P((char *name, char *, Principal *, unsigned int, int *));
+int kerb_db_put_principal __P((Principal *, unsigned int));
+int kerb_db_get_dba __P((char *, char *, Dba *, unsigned int, int *));
+
+void kerb_db_get_stat __P((DB_stat *));
+void kerb_db_put_stat __P((DB_stat *));
+void delta_stat __P((DB_stat *, DB_stat *, DB_stat *));
+
+int kerb_db_iterate __P((int (*func) (/* ??? */), char *arg));
+
+int kerb_cache_init __P((void));
+int kerb_cache_get_principal __P((char *name, char *, Principal *, unsigned int));
+int kerb_cache_put_principal __P((Principal *, unsigned int));
+int kerb_cache_get_dba __P((char *, char *, Dba *, unsigned int));
+int kerb_cache_put_dba __P((Dba *, unsigned int));
+
+void krb_print_principal __P((Principal *));
+
+#endif /*  __kdb_locl_h */
diff --git a/kerberosIV/kdb/krb_cache.c b/kerberosIV/kdb/krb_cache.c
new file mode 100644 (file)
index 0000000..1419087
--- /dev/null
@@ -0,0 +1,186 @@
+/*     $Id: krb_cache.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $      */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * This is where a cache would be implemented, if it were necessary.
+ */
+
+#include "kdb_locl.h"
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+#endif
+static  init = 0;
+
+/*
+ * initialization routine for cache 
+ */
+
+int
+kerb_cache_init()
+{
+    init = 1;
+    return (0);
+}
+
+/*
+ * look up a principal in the cache returns number of principals found 
+ */
+
+int
+kerb_cache_get_principal(serv, inst, principal, max)
+       char *serv;             /* could have wild card */
+       char *inst;             /* could have wild card */
+       Principal *principal;
+       unsigned int max;       /* max number of name structs to return */
+{
+    int     found = 0;
+
+    if (!init)
+       kerb_cache_init();
+#ifdef DEBUG
+    if (kerb_debug & 2)
+       fprintf(stderr, "cache_get_principal for %s %s max = %d\n",
+           serv, inst, max);
+#endif /* DEBUG */
+    
+#ifdef DEBUG
+    if (kerb_debug & 2) {
+       if (found) {
+           fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+               serv, inst, principal->name, principal->instance);
+       } else {
+           fprintf(stderr, "cache %s %s not found\n", serv,
+               inst);
+       }
+    }
+#endif
+    return (found);
+}
+
+/*
+ * insert/replace a principal in the cache returns number of principals
+ * inserted 
+ */
+
+int
+kerb_cache_put_principal(principal, max)
+       Principal *principal;
+       unsigned int max;       /* max number of principal structs to
+                                * insert */
+
+{
+    u_long  i;
+    int     count = 0;
+
+    if (!init)
+       kerb_cache_init();
+
+#ifdef DEBUG
+    if (kerb_debug & 2) {
+       fprintf(stderr, "kerb_cache_put_principal  max = %d",
+           max);
+    }
+#endif
+    
+    for (i = 0; i < max; i++) {
+#ifdef DEBUG
+       if (kerb_debug & 2)
+           fprintf(stderr, "\n %s %s",
+                   principal->name, principal->instance);
+#endif 
+       /* DO IT */
+       count++;
+       principal++;
+    }
+    return count;
+}
+
+/*
+ * look up a dba in the cache returns number of dbas found 
+ */
+
+int
+kerb_cache_get_dba(serv, inst, dba, max)
+       char *serv;             /* could have wild card */
+       char *inst;             /* could have wild card */
+       Dba *dba;
+       unsigned int max;       /* max number of name structs to return */
+{
+    int     found = 0;
+
+    if (!init)
+       kerb_cache_init();
+
+#ifdef DEBUG
+    if (kerb_debug & 2)
+       fprintf(stderr, "cache_get_dba for %s %s max = %d\n",
+           serv, inst, max);
+#endif
+
+#ifdef DEBUG
+    if (kerb_debug & 2) {
+       if (found) {
+           fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+               serv, inst, dba->name, dba->instance);
+       } else {
+           fprintf(stderr, "cache %s %s not found\n", serv, inst);
+       }
+    }
+#endif
+    return (found);
+}
+
+/*
+ * insert/replace a dba in the cache returns number of dbas inserted 
+ */
+
+int
+kerb_cache_put_dba(dba, max)
+       Dba *dba;
+       unsigned int max;       /* max number of dba structs to insert */
+
+{
+    u_long  i;
+    int     count = 0;
+
+    if (!init)
+       kerb_cache_init();
+#ifdef DEBUG
+    if (kerb_debug & 2) {
+       fprintf(stderr, "kerb_cache_put_dba  max = %d", max);
+    }
+#endif
+    for (i = 0; i < max; i++) {
+#ifdef DEBUG
+       if (kerb_debug & 2)
+           fprintf(stderr, "\n %s %s",
+                   dba->name, dba->instance);
+#endif 
+       /* DO IT */
+       count++;
+       dba++;
+    }
+    return count;
+}
+
diff --git a/kerberosIV/kdb/krb_dbm.c b/kerberosIV/kdb/krb_dbm.c
new file mode 100644 (file)
index 0000000..d4a37c7
--- /dev/null
@@ -0,0 +1,739 @@
+/*     $Id: krb_dbm.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $        */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "kdb_locl.h"
+
+#include <ndbm.h>
+
+#define KERB_DB_MAX_RETRY 5
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+extern char *progname;
+#endif
+
+static  init = 0;
+static char default_db_name[] = DBM_FILE;
+static char *current_db_name = default_db_name;
+
+static struct timeval timestamp;/* current time of request */
+static int non_blocking = 0;
+
+/*
+ * This module contains all of the code which directly interfaces to
+ * the underlying representation of the Kerberos database; this
+ * implementation uses a DBM or NDBM indexed "file" (actually
+ * implemented as two separate files) to store the relations, plus a
+ * third file as a semaphore to allow the database to be replaced out
+ * from underneath the KDC server.
+ */
+
+/*
+ * Locking:
+ * 
+ * There are two distinct locking protocols used.  One is designed to
+ * lock against processes (the admin_server, for one) which make
+ * incremental changes to the database; the other is designed to lock
+ * against utilities (kdb_util, kpropd) which replace the entire
+ * database in one fell swoop.
+ *
+ * The first locking protocol is implemented using flock() in the 
+ * krb_dbl_lock() and krb_dbl_unlock routines.
+ *
+ * The second locking protocol is necessary because DBM "files" are
+ * actually implemented as two separate files, and it is impossible to
+ * atomically rename two files simultaneously.  It assumes that the
+ * database is replaced only very infrequently in comparison to the time
+ * needed to do a database read operation.
+ *
+ * A third file is used as a "version" semaphore; the modification
+ * time of this file is the "version number" of the database.
+ * At the start of a read operation, the reader checks the version
+ * number; at the end of the read operation, it checks again.  If the
+ * version number changed, or if the semaphore was nonexistant at
+ * either time, the reader sleeps for a second to let things
+ * stabilize, and then tries again; if it does not succeed after
+ * KERB_DB_MAX_RETRY attempts, it gives up.
+ * 
+ * On update, the semaphore file is deleted (if it exists) before any
+ * update takes place; at the end of the update, it is replaced, with
+ * a version number strictly greater than the version number which
+ * existed at the start of the update.
+ * 
+ * If the system crashes in the middle of an update, the semaphore
+ * file is not automatically created on reboot; this is a feature, not
+ * a bug, since the database may be inconsistant.  Note that the
+ * absence of a semaphore file does not prevent another _update_ from
+ * taking place later.  Database replacements take place automatically
+ * only on slave servers; a crash in the middle of an update will be
+ * fixed by the next slave propagation.  A crash in the middle of an
+ * update on the master would be somewhat more serious, but this would
+ * likely be noticed by an administrator, who could fix the problem and
+ * retry the operation.
+ */
+
+/* Macros to convert ndbm names to dbm names.
+ * Note that dbm_nextkey() cannot be simply converted using a macro, since
+ * it is invoked giving the database, and nextkey() needs the previous key.
+ *
+ * Instead, all routines call "dbm_next" instead.
+ */
+
+#define dbm_next(db,key) dbm_nextkey(db)
+
+static char *gen_dbsuffix __P((char *db_name, char *sfx));
+static void decode_princ_key __P((datum *key, char *name, char *instance));
+static void encode_princ_contents __P((datum *contents, Principal *principal));
+static void decode_princ_contents __P((datum *contents, Principal *principal));
+static void encode_princ_key __P((datum *key, char *name, char *instance));
+static int kerb_dbl_init __P((void));
+static void kerb_dbl_fini __P((void));
+static int kerb_dbl_lock __P((int mode));
+static void kerb_dbl_unlock __P((void));
+static time_t kerb_start_update __P((char *db_name));
+static int kerb_end_update __P((char *db_name, time_t age));
+static time_t kerb_start_read __P((void));
+static int kerb_end_read __P((time_t age));
+
+/*
+ * Utility routine: generate name of database file.
+ */
+
+static char *
+gen_dbsuffix(db_name, sfx)
+     char *db_name;
+     char *sfx;
+{
+    char *dbsuffix;
+    
+    if (sfx == NULL)
+       sfx = ".ok";
+
+    dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
+    strcpy(dbsuffix, db_name);
+    strcat(dbsuffix, sfx);
+    return dbsuffix;
+}
+
+static void
+decode_princ_key(key, name, instance)
+     datum *key;
+     char *name;
+     char *instance;
+{
+    strncpy(name, key->dptr, ANAME_SZ);
+    strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
+    name[ANAME_SZ - 1] = '\0';
+    instance[INST_SZ - 1] = '\0';
+}
+
+static void
+encode_princ_contents(contents, principal)
+     datum *contents;
+     Principal *principal;
+{
+    contents->dsize = sizeof(*principal);
+    contents->dptr = (char *) principal;
+}
+
+static void
+decode_princ_contents(contents, principal)
+     datum *contents;
+     Principal *principal;
+{
+    bcopy(contents->dptr, (char *) principal, sizeof(*principal));
+}
+
+static void
+encode_princ_key(key, name, instance)
+     datum *key;
+     char *name;
+     char *instance;
+{
+    static char keystring[ANAME_SZ + INST_SZ];
+
+    bzero(keystring, ANAME_SZ + INST_SZ);
+    strncpy(keystring, name, ANAME_SZ);
+    strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
+    key->dptr = keystring;
+    key->dsize = ANAME_SZ + INST_SZ;
+}
+
+static int dblfd = -1;         /* db LOCK fd */
+static int mylock = 0;
+static int inited = 0;
+
+static int
+kerb_dbl_init()
+{
+    if (!inited) {
+       char *filename = gen_dbsuffix (current_db_name, ".ok");
+       if ((dblfd = open(filename, O_RDWR)) < 0) {
+           fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
+           fflush(stderr);
+           perror("open");
+           exit(1);
+       }
+       free(filename);
+       inited++;
+    }
+    return (0);
+}
+
+static void
+kerb_dbl_fini()
+{
+    close(dblfd);
+    dblfd = -1;
+    inited = 0;
+    mylock = 0;
+}
+
+static int
+kerb_dbl_lock(mode)
+     int mode;
+{
+    int flock_mode;
+    
+    if (!inited)
+       kerb_dbl_init();
+    if (mylock) {              /* Detect lock call when lock already
+                                * locked */
+       fprintf(stderr, "Kerberos locking error (mylock)\n");
+       fflush(stderr);
+       exit(1);
+    }
+    switch (mode) {
+    case KERB_DBL_EXCLUSIVE:
+       flock_mode = LOCK_EX;
+       break;
+    case KERB_DBL_SHARED:
+       flock_mode = LOCK_SH;
+       break;
+    default:
+       fprintf(stderr, "invalid lock mode %d\n", mode);
+       abort();
+    }
+    if (non_blocking)
+       flock_mode |= LOCK_NB;
+    
+    if (flock(dblfd, flock_mode) < 0) 
+       return errno;
+    mylock++;
+    return 0;
+}
+
+static void
+kerb_dbl_unlock()
+{
+    if (!mylock) {             /* lock already unlocked */
+       fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
+       fflush(stderr);
+       exit(1);
+    }
+    if (flock(dblfd, LOCK_UN) < 0) {
+       fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
+       fflush(stderr);
+       perror("flock");
+       exit(1);
+    }
+    mylock = 0;
+}
+
+int
+kerb_db_set_lockmode(mode)
+     int mode;
+{
+    int old = non_blocking;
+    non_blocking = mode;
+    return old;
+}
+
+/*
+ * initialization for data base routines.
+ */
+
+int
+kerb_db_init()
+{
+    init = 1;
+    return (0);
+}
+
+/*
+ * gracefully shut down database--must be called by ANY program that does
+ * a kerb_db_init 
+ */
+
+void
+kerb_db_fini()
+{
+}
+
+/*
+ * Set the "name" of the current database to some alternate value.
+ *
+ * Passing a null pointer as "name" will set back to the default.
+ * If the alternate database doesn't exist, nothing is changed.
+ */
+
+int
+kerb_db_set_name(name)
+     char *name;
+{
+    DBM *db;
+
+    if (name == NULL)
+       name = default_db_name;
+    db = dbm_open(name, 0, 0);
+    if (db == NULL)
+       return errno;
+    dbm_close(db);
+    kerb_dbl_fini();
+    current_db_name = name;
+    return 0;
+}
+
+/*
+ * Return the last modification time of the database.
+ */
+
+time_t
+kerb_get_db_age()
+{
+    struct stat st;
+    char *okname;
+    time_t age;
+    
+    okname = gen_dbsuffix(current_db_name, ".ok");
+
+    if (stat (okname, &st) < 0)
+       age = 0;
+    else
+       age = st.st_mtime;
+
+    free (okname);
+    return age;
+}
+
+/*
+ * Remove the semaphore file; indicates that database is currently
+ * under renovation.
+ *
+ * This is only for use when moving the database out from underneath
+ * the server (for example, during slave updates).
+ */
+
+static time_t
+kerb_start_update(db_name)
+     char *db_name;
+{
+    char *okname = gen_dbsuffix(db_name, ".ok");
+    time_t age = kerb_get_db_age();
+    
+    if (unlink(okname) < 0
+       && errno != ENOENT) {
+           age = -1;
+    }
+    free (okname);
+    return age;
+}
+
+static int
+kerb_end_update(db_name, age)
+     char *db_name;
+     time_t age;
+{
+    int fd;
+    int retval = 0;
+    char *new_okname = gen_dbsuffix(db_name, ".ok#");
+    char *okname = gen_dbsuffix(db_name, ".ok");
+    
+    fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+    if (fd < 0)
+       retval = errno;
+    else {
+       struct stat st;
+       struct utimbuf tv;
+       /* make sure that semaphore is "after" previous value. */
+       if (fstat (fd, &st) == 0
+           && st.st_mtime <= age) {
+           tv.actime = st.st_atime;
+           tv.modtime = age;
+           /* set times.. */
+           utime (new_okname, &tv);
+           fsync(fd);
+       }
+       close(fd);
+       if (rename (new_okname, okname) < 0)
+           retval = errno;
+    }
+
+    free (new_okname);
+    free (okname);
+
+    return retval;
+}
+
+static time_t
+kerb_start_read()
+{
+    return kerb_get_db_age();
+}
+
+static int
+kerb_end_read(age)
+     time_t age;
+{
+    if (kerb_get_db_age() != age || age == -1) {
+       return -1;
+    }
+    return 0;
+}
+
+/*
+ * Create the database, assuming it's not there.
+ */
+
+int
+kerb_db_create(db_name)
+     char *db_name;
+{
+    char *okname = gen_dbsuffix(db_name, ".ok");
+    int fd;
+    register int ret = 0;
+    DBM *db;
+
+    db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
+    if (db == NULL)
+       ret = errno;
+    else
+       dbm_close(db);
+    if (ret == 0) {
+       fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+       if (fd < 0)
+           ret = errno;
+       close(fd);
+    }
+    return ret;
+}
+
+/*
+ * "Atomically" rename the database in a way that locks out read
+ * access in the middle of the rename.
+ *
+ * Not perfect; if we crash in the middle of an update, we don't
+ * necessarily know to complete the transaction the rename, but...
+ */
+
+int
+kerb_db_rename(from, to)
+     char *from;
+     char *to;
+{
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    char *fromdb = gen_dbsuffix (from, ".db");
+    char *todb = gen_dbsuffix (from, ".db");
+#else
+    char *fromdir = gen_dbsuffix (from, ".dir");
+    char *todir = gen_dbsuffix (to, ".dir");
+    char *frompag = gen_dbsuffix (from , ".pag");
+    char *topag = gen_dbsuffix (to, ".pag");
+#endif
+    char *fromok = gen_dbsuffix(from, ".ok");
+    long trans = kerb_start_update(to);
+    int ok = 0;
+    
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    if (rename (fromdb, todb) == 0) {
+       (void) unlink (fromdb);
+       ok = 1;
+    }
+    free (fromdb);
+    free (todb);
+#else
+    if ((rename (fromdir, todir) == 0)
+       && (rename (frompag, topag) == 0)) {
+       (void) unlink (fromok);
+       ok = 1;
+    }
+    free (fromdir);
+    free (todir);
+    free (frompag);
+    free (topag);
+#endif
+    free (fromok);
+    if (ok)
+       return kerb_end_update(to, trans);
+    else
+       return -1;
+}
+
+/*
+ * look up a principal in the data base returns number of principals
+ * found , and whether there were more than requested. 
+ */
+
+int
+kerb_db_get_principal(name, inst, principal, max, more)
+     char *name;               /* could have wild card */
+     char *inst;               /* could have wild card */
+     Principal *principal;     /* max number of name structs to return */
+     unsigned int max;         /* where there more than 'max' tuples? */
+     int *more;
+{
+    int     found = 0, code;
+    extern int errorproc();
+    int     wildp, wildi;
+    datum   key, contents;
+    char    testname[ANAME_SZ], testinst[INST_SZ];
+    u_long trans;
+    int try;
+    DBM    *db;
+
+    if (!init)
+       kerb_db_init();         /* initialize database routines */
+
+    for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
+       trans = kerb_start_read();
+
+       if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+           return -1;
+
+       db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+       *more = 0;
+
+#ifdef DEBUG
+       if (kerb_debug & 2)
+           fprintf(stderr,
+                   "%s: db_get_principal for %s %s max = %d",
+                   progname, name, inst, max);
+#endif
+
+       wildp = !strcmp(name, "*");
+       wildi = !strcmp(inst, "*");
+
+       if (!wildi && !wildp) { /* nothing's wild */
+           encode_princ_key(&key, name, inst);
+           contents = dbm_fetch(db, key);
+           if (contents.dptr == NULL) {
+               found = 0;
+               goto done;
+           }
+           decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+           if (kerb_debug & 1) {
+               fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
+                       principal->name, principal->instance,
+                       strlen(principal->name),
+                       strlen(principal->instance));
+           }
+#endif
+           found = 1;
+           goto done;
+       }
+       /* process wild cards by looping through entire database */
+
+       for (key = dbm_firstkey(db); key.dptr != NULL;
+            key = dbm_next(db, key)) {
+           decode_princ_key(&key, testname, testinst);
+           if ((wildp || !strcmp(testname, name)) &&
+               (wildi || !strcmp(testinst, inst))) { /* have a match */
+               if (found >= max) {
+                   *more = 1;
+                   goto done;
+               } else {
+                   found++;
+                   contents = dbm_fetch(db, key);
+                   decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+                   if (kerb_debug & 1) {
+                       fprintf(stderr,
+                               "\tfound %s %s p_n length %d t_n length %d\n",
+                               principal->name, principal->instance,
+                               strlen(principal->name),
+                               strlen(principal->instance));
+                   }
+#endif
+                   principal++; /* point to next */
+               }
+           }
+       }
+
+    done:
+       kerb_dbl_unlock();      /* unlock read lock */
+       dbm_close(db);
+       if (kerb_end_read(trans) == 0)
+           break;
+       found = -1;
+       if (!non_blocking)
+           sleep(1);
+    }
+    return (found);
+}
+
+/*
+ * Update a name in the data base.  Returns number of names
+ * successfully updated.
+ */
+
+int
+kerb_db_put_principal(principal, max)
+     Principal *principal;     /* number of principal structs to */
+     unsigned int max;         /* update */
+
+{
+    int     found = 0, code;
+    u_long  i;
+    extern int errorproc();
+    datum   key, contents;
+    DBM    *db;
+
+    gettimeofday(&timestamp, NULL);
+
+    if (!init)
+       kerb_db_init();
+
+    if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0)
+       return -1;
+
+    db = dbm_open(current_db_name, O_RDWR, 0600);
+
+#ifdef DEBUG
+    if (kerb_debug & 2)
+       fprintf(stderr, "%s: kerb_db_put_principal  max = %d",
+           progname, max);
+#endif
+
+    /* for each one, stuff temps, and do replace/append */
+    for (i = 0; i < max; i++) {
+       encode_princ_contents(&contents, principal);
+       encode_princ_key(&key, principal->name, principal->instance);
+       dbm_store(db, key, contents, DBM_REPLACE);
+#ifdef DEBUG
+       if (kerb_debug & 1) {
+           fprintf(stderr, "\n put %s %s\n",
+               principal->name, principal->instance);
+       }
+#endif
+       found++;
+       principal++;            /* bump to next struct                     */
+    }
+
+    dbm_close(db);
+    kerb_dbl_unlock();         /* unlock database */
+    return (found);
+}
+
+void
+kerb_db_get_stat(s)
+     DB_stat *s;
+{
+    gettimeofday(&timestamp, NULL);
+
+
+    s->cpu = 0;
+    s->elapsed = 0;
+    s->dio = 0;
+    s->pfault = 0;
+    s->t_stamp = timestamp.tv_sec;
+    s->n_retrieve = 0;
+    s->n_replace = 0;
+    s->n_append = 0;
+    s->n_get_stat = 0;
+    s->n_put_stat = 0;
+    /* update local copy too */
+}
+
+void
+kerb_db_put_stat(s)
+     DB_stat *s;
+{
+}
+
+void
+delta_stat(a, b, c)
+     DB_stat *a, *b, *c;
+{
+    /* c = a - b then b = a for the next time */
+
+    c->cpu = a->cpu - b->cpu;
+    c->elapsed = a->elapsed - b->elapsed;
+    c->dio = a->dio - b->dio;
+    c->pfault = a->pfault - b->pfault;
+    c->t_stamp = a->t_stamp - b->t_stamp;
+    c->n_retrieve = a->n_retrieve - b->n_retrieve;
+    c->n_replace = a->n_replace - b->n_replace;
+    c->n_append = a->n_append - b->n_append;
+    c->n_get_stat = a->n_get_stat - b->n_get_stat;
+    c->n_put_stat = a->n_put_stat - b->n_put_stat;
+
+    bcopy(a, b, sizeof(DB_stat));
+    return;
+}
+
+/*
+ * look up a dba in the data base returns number of dbas found , and
+ * whether there were more than requested. 
+ */
+
+int
+kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
+     char *dba_name;           /* could have wild card */
+     char *dba_inst;           /* could have wild card */
+     Dba *dba;                 /* max number of name structs to return */
+     unsigned int max;         /* where there more than 'max' tuples? */
+     int *more;
+{
+    *more = 0;
+    return (0);
+}
+
+int
+kerb_db_iterate (func, arg)
+     int (*func)();
+     char *arg;                        /* void *, really */
+{
+    datum key, contents;
+    Principal *principal;
+    int code;
+    DBM *db;
+    
+    kerb_db_init();            /* initialize and open the database */
+    if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+       return code;
+
+    db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+    for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
+       contents = dbm_fetch (db, key);
+       /* XXX may not be properly aligned */
+       principal = (Principal *) contents.dptr;
+       if ((code = (*func)(arg, principal)) != 0)
+           return code;
+    }
+    dbm_close(db);
+    kerb_dbl_unlock();
+    return 0;
+}
diff --git a/kerberosIV/kdb/krb_kdb_utils.c b/kerberosIV/kdb/krb_kdb_utils.c
new file mode 100644 (file)
index 0000000..d9c8185
--- /dev/null
@@ -0,0 +1,153 @@
+/*     $Id: krb_kdb_utils.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $  */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Utility routines for Kerberos programs which directly access
+ * the database.  This code was duplicated in too many places
+ * before I gathered it here.
+ *
+ * Jon Rochlis, MIT Telecom, March 1988
+ */
+
+#include "kdb_locl.h"
+
+#include <kdc.h>
+
+long 
+kdb_get_master_key(prompt, master_key, master_key_sched)
+       int prompt;
+       des_cblock *master_key;
+       struct des_ks_struct *master_key_sched;
+{
+  int kfile;
+
+  if (prompt)  {
+#ifdef NOENCRYPTION
+      placebo_read_password(master_key,
+                           "\nEnter Kerberos master key: ", 0);
+#else
+      des_read_password(master_key,
+                            "\nEnter Kerberos master key: ", 0);
+#endif
+      printf ("\n");
+  }
+  else {
+    kfile = open(MKEYFILE, O_RDONLY, 0600);
+    if (kfile < 0) {
+      /* oh, for com_err_ */
+      return (-1);
+    }
+    if (read(kfile, (char *) master_key, 8) != 8) {
+      return (-1);
+    }
+    close(kfile);
+  }
+
+#ifndef NOENCRYPTION
+  des_key_sched(master_key,master_key_sched);
+#endif
+  return (0);
+}
+
+/* The old algorithm used the key schedule as the initial vector which
+   was byte order depedent ... */
+
+void
+kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
+       des_cblock *in;
+       des_cblock *out;
+       des_cblock *master_key;
+       struct des_ks_struct *master_key_sched;
+       int e_d_flag;
+{
+
+#ifdef NOENCRYPTION
+  bcopy(in, out, sizeof(des_cblock));
+#else
+  des_pcbc_encrypt(in,out,(long)sizeof(des_cblock),master_key_sched,master_key,
+       e_d_flag);
+#endif
+}
+
+/* The caller is reasponsible for cleaning up the master key and sched,
+   even if we can't verify the master key */
+
+/* Returns master key version if successful, otherwise -1 */
+
+long 
+kdb_verify_master_key (master_key, master_key_sched, out)
+       des_cblock *master_key;
+       struct des_ks_struct *master_key_sched;
+       FILE *out;              /* setting this to non-null be do output */
+{
+  des_cblock key_from_db;
+  Principal principal_data[1];
+  int n, more = 0;
+  long master_key_version;
+
+  /* lookup the master key version */
+  n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+                        1 /* only one please */, &more);
+  if ((n != 1) || more) {
+    if (out != (FILE *) NULL) 
+      fprintf(out,
+             "verify_master_key: %s, %d found.\n",
+             "Kerberos error on master key version lookup",
+             n);
+    return (-1);
+  }
+
+  master_key_version = (long) principal_data[0].key_version;
+
+  /* set up the master key */
+  if (out != (FILE *) NULL)  /* should we punt this? */
+    fprintf(out, "Current Kerberos master key version is %d.\n",
+           principal_data[0].kdc_key_ver);
+
+  /*
+   * now use the master key to decrypt the key in the db, had better
+   * be the same! 
+   */
+  bcopy(&principal_data[0].key_low, key_from_db, 4);
+  bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
+  kdb_encrypt_key (&key_from_db, &key_from_db, 
+                  master_key, master_key_sched, DES_DECRYPT);
+
+  /* the decrypted database key had better equal the master key */
+  n = bcmp((char *) master_key, (char *) key_from_db,
+          sizeof(master_key));
+  /* this used to zero the master key here! */
+  bzero(key_from_db, sizeof(key_from_db));
+  bzero(principal_data, sizeof (principal_data));
+
+  if (n && (out != (FILE *) NULL)) {
+    fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
+    fprintf(out, "does not match database.\n");
+    return (-1);
+  }
+  if (out != (FILE *) NULL) {
+    fprintf(out, "\nMaster key entered.  BEWARE!\07\07\n");
+    fflush(out);
+  }
+
+  return (master_key_version);
+}
diff --git a/kerberosIV/kdb/krb_lib.c b/kerberosIV/kdb/krb_lib.c
new file mode 100644 (file)
index 0000000..f5d9634
--- /dev/null
@@ -0,0 +1,236 @@
+/*     $Id: krb_lib.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $        */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "kdb_locl.h"
+
+#ifdef DEBUG
+extern int debug;
+extern char *progname;
+long    kerb_debug;
+#endif
+
+static int init = 0;
+
+/*
+ * initialization routine for data base 
+ */
+
+int
+kerb_init()
+{
+#ifdef DEBUG
+    if (!init) {
+       char *dbg = getenv("KERB_DBG");
+       if (dbg)
+           sscanf(dbg, "%d", &kerb_debug);
+       init = 1;
+    }
+#endif
+    kerb_db_init();
+
+#ifdef CACHE
+    kerb_cache_init();
+#endif
+
+    /* successful init, return 0, else errcode */
+    return (0);
+}
+
+/*
+ * finalization routine for database -- NOTE: MUST be called by any
+ * program using kerb_init.  ALSO will have to be modified to finalize
+ * caches, if they're ever really implemented. 
+ */
+
+void
+kerb_fini()
+{
+    kerb_db_fini();
+}
+
+/*
+ * look up a principal in the cache or data base returns number of
+ * principals found 
+ */
+
+int
+kerb_get_principal(name, inst, principal, max, more)
+       char *name;             /* could have wild card */
+       char *inst;             /* could have wild card */
+       Principal *principal;
+       unsigned int max;       /* max number of name structs to return */
+       int *more;              /* more tuples than room for */
+
+{
+    int     found = 0;
+#ifdef CACHE
+    static int wild = 0;
+#endif
+    if (!init)
+       kerb_init();
+
+#ifdef DEBUG
+    if (kerb_debug & 1)
+       fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n",
+           progname, name, inst, max);
+#endif
+    
+    /*
+     * if this is a request including a wild card, have to go to db
+     * since the cache may not be exhaustive. 
+     */
+
+    /* clear the principal area */
+    bzero((char *) principal, max * sizeof(Principal));
+
+#ifdef CACHE
+    /*
+     * so check to see if the name contains a wildcard "*" or "?", not
+     * preceeded by a backslash. 
+     */
+    wild = 0;
+    if (index(name, '*') || index(name, '?') ||
+       index(inst, '*') || index(inst, '?'))
+       wild = 1;
+
+    if (!wild) {
+       /* try the cache first */
+       found = kerb_cache_get_principal(name, inst, principal, max, more);
+       if (found)
+           return (found);
+    }
+#endif
+    /* If we didn't try cache, or it wasn't there, try db */
+    found = kerb_db_get_principal(name, inst, principal, max, more);
+    /* try to insert principal(s) into cache if it was found */
+#ifdef CACHE
+    if (found) {
+       kerb_cache_put_principal(principal, found);
+    }
+#endif
+    return (found);
+}
+
+/* principals */
+int
+kerb_put_principal(principal, n)
+       Principal *principal;
+       unsigned int n;         /* number of principal structs to write */
+{
+    struct tm *tp;
+
+    /* set mod date */
+    principal->mod_date = time((time_t *)0);
+    /* and mod date string */
+
+    tp = k_localtime(&principal->mod_date);
+    (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d",
+                  tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+                  tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+#ifdef DEBUG
+    if (kerb_debug & 1) {
+       int i;
+       fprintf(stderr, "\nkerb_put_principal...");
+       for (i = 0; i < n; i++) {
+           krb_print_principal(&principal[i]);
+       }
+    }
+#endif
+    /* write database */
+    if (kerb_db_put_principal(principal, n) < 0) {
+#ifdef DEBUG
+       if (kerb_debug & 1)
+           fprintf(stderr, "\n%s: kerb_db_put_principal err", progname);
+       /* watch out for cache */
+#endif
+       return -1;
+    }
+#ifdef CACHE
+    /* write cache */
+    if (!kerb_cache_put_principal(principal, n)) {
+#ifdef DEBUG
+       if (kerb_debug & 1)
+           fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname);
+#endif
+       return -1;
+    }
+#endif
+    return 0;
+}
+
+int
+kerb_get_dba(name, inst, dba, max, more)
+       char *name;             /* could have wild card */
+       char *inst;             /* could have wild card */
+       Dba *dba;
+       unsigned int max;       /* max number of name structs to return */
+       int *more;              /* more tuples than room for */
+
+{
+    int     found = 0;
+#ifdef CACHE
+    static int wild = 0;
+#endif
+    if (!init)
+       kerb_init();
+
+#ifdef DEBUG
+    if (kerb_debug & 1)
+       fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n",
+           progname, name, inst, max);
+#endif
+    /*
+     * if this is a request including a wild card, have to go to db
+     * since the cache may not be exhaustive. 
+     */
+
+    /* clear the dba area */
+    bzero((char *) dba, max * sizeof(Dba));
+
+#ifdef CACHE
+    /*
+     * so check to see if the name contains a wildcard "*" or "?", not
+     * preceeded by a backslash. 
+     */
+
+    wild = 0;
+    if (index(name, '*') || index(name, '?') ||
+       index(inst, '*') || index(inst, '?'))
+       wild = 1;
+
+    if (!wild) {
+       /* try the cache first */
+       found = kerb_cache_get_dba(name, inst, dba, max, more);
+       if (found)
+           return (found);
+    }
+#endif
+    /* If we didn't try cache, or it wasn't there, try db */
+    found = kerb_db_get_dba(name, inst, dba, max, more);
+#ifdef CACHE
+    /* try to insert dba(s) into cache if it was found */
+    if (found) {
+       kerb_cache_put_dba(dba, found);
+    }
+#endif
+    return (found);
+}
diff --git a/kerberosIV/kdb/print_princ.c b/kerberosIV/kdb/print_princ.c
new file mode 100644 (file)
index 0000000..3c358c6
--- /dev/null
@@ -0,0 +1,48 @@
+/*     $Id: print_princ.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $    */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "kdb_locl.h"
+
+void
+krb_print_principal(a_n)
+       Principal *a_n;
+{
+    struct tm *time_p;
+
+    /* run-time database does not contain string versions */
+    time_p = k_localtime(&(a_n->exp_date));
+
+    fprintf(stderr,
+    "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min  attr 0x%02x",
+    a_n->name, a_n->instance,
+    time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900,
+    time_p->tm_mon + 1, time_p->tm_mday,
+    time_p->tm_hour, time_p->tm_min,
+    a_n->max_life, 5 * a_n->max_life, a_n->attributes);
+
+    fprintf(stderr,
+    "\n\tkey_ver %d  k_low 0x%08lx  k_high 0x%08lx  akv %d  exists %ld\n",
+    a_n->key_version, (long)a_n->key_low, (long)a_n->key_high,
+    a_n->kdc_key_ver, (long)a_n->old);
+
+    fflush(stderr);
+}
diff --git a/kerberosIV/kdb/shlib_version b/kerberosIV/kdb/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/kdb_destroy/Makefile b/kerberosIV/kdb_destroy/Makefile
new file mode 100644 (file)
index 0000000..1389546
--- /dev/null
@@ -0,0 +1,7 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $
+
+PROG=  kdb_destroy
+MAN=   kdb_destroy.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kdb_destroy/kdb_destroy.8 b/kerberosIV/kdb_destroy/kdb_destroy.8
new file mode 100644 (file)
index 0000000..9898be9
--- /dev/null
@@ -0,0 +1,32 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kdb_destroy.8,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $
+.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_destroy \- destroy Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_destroy
+.SH DESCRIPTION
+.I kdb_destroy
+deletes a Kerberos key distribution center database.
+.PP
+The user is prompted to verify that the database should be destroyed.  A
+response beginning with `y' or `Y' confirms deletion.
+Any other response aborts deletion.
+.SH DIAGNOSTICS
+.TP 20n
+"Database cannot be deleted at /kerberos/principal"
+The attempt to delete the database failed (probably due to a system or
+access permission error).
+.TP
+"Database not deleted."
+The user aborted the deletion.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.SH SEE ALSO
+kdb_init(8)
diff --git a/kerberosIV/kdb_destroy/kdb_destroy.c b/kerberosIV/kdb_destroy/kdb_destroy.c
new file mode 100644 (file)
index 0000000..96ec912
--- /dev/null
@@ -0,0 +1,61 @@
+/*     $Id: kdb_destroy.c,v 1.1.1.1 1995/12/14 06:52:43 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <adm_locl.h>
+
+int
+main(void)
+{
+    char    answer[10];                /* user input */
+    char    dbm[256];          /* database path and name */
+    char    dbm1[256];         /* database path and name */
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+    char   *file;               /* database file names */
+#else
+    char   *file1, *file2;     /* database file names */
+#endif
+
+    strcpy(dbm, DBM_FILE);
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+    file = strcat(dbm, ".db");
+#else
+    strcpy(dbm1, DBM_FILE);
+    file1 = strcat(dbm, ".dir");
+    file2 = strcat(dbm1, ".pag");
+#endif
+
+    printf("You are about to destroy the Kerberos database ");
+    printf("on this machine.\n");
+    printf("Are you sure you want to do this (y/n)? ");
+    fgets(answer, sizeof(answer), stdin);
+
+    if (answer[0] == 'y' || answer[0] == 'Y') {
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+       if (unlink(file) == 0)
+#else
+       if (unlink(file1) == 0 && unlink(file2) == 0)
+#endif
+           fprintf(stderr, "Database deleted at %s\n", DBM_FILE);
+       else
+           fprintf(stderr, "Database cannot be deleted at %s\n",
+                   DBM_FILE);
+    } else
+       fprintf(stderr, "Database not deleted.\n");
+    exit(1);
+}
diff --git a/kerberosIV/kdb_edit/Makefile b/kerberosIV/kdb_edit/Makefile
new file mode 100644 (file)
index 0000000..5134f3d
--- /dev/null
@@ -0,0 +1,11 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+
+PROG=  kdb_edit
+SRCS=  kdb_edit.c maketime.c
+CFLAGS+=-I${.CURDIR}
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   kdb_edit.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kdb_edit/kdb_edit.8 b/kerberosIV/kdb_edit/kdb_edit.8
new file mode 100644 (file)
index 0000000..974f08e
--- /dev/null
@@ -0,0 +1,54 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kdb_edit.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_edit \-  Kerberos key distribution center database editing utility
+.SH SYNOPSIS
+kdb_edit [
+.B \-n
+]
+.SH DESCRIPTION
+.I kdb_edit
+is used to create or change principals stored in the Kerberos key
+distribution center (KDC) database.
+.PP
+When executed,
+.I kdb_edit
+prompts for the master key string and verifies that it matches the
+master key stored in the database.
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+Once the master key has been verified,
+.I kdb_edit
+begins a prompt loop.  The user is prompted for the principal and
+instance to be modified.  If the entry is not found the user may create
+it.
+Once an entry is found or created, the user may set the password,
+expiration date, maximum ticket lifetime, and attributes.
+Default expiration dates, maximum ticket lifetimes, and attributes are
+presented in brackets; if the user presses return the default is selected.
+There is no default password.
+The password RANDOM is interpreted specially, and if entered
+the user may have the program select a random DES key for the
+principal.
+.PP
+Upon successfully creating or changing the entry, ``Edit O.K.'' is
+printed.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/kerberosIV/kdb_edit/kdb_edit.c b/kerberosIV/kdb_edit/kdb_edit.c
new file mode 100644 (file)
index 0000000..7d79d3f
--- /dev/null
@@ -0,0 +1,473 @@
+/*     $Id: kdb_edit.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services. 
+ */
+
+/*
+ * exit returns         0 ==> success -1 ==> error 
+ */
+
+#include <adm_locl.h>
+
+#ifdef DEBUG
+extern  kerb_debug;
+#endif
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+static char    prog[32];
+char   *progname = prog;
+static int     nflag = 0;
+static int     debug;
+
+static des_cblock new_key;
+
+static int     i, j;
+static int     more;
+
+static char    input_name[ANAME_SZ];
+static char    input_instance[INST_SZ];
+
+#define        MAX_PRINCIPAL   10
+static Principal principal_data[MAX_PRINCIPAL];
+
+static Principal old_principal;
+static Principal default_princ;
+
+static des_cblock master_key;
+static des_cblock session_key;
+static des_key_schedule master_key_schedule;
+static char pw_str[255];
+static long master_key_version;
+
+static void
+Usage(void)
+{
+    fprintf(stderr, "Usage: %s [-n]\n", progname);
+    exit(1);
+}
+
+/*
+ * "fgets" where the nl is zapped afterwards.
+ */
+static char*
+z_fgets(cp, count, fp)
+       char *cp;
+       int count;
+       FILE *fp;
+{
+       int ix;
+       char *p;
+
+       if (fgets(cp, count, fp) == 0) {
+               return 0;
+       }
+       cp[count-1] = 0;
+       if ((p = strchr(cp, '\n')) == 0) {
+               return 0;
+       }
+       *p = 0;
+       return cp;
+}
+
+
+static int
+change_principal(void)
+{
+    static char temp[255];
+    int     creating = 0;
+    int     editpw = 0;
+    int     changed = 0;
+    long    temp_long;
+    int     n;
+    struct tm  *tp, edate, *localtime(const time_t *);
+    long       maketime(struct tm *tp, int local);
+
+    fprintf(stdout, "\nPrincipal name: ");
+    fflush(stdout);
+    if (!z_fgets(input_name, sizeof input_name, stdin) || *input_name == '\0')
+       return 0;
+    fprintf(stdout, "Instance: ");
+    fflush(stdout);
+    /* instance can be null */
+    z_fgets(input_instance, sizeof input_instance, stdin);
+    j = kerb_get_principal(input_name, input_instance, principal_data,
+                          MAX_PRINCIPAL, &more);
+    if (!j) {
+       fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
+       z_fgets(temp, sizeof temp, stdin); /* Default case should work, it didn't */
+       if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
+           return -1;
+       /* make a new principal, fill in defaults */
+       j = 1;
+       creating = 1;
+       strcpy(principal_data[0].name, input_name);
+       strcpy(principal_data[0].instance, input_instance);
+       principal_data[0].old = NULL;
+       principal_data[0].exp_date = default_princ.exp_date;
+       principal_data[0].max_life = default_princ.max_life;
+       principal_data[0].attributes = default_princ.attributes;
+       principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
+       principal_data[0].key_version = 0; /* bumped up later */
+    }
+    tp = k_localtime(&principal_data[0].exp_date);
+    (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
+                  tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+                  tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+    for (i = 0; i < j; i++) {
+       for (;;) {
+           fprintf(stdout,
+                   "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
+                   principal_data[i].name, principal_data[i].instance,
+                   principal_data[i].kdc_key_ver);
+           editpw = 1;
+           changed = 0;
+           if (!creating) {
+               /*
+                * copy the existing data so we can use the old values
+                * for the qualifier clause of the replace 
+                */
+               principal_data[i].old = (char *) &old_principal;
+               bcopy(&principal_data[i], &old_principal,
+                     sizeof(old_principal));
+               printf("\nChange password [n] ? ");
+               z_fgets(temp, sizeof temp, stdin);
+               if (strcmp("y", temp) && strcmp("Y", temp))
+                   editpw = 0;
+           }
+           fflush(stdout);
+           /* password */
+           if (editpw) {
+#ifdef NOENCRYPTION
+               placebo_read_pw_string(pw_str, sizeof pw_str,
+                   "\nNew Password: ", TRUE);
+#else
+                des_read_pw_string(pw_str, sizeof pw_str,
+                       "\nNew Password: ", TRUE);
+#endif
+               if (   strcmp(pw_str, "RANDOM") == 0
+                   || strcmp(pw_str, "") == 0) {
+                   printf("\nRandom password [y] ? ");
+                   z_fgets(temp, sizeof temp, stdin);
+                   if (!strcmp("n", temp) || !strcmp("N", temp)) {
+                       /* no, use literal */
+#ifdef NOENCRYPTION
+                       bzero(new_key, sizeof(des_cblock));
+                       new_key[0] = 127;
+#else
+                       des_string_to_key(pw_str, &new_key);
+#endif
+                       bzero(pw_str, sizeof pw_str);   /* "RANDOM" */
+                   } else {
+#ifdef NOENCRYPTION
+                       bzero(new_key, sizeof(des_cblock));
+                       new_key[0] = 127;
+#else
+                       des_new_random_key(&new_key);
+#endif
+                       bzero(pw_str, sizeof pw_str);
+                   }
+               } else if (!strcmp(pw_str, "NULL")) {
+                   printf("\nNull Key [y] ? ");
+                   z_fgets(temp, sizeof temp, stdin);
+                   if (!strcmp("n", temp) || !strcmp("N", temp)) {
+                       /* no, use literal */
+#ifdef NOENCRYPTION
+                       bzero(new_key, sizeof(des_cblock));
+                       new_key[0] = 127;
+#else
+                       des_string_to_key(pw_str, &new_key);
+#endif
+                       bzero(pw_str, sizeof pw_str);   /* "NULL" */
+                   } else {
+
+                       principal_data[i].key_low = 0;
+                       principal_data[i].key_high = 0;
+                       goto null_key;
+                   }
+               } else {
+#ifdef NOENCRYPTION
+                   bzero(new_key, sizeof(des_cblock));
+                   new_key[0] = 127;
+#else
+                   des_string_to_key(pw_str, &new_key);
+#endif
+                   bzero(pw_str, sizeof pw_str);
+               }
+
+               /* seal it under the kerberos master key */
+               kdb_encrypt_key (&new_key, &new_key, 
+                                &master_key, master_key_schedule,
+                                DES_ENCRYPT);
+               bcopy(new_key, &principal_data[i].key_low, 4);
+               bcopy(((long *) new_key) + 1,
+                   &principal_data[i].key_high, 4);
+               bzero(new_key, sizeof(new_key));
+       null_key:
+               /* set master key version */
+               principal_data[i].kdc_key_ver =
+                   (unsigned char) master_key_version;
+               /* bump key version # */
+               principal_data[i].key_version++;
+               fprintf(stdout,
+                       "\nPrincipal's new key version = %d\n",
+                       principal_data[i].key_version);
+               fflush(stdout);
+               changed = 1;
+           }
+           /* expiration date */
+           fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+                   principal_data[i].exp_date_txt);
+           zaptime(&edate);
+           while (z_fgets(temp, sizeof temp, stdin) &&
+                  ((n = strlen(temp)) >
+                   sizeof(principal_data[0].exp_date_txt))) {
+           bad_date:
+               fprintf(stdout, "\07\07Date Invalid\n");
+               fprintf(stdout,
+                       "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+                       principal_data[i].exp_date_txt);
+               zaptime(&edate);
+           }
+
+           if (*temp) {
+               if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
+                             &edate.tm_mon, &edate.tm_mday) != 3)
+                   goto bad_date;
+               (void) strcpy(principal_data[i].exp_date_txt, temp);
+               edate.tm_mon--;         /* January is 0, not 1 */
+               edate.tm_hour = 23;     /* nearly midnight at the end of the */
+               edate.tm_min = 59;      /* specified day */
+               if (!(principal_data[i].exp_date = maketime(&edate, 1)))
+                   goto bad_date;
+               changed = 1;
+           }
+
+           /* maximum lifetime */
+           fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+                   principal_data[i].max_life);
+           while (z_fgets(temp, sizeof temp, stdin) && *temp) {
+               if (sscanf(temp, "%ld", &temp_long) != 1)
+                   goto bad_life;
+               if (temp_long > 255 || (temp_long < 0)) {
+               bad_life:
+                   fprintf(stdout, "\07\07Invalid, choose 0-255\n");
+                   fprintf(stdout,
+                           "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+                           principal_data[i].max_life);
+                   continue;
+               }
+               changed = 1;
+               /* dont clobber */
+               principal_data[i].max_life = (unsigned short) temp_long;
+               break;
+           }
+
+           /* attributes */
+           fprintf(stdout, "Attributes [ %d ] ? ",
+                   principal_data[i].attributes);
+           while (z_fgets(temp, sizeof temp, stdin) && *temp) {
+               if (sscanf(temp, "%ld", &temp_long) != 1)
+                   goto bad_att;
+               if (temp_long > 65535 || (temp_long < 0)) {
+               bad_att:
+                   fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
+                   fprintf(stdout, "Attributes [ %d ] ? ",
+                           principal_data[i].attributes);
+                   continue;
+               }
+               changed = 1;
+               /* dont clobber */
+               principal_data[i].attributes =
+                   (unsigned short) temp_long;
+               break;
+           }
+
+           /*
+            * remaining fields -- key versions and mod info, should
+            * not be directly manipulated 
+            */
+           if (changed) {
+               if (kerb_put_principal(&principal_data[i], 1)) {
+                   fprintf(stdout,
+                       "\nError updating Kerberos database");
+               } else {
+                   fprintf(stdout, "Edit O.K.");
+               }
+           } else {
+               fprintf(stdout, "Unchanged");
+           }
+
+
+           bzero(&principal_data[i].key_low, 4);
+           bzero(&principal_data[i].key_high, 4);
+           fflush(stdout);
+           break;
+       }
+    }
+    if (more) {
+       fprintf(stdout, "\nThere were more tuples found ");
+       fprintf(stdout, "than there were space for");
+      }
+    return 1;
+}
+
+static void
+cleanup(void)
+{
+
+    bzero(master_key, sizeof(master_key));
+    bzero(session_key, sizeof(session_key));
+    bzero(master_key_schedule, sizeof(master_key_schedule));
+    bzero(principal_data, sizeof(principal_data));
+    bzero(new_key, sizeof(new_key));
+    bzero(pw_str, sizeof(pw_str));
+}
+
+int
+main(int argc, char **argv)
+{
+    /* Local Declarations */
+
+    long    n;
+
+    prog[sizeof prog - 1] = '\0';      /* make sure terminated */
+    strncpy(prog, argv[0], sizeof prog - 1);   /* salt away invoking
+                                                * program */
+
+    /* Assume a long is four bytes */
+    if (sizeof(long) != 4) {
+       fprintf(stdout, "%s: size of long is %d.\n", prog, (int)sizeof(long));
+       exit(-1);
+    }
+    /* Assume <=32 signals */
+    if (NSIG > 32) {
+       fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
+       exit(-1);
+    }
+    while (--argc > 0 && (*++argv)[0] == '-')
+       for (i = 1; argv[0][i] != '\0'; i++) {
+           switch (argv[0][i]) {
+
+               /* debug flag */
+           case 'd':
+               debug = 1;
+               continue;
+
+               /* debug flag */
+#ifdef DEBUG
+           case 'l':
+               kerb_debug |= 1;
+               continue;
+#endif
+           case 'n':           /* read MKEYFILE for master key */
+               nflag = 1;
+               continue;
+
+           default:
+               fprintf(stderr, "%s: illegal flag \"%c\"\n",
+                       progname, argv[0][i]);
+               Usage();        /* Give message and die */
+           }
+       };
+
+    fprintf(stdout, "Opening database...\n");
+    fflush(stdout);
+    kerb_init();
+    if (argc > 0) {
+       if (kerb_db_set_name(*argv) != 0) {
+           fprintf(stderr, "Could not open altername database name\n");
+           exit(1);
+       }
+    }
+
+#ifdef notdef
+    no_core_dumps();           /* diddle signals to avoid core dumps! */
+
+    /* ignore whatever is reasonable */
+    signal(SIGHUP, SIG_IGN);
+    signal(SIGINT, SIG_IGN);
+    signal(SIGTSTP, SIG_IGN);
+
+#endif
+
+    if (kdb_get_master_key ((nflag == 0), 
+                           &master_key, master_key_schedule) != 0) {
+      fprintf (stdout, "Couldn't read master key.\n");
+      fflush (stdout);
+      exit (-1);
+    }
+
+    if ((master_key_version = kdb_verify_master_key(&master_key,
+                                                   master_key_schedule,
+                                                   stdout)) < 0)
+      exit (-1);
+
+    /* Initialize non shared random sequence */
+    des_init_random_number_generator(&master_key);
+
+    /* lookup the default values */
+    n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+                          &default_princ, 1, &more);
+    if (n != 1) {
+       fprintf(stderr,
+            "%s: Kerberos error on default value lookup, %ld found.\n",
+               progname, n);
+       exit(-1);
+    }
+    fprintf(stdout, "Previous or default values are in [brackets] ,\n");
+    fprintf(stdout, "enter return to leave the same, or new value.\n");
+
+    while (change_principal()) {
+    }
+
+    cleanup();
+    exit(0);
+}
+
+#if 0
+static void
+sig_exit(sig, code, scp)
+    int     sig, code;
+    struct sigcontext *scp;
+{
+    cleanup();
+    fprintf(stderr,
+       "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
+        sig, code, scp->sc_pc);
+    exit(-1);
+}
+
+static void
+no_core_dumps()
+{
+    signal(SIGQUIT, sig_exit);
+    signal(SIGILL, sig_exit);
+    signal(SIGTRAP, sig_exit);
+    signal(SIGIOT, sig_exit);
+    signal(SIGEMT, sig_exit);
+    signal(SIGFPE, sig_exit);
+    signal(SIGBUS, sig_exit);
+    signal(SIGSEGV, sig_exit);
+    signal(SIGSYS, sig_exit);
+}
+#endif
diff --git a/kerberosIV/kdb_edit/maketime.c b/kerberosIV/kdb_edit/maketime.c
new file mode 100644 (file)
index 0000000..3264dd8
--- /dev/null
@@ -0,0 +1,88 @@
+/*     $Id: maketime.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Convert a struct tm * to a UNIX time.
+ */
+
+#include <adm_locl.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(struct tm *tp, int local)
+{
+    register long retval;
+    int foo;
+    int *marray;
+
+    if (tp->tm_mon < 0 || tp->tm_mon > 11 ||
+       tp->tm_hour < 0 || tp->tm_hour > 23 ||
+       tp->tm_min < 0 || tp->tm_min > 59 ||
+       tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */
+       return 0;
+
+    retval = 0;
+    if (tp->tm_year < 1900)
+       foo = tp->tm_year + 1900;
+    else
+       foo = tp->tm_year;
+
+    if (foo < 1901 || foo > 2038)      /* year is too small/large */
+       return 0;
+
+    if (daysinyear(foo) == 366) {
+       if (tp->tm_mon > 1)
+           retval+= SECSPERDAY;        /* add leap day */
+       marray = leapyear;
+    } else
+       marray = nonleapyear;
+
+    if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon])
+       return 0;                       /* out of range */
+
+    while (--foo >= 1970)
+       retval += daysinyear(foo) * SECSPERDAY;
+
+    retval += cumdays[tp->tm_mon] * SECSPERDAY;
+    retval += (tp->tm_mday-1) * SECSPERDAY;
+    retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec;
+
+    if (local) {
+       /* need to use local time, so we retrieve timezone info */
+       struct timezone tz;
+       struct timeval tv;
+       if (gettimeofday(&tv, &tz) < 0) {
+           /* some error--give up? */
+           return(retval);
+       }
+       retval += tz.tz_minuteswest * SECSPERMIN;
+    }
+    return(retval);
+}
diff --git a/kerberosIV/kdb_init/Makefile b/kerberosIV/kdb_init/Makefile
new file mode 100644 (file)
index 0000000..3672139
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+
+PROG=  kdb_init
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   kdb_init.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kdb_init/kdb_init.8 b/kerberosIV/kdb_init/kdb_init.8
new file mode 100644 (file)
index 0000000..92314db
--- /dev/null
@@ -0,0 +1,40 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kdb_init.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_init \- Initialize Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_init [ 
+.B realm
+]
+.SH DESCRIPTION
+.I kdb_init
+initializes a Kerberos key distribution center database, creating the
+necessary principals.
+.PP
+If the optional
+.I realm
+argument is not present,
+.I kdb_init
+prompts for a realm name (defaulting to the definition in /usr/include/krb.h).
+After determining the realm to be created, it prompts for
+a master key password.  The master key password is used to encrypt
+every encryption key stored in the database.
+.SH DIAGNOSTICS
+.TP 20n
+"/kerberos/principal: File exists"
+An attempt was made to create a database on a machine which already had
+an existing database.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/usr/include/krb.h
+Include file defining default realm
+.SH SEE ALSO
+kdb_destroy(8)
diff --git a/kerberosIV/kdb_init/kdb_init.c b/kerberosIV/kdb_init/kdb_init.c
new file mode 100644 (file)
index 0000000..9866e54
--- /dev/null
@@ -0,0 +1,173 @@
+/*     $Id: kdb_init.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * program to initialize the database,  reports error if database file
+ * already exists. 
+ */
+
+#include <adm_locl.h>
+
+enum ap_op {
+    NULL_KEY,                  /* setup null keys */
+    MASTER_KEY,                 /* use master key as new key */
+    RANDOM_KEY                 /* choose a random key */
+};
+
+char   *progname;
+static des_cblock master_key;
+static des_key_schedule master_key_schedule;
+
+/* use a return code to indicate success or failure.  check the return */
+/* values of the routines called by this routine. */
+
+static int
+add_principal(char *name, char *instance, enum ap_op aap_op)
+{
+    Principal principal;
+    struct tm *tm;
+    des_cblock new_key;
+
+    bzero(&principal, sizeof(principal));
+    strncpy(principal.name, name, ANAME_SZ);
+    strncpy(principal.instance, instance, INST_SZ);
+    switch (aap_op) {
+    case NULL_KEY:
+       principal.key_low = 0;
+       principal.key_high = 0;
+       break;
+    case RANDOM_KEY:
+#ifdef NOENCRYPTION
+       bzero(new_key, sizeof(des_cblock));
+       new_key[0] = 127;
+#else
+       des_new_random_key(&new_key);
+#endif
+       kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
+                        DES_ENCRYPT);
+       bcopy(new_key, &principal.key_low, 4);
+       bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+       break;
+    case MASTER_KEY:
+       bcopy (master_key, new_key, sizeof (des_cblock));
+       kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
+                        DES_ENCRYPT);
+       bcopy(new_key, &principal.key_low, 4);
+       bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+       break;
+    }
+    principal.exp_date = 946702799;    /* Happy new century */
+    strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ);
+    principal.mod_date = time(0);
+
+    tm = k_localtime(&principal.mod_date);
+    principal.attributes = 0;
+    principal.max_life = 255;
+
+    principal.kdc_key_ver = 1;
+    principal.key_version = 1;
+
+    strncpy(principal.mod_name, "db_creation", ANAME_SZ);
+    strncpy(principal.mod_instance, "", INST_SZ);
+    principal.old = 0;
+
+    if (kerb_db_put_principal(&principal, 1) != 1)
+        return -1;             /* FAIL */
+    
+    /* let's play it safe */
+    bzero (new_key, sizeof (des_cblock));
+    bzero (&principal.key_low, 4);
+    bzero (&principal.key_high, 4);
+    return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+    char    realm[REALM_SZ];
+    char   *cp;
+    int code;
+    char *database;
+    
+    progname = (cp = strrchr(*argv, '/')) ? cp + 1 : *argv;
+
+    if (argc > 3) {
+       fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
+       exit(1);
+    }
+    if (argc == 3) {
+       database = argv[2];
+       --argc;
+    } else
+       database = DBM_FILE;
+
+    /* Do this first, it'll fail if the database exists */
+    if ((code = kerb_db_create(database)) != 0) {
+       fprintf(stderr, "Couldn't create database: %s\n",
+               strerror(code));
+       exit(1);
+    }
+    kerb_db_set_name(database);
+
+    if (argc == 2)
+       strncpy(realm, argv[1], REALM_SZ);
+    else {
+       fprintf(stderr, "Realm name [default  %s ]: ", KRB_REALM);
+       if (fgets(realm, sizeof(realm), stdin) == NULL) {
+           fprintf(stderr, "\nEOF reading realm\n");
+           exit(1);
+       }
+       if ((cp = strchr(realm, '\n')))
+           *cp = '\0';
+       if (!*realm)                    /* no realm given */
+           strcpy(realm, KRB_REALM);
+    }
+    if (!k_isrealm(realm)) {
+       fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n",
+               progname, realm);
+       exit(1);
+    }
+    printf("You will be prompted for the database Master Password.\n");
+    printf("It is important that you NOT FORGET this password.\n");
+    fflush(stdout);
+
+    if (kdb_get_master_key (TRUE, &master_key, master_key_schedule) != 0) {
+      fprintf (stderr, "Couldn't read master key.\n");
+      exit (-1);
+    }
+
+    /* Initialize non shared random sequence */
+    des_init_random_number_generator(&master_key);
+
+    if (
+       add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) ||
+       add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) ||
+       add_principal("krbtgt", realm, RANDOM_KEY) ||
+       add_principal("changepw", KRB_MASTER, RANDOM_KEY) 
+       ) {
+       fprintf(stderr, "\n%s: couldn't initialize database.\n",
+               progname);
+       exit(1);
+    }
+
+    /* play it safe */
+    bzero (master_key, sizeof (des_cblock));
+    bzero (master_key_schedule, sizeof (des_key_schedule));
+    exit(0);
+}
diff --git a/kerberosIV/kdb_util/Makefile b/kerberosIV/kdb_util/Makefile
new file mode 100644 (file)
index 0000000..8916b72
--- /dev/null
@@ -0,0 +1,11 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+
+PROG=  kdb_util
+SRCS=  kdb_util.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   kdb_util.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kdb_util/kdb_util.8 b/kerberosIV/kdb_util/kdb_util.8
new file mode 100644 (file)
index 0000000..523bdf3
--- /dev/null
@@ -0,0 +1,63 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kdb_util.8,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $
+.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_util \-  Kerberos key distribution center database utility
+.SH SYNOPSIS
+kdb_util 
+.B operation filename
+.SH DESCRIPTION
+.I kdb_util
+allows the Kerberos key distribution center (KDC) database administrator to
+perform utility functions on the database.
+.PP
+.I Operation
+must be one of the following:
+.TP 10n
+.I load
+initializes the KDC database with the records described by the
+text contained in the file
+.IR filename .
+Any existing database is overwritten.
+.TP
+.I dump
+dumps the KDC database into a text representation in the file
+.IR filename .
+.TP
+.I slave_dump
+performs a database dump like the
+.I dump
+operation, and additionally creates a semaphore file signalling the
+propagation software that an update is available for distribution to
+slave KDC databases.
+.TP
+.I new_master_key
+prompts for the old and new master key strings, and then dumps the KDC
+database into a text representation in the file
+.IR filename .
+The keys in the text representation are encrypted in the new master key.
+.TP
+.I convert_old_db
+prompts for the master key string, and then dumps the KDC database into
+a text representation in the file
+.IR filename .
+The existing database is assumed to be encrypted using the old format
+(encrypted by the key schedule of the master key); the dumped database
+is encrypted using the new format (encrypted directly with master key).
+.PP
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+.IR filename .ok
+semaphore file created by
+.IR slave_dump.
diff --git a/kerberosIV/kdb_util/kdb_util.c b/kerberosIV/kdb_util/kdb_util.c
new file mode 100644 (file)
index 0000000..2805e2e
--- /dev/null
@@ -0,0 +1,484 @@
+/*     $Id: kdb_util.c,v 1.1.1.1 1995/12/14 06:52:42 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Kerberos database manipulation utility. This program allows you to
+ * dump a kerberos database to an ascii readable file and load this
+ * file into the database. Read locking of the database is done during a
+ * dump operation. NO LOCKING is done during a load operation. Loads
+ * should happen with other processes shutdown. 
+ *
+ * Written July 9, 1987 by Jeffrey I. Schiller
+ */
+
+#include <adm_locl.h>
+
+static char *prog; 
+
+Principal aprinc;
+
+static des_cblock master_key, new_master_key;
+static des_key_schedule master_key_schedule, new_master_key_schedule;
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+/* cv_key is a procedure which takes a principle and changes its key, 
+   either for a new method of encrypting the keys, or a new master key.
+   if cv_key is null no transformation of key is done (other than net byte
+   order). */
+
+struct callback_args {
+    void (*cv_key)();
+    FILE *output_file;
+};
+
+static void
+print_time(FILE *file, time_t timeval)
+{
+    struct tm *tm;
+    tm = gmtime(&timeval);
+    fprintf(file, " %04d%02d%02d%02d%02d",
+            tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,
+            tm->tm_mon + 1,
+            tm->tm_mday,
+            tm->tm_hour,
+            tm->tm_min);
+}
+
+static long
+time_explode(char *cp)
+{
+    char wbuf[5];
+    struct tm tp;
+    long maketime(struct tm *tp, int local);
+    int local;
+
+    zaptime(&tp);                      /* clear out the struct */
+    
+    if (strlen(cp) > 10) {             /* new format */
+       (void) strncpy(wbuf, cp, 4);
+       wbuf[4] = 0;
+       tp.tm_year = atoi(wbuf);
+       cp += 4;                        /* step over the year */
+       local = 0;                      /* GMT */
+    } else {                           /* old format: local time, 
+                                          year is 2 digits, assuming 19xx */
+       wbuf[0] = *cp++;
+       wbuf[1] = *cp++;
+       wbuf[2] = 0;
+       tp.tm_year = 1900 + atoi(wbuf);
+       local = 1;                      /* local */
+    }
+
+    wbuf[0] = *cp++;
+    wbuf[1] = *cp++;
+    wbuf[2] = 0;
+    tp.tm_mon = atoi(wbuf)-1;
+
+    wbuf[0] = *cp++;
+    wbuf[1] = *cp++;
+    tp.tm_mday = atoi(wbuf);
+    
+    wbuf[0] = *cp++;
+    wbuf[1] = *cp++;
+    tp.tm_hour = atoi(wbuf);
+    
+    wbuf[0] = *cp++;
+    wbuf[1] = *cp++;
+    tp.tm_min = atoi(wbuf);
+
+
+    return(maketime(&tp, local));
+}
+
+static int
+dump_db_1(char *arg, Principal *principal)
+{          /* replace null strings with "*" */
+    struct callback_args *a = (struct callback_args *)arg;
+    
+    if (principal->instance[0] == '\0') {
+       principal->instance[0] = '*';
+       principal->instance[1] = '\0';
+    }
+    if (principal->mod_name[0] == '\0') {
+       principal->mod_name[0] = '*';
+       principal->mod_name[1] = '\0';
+    }
+    if (principal->mod_instance[0] == '\0') {
+       principal->mod_instance[0] = '*';
+       principal->mod_instance[1] = '\0';
+    }
+    if (a->cv_key != NULL) {
+       (*a->cv_key) (principal);
+    }
+    fprintf(a->output_file, "%s %s %d %d %d %d %x %x",
+           principal->name,
+           principal->instance,
+           principal->max_life,
+           principal->kdc_key_ver,
+           principal->key_version,
+           principal->attributes,
+           (int)htonl (principal->key_low),
+           (int)htonl (principal->key_high));
+    print_time(a->output_file, principal->exp_date);
+    print_time(a->output_file, principal->mod_date);
+    fprintf(a->output_file, " %s %s\n",
+           principal->mod_name,
+           principal->mod_instance);
+    return 0;
+}
+
+static int
+dump_db (char *db_file, FILE *output_file, void (*cv_key) (Principal *))
+{
+    struct callback_args a;
+
+    a.cv_key = cv_key;
+    a.output_file = output_file;
+    
+    kerb_db_iterate (dump_db_1, (char *)&a);
+    return fflush(output_file);
+}
+
+static void
+load_db (char *db_file, FILE *input_file)
+{
+    char    exp_date_str[50];
+    char    mod_date_str[50];
+    int     temp1, temp2, temp3;
+    int code;
+    char *temp_db_file;
+    temp1 = strlen(db_file)+2;
+    temp_db_file = malloc (temp1);
+    strcpy(temp_db_file, db_file);
+    strcat(temp_db_file, "~");
+
+    /* Create the database */
+    if ((code = kerb_db_create(temp_db_file)) != 0) {
+       fprintf(stderr, "Couldn't create temp database %s: %s\n",
+               temp_db_file, strerror(code));
+       exit(1);
+    }
+    kerb_db_set_name(temp_db_file);
+    for (;;) {                 /* explicit break on eof from fscanf */
+        u_long key_lo, key_hi; /* Must match format string */
+       bzero((char *)&aprinc, sizeof(aprinc));
+       if (fscanf(input_file,
+                  "%s %s %d %d %d %hd %lx %lx %s %s %s %s\n",
+                  aprinc.name,
+                  aprinc.instance,
+                  &temp1,
+                  &temp2,
+                  &temp3,
+                  &aprinc.attributes,
+                  &key_lo,
+                  &key_hi,
+                  exp_date_str,
+                  mod_date_str,
+                  aprinc.mod_name,
+                  aprinc.mod_instance) == EOF)
+           break;
+       aprinc.key_low = ntohl (key_lo);
+       aprinc.key_high = ntohl (key_hi);
+       aprinc.max_life = (unsigned char) temp1;
+       aprinc.kdc_key_ver = (unsigned char) temp2;
+       aprinc.key_version = (unsigned char) temp3;
+       aprinc.exp_date = time_explode(exp_date_str);
+       aprinc.mod_date = time_explode(mod_date_str);
+       if (aprinc.instance[0] == '*')
+           aprinc.instance[0] = '\0';
+       if (aprinc.mod_name[0] == '*')
+           aprinc.mod_name[0] = '\0';
+       if (aprinc.mod_instance[0] == '*')
+           aprinc.mod_instance[0] = '\0';
+       if (kerb_db_put_principal(&aprinc, 1) != 1) {
+           fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",
+                   aprinc.name, aprinc.instance,
+                   strerror(errno));
+           exit(1);
+       };
+    }
+    if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
+       perror("database rename failed");
+    (void) fclose(input_file);
+    free(temp_db_file);
+}
+
+/*ARGSUSED*/
+static void
+update_ok_file (char *file_name)
+{
+    /* handle slave locking/failure stuff */
+    char *file_ok;
+    int fd;
+    static char ok[]=".dump_ok";
+
+    if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
+       == NULL) {
+       fprintf(stderr, "kdb_util: out of memory.\n");
+       (void) fflush (stderr);
+       perror ("malloc");
+       exit (1);
+    }
+    strcpy(file_ok, file_name);
+    strcat(file_ok, ok);
+    if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {
+       fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);
+       perror("");
+       (void) fflush (stderr);
+       exit (1);
+    }
+    free(file_ok);
+    close(fd);
+}
+
+static void
+convert_key_new_master (Principal *p)
+{
+  des_cblock key;
+
+  /* leave null keys alone */
+  if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+  /* move current key to des_cblock for encryption, special case master key
+     since that's changing */
+  if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
+      (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
+    bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));
+    (p->key_version)++;
+  } else {
+    bcopy((char *)&(p->key_low), (char *)key, 4);
+    bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);
+    kdb_encrypt_key (&key, &key, &master_key, master_key_schedule, DES_DECRYPT);
+  }
+
+  kdb_encrypt_key (&key, &key, &new_master_key, new_master_key_schedule, DES_ENCRYPT);
+
+  bcopy((char *)key, (char *)&(p->key_low), 4);
+  bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+  bzero((char *)key, sizeof (key));  /* a little paranoia ... */
+
+  (p->kdc_key_ver)++;
+}
+
+static void
+clear_secrets (void)
+{
+  bzero((char *)master_key, sizeof (des_cblock));
+  bzero((char *)master_key_schedule, sizeof (des_key_schedule));
+  bzero((char *)new_master_key, sizeof (des_cblock));
+  bzero((char *)new_master_key_schedule, sizeof (des_key_schedule));
+}
+
+static void
+convert_new_master_key (char *db_file, FILE *out)
+{
+
+  printf ("\n\nEnter the CURRENT master key.");
+  if (kdb_get_master_key (TRUE, &master_key, master_key_schedule) != 0) {
+    fprintf (stderr, "%s: Couldn't get master key.\n", prog);
+    clear_secrets ();
+    exit (-1);
+  }
+
+  if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
+    clear_secrets ();
+    exit (-1);
+  }
+
+  printf ("\n\nNow enter the NEW master key.  Do not forget it!!");
+  if (kdb_get_master_key (TRUE, &new_master_key, new_master_key_schedule) != 0) {
+    fprintf (stderr, "%s: Couldn't get new master key.\n", prog);
+    clear_secrets ();
+    exit (-1);
+  }
+
+  dump_db (db_file, out, convert_key_new_master);
+}
+
+static void
+convert_key_old_db (Principal *p)
+{
+  des_cblock key;
+
+ /* leave null keys alone */
+  if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+  bcopy((char *)&(p->key_low), (char *)key, 4);
+  bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);
+
+#ifndef NOENCRYPTION
+  des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key,
+       (long)sizeof(des_cblock),master_key_schedule,
+       (des_cblock *)master_key_schedule, DES_DECRYPT);
+#endif
+
+  /* make new key, new style */
+  kdb_encrypt_key (&key, &key, &master_key, master_key_schedule, DES_ENCRYPT);
+
+  bcopy((char *)key, (char *)&(p->key_low), 4);
+  bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+  bzero((char *)key, sizeof (key));  /* a little paranoia ... */
+}
+
+static void
+convert_old_format_db (char *db_file, FILE *out)
+{
+  des_cblock key_from_db;
+  Principal principal_data[1];
+  int n, more;
+
+  if (kdb_get_master_key (TRUE, &master_key, master_key_schedule) != 0L) {
+    fprintf (stderr, "%s: Couldn't get master key.\n", prog);
+    clear_secrets();
+    exit (-1);
+  }
+
+  /* can't call kdb_verify_master_key because this is an old style db */
+  /* lookup the master key version */
+  n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+                        1 /* only one please */, &more);
+  if ((n != 1) || more) {
+    fprintf(stderr, "verify_master_key: Kerberos error on master key lookup, %d found.\n", n);
+    exit (-1);
+  }
+
+  /* set up the master key */
+  fprintf(stderr, "Current Kerberos master key version is %d.\n",
+         principal_data[0].kdc_key_ver);
+
+  /*
+   * now use the master key to decrypt (old style) the key in the db, had better
+   * be the same! 
+   */
+  bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);
+  bcopy((char *)&principal_data[0].key_high,
+       (char *)(((long *) key_from_db) + 1), 4);
+#ifndef NOENCRYPTION
+  des_pcbc_encrypt(&key_from_db,&key_from_db,(long)sizeof(key_from_db),
+       master_key_schedule,(des_cblock *)master_key_schedule, DES_DECRYPT);
+#endif
+  /* the decrypted database key had better equal the master key */
+  n = bcmp((char *) master_key, (char *) key_from_db,
+          sizeof(master_key));
+  bzero((char *)key_from_db, sizeof(key_from_db));
+
+  if (n) {
+    fprintf(stderr, "\n\07\07verify_master_key: Invalid master key, ");
+    fprintf(stderr, "does not match database.\n");
+    exit (-1);
+  }
+    
+  fprintf(stderr, "Master key verified.\n");
+  (void) fflush(stderr);
+
+  dump_db (db_file, out, convert_key_old_db);
+}
+
+int
+main(int argc, char **argv)
+{
+    FILE   *file;
+    enum {
+       OP_LOAD,
+       OP_DUMP,
+       OP_SLAVE_DUMP,
+       OP_NEW_MASTER,
+       OP_CONVERT_OLD_DB
+    }       op;
+    char *file_name;
+    char *db_name;
+    prog = argv[0];
+    
+    if (argc != 3 && argc != 4) {
+       fprintf(stderr, "Usage: %s operation file-name [database name].\n",
+               argv[0]);
+       exit(1);
+    }
+    if (argc == 3)
+       db_name = DBM_FILE;
+    else
+       db_name = argv[3];
+
+    if (kerb_db_set_name (db_name) != 0) {
+       perror("Can't open database");
+       exit(1);
+    }
+    
+    if (!strcmp(argv[1], "load"))
+       op = OP_LOAD;
+    else if (!strcmp(argv[1], "dump"))
+       op = OP_DUMP;
+    else if (!strcmp(argv[1], "slave_dump"))
+        op = OP_SLAVE_DUMP;
+    else if (!strcmp(argv[1], "new_master_key"))
+        op = OP_NEW_MASTER;
+    else if (!strcmp(argv[1], "convert_old_db"))
+        op = OP_CONVERT_OLD_DB;
+    else {
+       fprintf(stderr,
+           "%s: %s is an invalid operation.\n", prog, argv[1]);
+       fprintf(stderr,
+           "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);
+       fprintf(stderr,
+               "\"load\", \"new_master_key\", and \"convert_old_db\".\n");
+       exit(1);
+    }
+
+    file_name = argv[2];
+    file = fopen(file_name, op == OP_LOAD ? "r" : "w");
+    if (file == NULL) {
+       fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);
+       (void) fflush(stderr);
+       perror("open");
+       exit(1);
+    }
+
+    switch (op) {
+    case OP_DUMP:
+      if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+         (fclose(file) == EOF)) {
+         fprintf(stderr, "error on file %s:", file_name);
+         perror("");
+         exit(1);
+      }
+      break;
+    case OP_SLAVE_DUMP:
+      if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+         (fclose(file) == EOF)) {
+         fprintf(stderr, "error on file %s:", file_name);
+         perror("");
+         exit(1);
+      }
+      update_ok_file (file_name);
+      break;
+    case OP_LOAD:
+      load_db (db_name, file);
+      break;
+    case OP_NEW_MASTER:
+      convert_new_master_key (db_name, file);
+      printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+      break;
+    case OP_CONVERT_OLD_DB:
+      convert_old_format_db (db_name, file);
+      printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);      
+      break;
+    }
+    exit(0);
+  }
diff --git a/kerberosIV/kdestroy/Makefile b/kerberosIV/kdestroy/Makefile
new file mode 100644 (file)
index 0000000..6bef35d
--- /dev/null
@@ -0,0 +1,8 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+
+PROG=  kdestroy
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+BINDIR=        /usr/bin
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kdestroy/kdestroy.1 b/kerberosIV/kdestroy/kdestroy.1
new file mode 100644 (file)
index 0000000..0fd7d4d
--- /dev/null
@@ -0,0 +1,80 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kdestroy.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $
+.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdestroy \- destroy Kerberos tickets
+.SH SYNOPSIS
+.B kdestroy
+[
+.B \-f
+]
+[
+.B \-q
+]
+.SH DESCRIPTION
+The
+.I kdestroy
+utility destroys the user's active
+Kerberos
+authorization tickets by writing zeros to the file that contains them.
+If the ticket file does not exist,
+.I kdestroy
+displays a message to that effect.
+.PP
+After overwriting the file,
+.I kdestroy
+removes the file from the system.
+The utility
+displays a message indicating the success or failure of the
+operation.
+If
+.I kdestroy
+is unable to destroy the ticket file,
+the utility will warn you by making your terminal beep.
+.PP
+In the Athena workstation environment,
+the
+.I toehold
+service automatically destroys your tickets when you
+end a workstation session.
+If your site does not provide a similar ticket-destroying mechanism,
+you can place the
+.I kdestroy
+command in your
+.I .logout
+file so that your tickets are destroyed automatically
+when you logout.
+.PP
+The options to
+.I kdestroy
+are as follows:
+.TP 7
+.B \-f
+.I kdestroy
+runs without displaying the status message.
+.TP
+.B \-q
+.I kdestroy
+will not make your terminal beep if it fails to destroy the tickets.
+.SH FILES
+KRBTKFILE environment variable if set, otherwise
+.br
+/tmp/tkt[uid]
+.SH SEE ALSO
+kerberos(1), kinit(1), klist(1)
+.SH BUGS
+.PP
+Only the tickets in the user's current ticket file are destroyed.
+Separate ticket files are used to hold root instance and password
+changing tickets.  These files should probably be destroyed too, or
+all of a user's tickets kept in a single ticket file.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+.br
+Bill Sommerfeld, MIT Project Athena
diff --git a/kerberosIV/kdestroy/kdestroy.c b/kerberosIV/kdestroy/kdestroy.c
new file mode 100644 (file)
index 0000000..c5e05d5
--- /dev/null
@@ -0,0 +1,71 @@
+/*     $Id: kdestroy.c,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * This program causes Kerberos tickets to be destroyed.
+ * Options are: 
+ *
+ *   -q[uiet]  - no bell even if tickets not destroyed
+ *   -f[orce]  - no message printed at all 
+ */
+
+#include <kuser_locl.h>
+
+static char *pname;
+
+static void
+usage()
+{
+    fprintf(stderr, "Usage: %s [-f] [-q]\n", pname);
+    exit(1);
+}
+
+int
+main(argc, argv)
+    int argc;
+    char   *argv[];
+{
+    int     fflag=0, qflag=0, k_errno;
+    register char *cp;
+
+    cp = strrchr (argv[0], '/');
+    if (cp == NULL)
+       pname = argv[0];
+    else
+       pname = cp+1;
+
+    if (argc > 2)
+       usage();
+    else if (argc == 2) {
+       if (!strcmp(argv[1], "-f"))
+           ++fflag;
+       else if (!strcmp(argv[1], "-q"))
+           ++qflag;
+       else usage();
+    }
+
+    k_errno = dest_tkt();
+
+    if (fflag) {
+       if (k_errno != 0 && k_errno != RET_TKFIL)
+           exit(1);
+       else
+           exit(0);
+    } else {
+       if (k_errno == 0)
+           printf("Tickets destroyed.\n");
+       else if (k_errno == RET_TKFIL)
+           fprintf(stderr, "No tickets to destroy.\n");
+       else {
+           fprintf(stderr, "Tickets NOT destroyed.\n");
+           if (!qflag)
+               fprintf(stderr, "\007");
+           exit(1);
+       }
+    }
+    exit(0);
+}
diff --git a/kerberosIV/kerberos/Makefile b/kerberosIV/kerberos/Makefile
new file mode 100644 (file)
index 0000000..e346e8b
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $
+
+PROG=  kerberos
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   kerberos.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kerberos/kerberos.8 b/kerberosIV/kerberos/kerberos.8
new file mode 100644 (file)
index 0000000..3fc6b62
--- /dev/null
@@ -0,0 +1,258 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kerberos.8,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $
+.TH KERBEROS 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kerberos \- introduction to the Kerberos system
+
+.SH DESCRIPTION
+The
+Kerberos
+system authenticates
+individual users in a network environment.
+After authenticating yourself to
+Kerberos,
+you can use network utilities such as
+.IR rlogin ,
+.IR rcp ,
+and
+.IR rsh
+without
+having to present passwords to remote hosts and without having to bother
+with
+.I \.rhosts
+files.
+Note that these utilities will work without passwords only if
+the remote machines you deal with
+support the
+Kerberos
+system.
+All Athena timesharing machines and public workstations support
+Kerberos.
+.PP
+Before you can use
+Kerberos,
+you must register as an Athena user,
+and you must make sure you have been added to
+the
+Kerberos
+database.
+You can use the
+.I kinit
+command to find out.
+This command
+tries to log you into the
+Kerberos
+system.
+.I kinit
+will prompt you for a username and password.
+Enter your username and password.
+If the utility lets you login without giving you a message,
+you have already been registered.
+.PP
+If you enter your username and
+.I kinit
+responds with this message:
+.nf
+
+Principal unknown (kerberos)
+
+.fi
+you haven't been registered as a
+Kerberos
+user.
+See your system administrator.
+.PP
+A Kerberos name contains three parts.
+The first is the
+.I principal name,
+which is usually a user's or service's name.
+The second is the
+.I instance,
+which in the case of a user is usually null.
+Some users may have privileged instances, however,
+such as ``root'' or ``admin''.
+In the case of a service, the instance is the
+name of the machine on which it runs; i.e. there
+can be an
+.I rlogin
+service running on the machine ABC, which
+is different from the rlogin service running on
+the machine XYZ.
+The third part of a Kerberos name
+is the
+.I realm.
+The realm corresponds to the Kerberos service providing
+authentication for the principal.
+For example, at MIT there is a Kerberos running at the
+Laboratory for Computer Science and one running at
+Project Athena.
+.PP
+When writing a Kerberos name, the principal name is
+separated from the instance (if not null) by a period,
+and the realm (if not the local realm) follows, preceded by
+an ``@'' sign.
+The following are examples of valid Kerberos names:
+.sp
+.nf
+.in +8
+billb
+jis.admin
+srz@lcs.mit.edu
+treese.root@athena.mit.edu
+.in -8
+.fi
+.PP
+When you authenticate yourself with
+Kerberos,
+through either the workstation
+.I toehold
+system or the
+.I kinit
+command,
+Kerberos
+gives you an initial
+Kerberos
+.IR ticket .
+(A
+Kerberos
+ticket
+is an encrypted protocol message that provides authentication.)
+Kerberos
+uses this ticket for network utilities
+such as
+.I rlogin
+and
+.IR rcp .
+The ticket transactions are done transparently,
+so you don't have to worry about their management.
+.PP
+Note, however, that tickets expire.
+Privileged tickets, such as root instance tickets,
+expire in a few minutes, while tickets that carry more ordinary
+privileges may be good for several hours or a day, depending on the
+installation's policy.
+If your login session extends beyond the time limit,
+you will have to re-authenticate yourself to
+Kerberos
+to get new tickets.
+Use the
+.IR kinit
+command to re-authenticate yourself.
+.PP
+If you use the
+.I kinit
+command to get your tickets,
+make sure you use the
+.I kdestroy
+command
+to destroy your tickets before you end your login session.
+You should probably put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+For more information about the
+.I kinit
+and
+.I kdestroy
+commands,
+see the
+.I kinit(1)
+and
+.I kdestroy(1)
+manual pages.
+.PP
+Currently,
+Kerberos
+supports the following network services:
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp .
+Other services are being worked on,
+such as the
+.IR pop
+mail system and NFS (network file system),
+but are not yet available.
+
+.SH "SEE ALSO"
+kdestroy(1), kinit(1), klist(1), kpasswd(1), des_crypt(3), kerberos(3),
+kadmin(8)
+.SH BUGS
+Kerberos
+will not do authentication forwarding.
+In other words,
+if you use
+.I rlogin
+to login to a remote host,
+you cannot use
+Kerberos
+services from that host
+until you authenticate yourself explicitly on that host.
+Although you may need to authenticate yourself on the remote
+host,
+be aware that when you do so,
+.I rlogin
+sends your password across the network in clear text.
+
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+
+The following people helped out on various aspects of the system:
+
+Jeff Schiller designed and wrote the administration server and its
+user interface, kadmin.
+He also wrote the dbm version of the database management system.
+
+Mark Colan developed the
+Kerberos
+versions of
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp ,
+as well as contributing work on the servers.
+
+John Ostlund developed the
+Kerberos
+versions of
+.I passwd
+and
+.IR userreg .
+
+Stan Zanarotti pioneered Kerberos in a foreign realm (LCS),
+and made many contributions based on that experience.
+
+Many people contributed code and/or useful ideas, including
+Jim Aspnes,
+Bob Baldwin,
+John Barba,
+Richard Basch,
+Jim Bloom,
+Bill Bryant,
+Rob French,
+Dan Geer,
+David Jedlinsky,
+John Kohl,
+John Kubiatowicz,
+Bob McKie,
+Brian Murphy,
+Ken Raeburn,
+Chris Reed,
+Jon Rochlis,
+Mike Shanzer,
+Bill Sommerfeld,
+Jennifer Steiner,
+Ted Ts'o,
+and
+Win Treese.
+
+.SH RESTRICTIONS
+
+COPYRIGHT 1985,1986 Massachusetts Institute of Technology
diff --git a/kerberosIV/kerberos/kerberos.c b/kerberosIV/kerberos/kerberos.c
new file mode 100644 (file)
index 0000000..a87d11c
--- /dev/null
@@ -0,0 +1,814 @@
+/*     $Id: kerberos.c,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <sys/types.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+
+#include <prot.h>
+#include <klog.h>
+#include <kdc.h>
+
+static struct sockaddr_in sina = {AF_INET};
+int     f;
+
+/* XXX several files in libkdb know about this */
+char *progname;
+
+static des_key_schedule master_key_schedule;
+static des_cblock master_key;
+
+static struct timeval kerb_time;
+static Principal a_name_data;  /* for requesting user */
+static Principal s_name_data;  /* for services requested */
+static des_cblock session_key;
+static u_char master_key_version;
+static char k_instance[INST_SZ];
+static char *lt;
+static int more;
+
+static int mflag;              /* Are we invoked manually? */
+static int lflag;              /* Have we set an alterate log file? */
+static char *log_file;         /* name of alt. log file */
+static int nflag;              /* don't check max age */
+static int rflag;              /* alternate realm specified */
+
+/* fields within the received request packet */
+static u_char req_msg_type;
+static u_char req_version;
+static char *req_name_ptr;
+static char *req_inst_ptr;
+static char *req_realm_ptr;
+static u_long req_time_ws;
+
+int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */
+
+static char local_realm[REALM_SZ];
+
+/* statistics */
+static int q_bytes;            /* current bytes remaining in queue */
+static int q_n;                /* how many consecutive non-zero
+                                * q_bytes   */
+static int max_q_bytes;
+static int max_q_n;
+static int n_auth_req;
+static int n_appl_req;
+static int n_packets;
+
+static int max_age = -1;
+static int pause_int = -1;
+
+/*
+ * Print usage message and exit.
+ */
+static void
+usage(void)
+{
+    fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname, 
+           " [-a max_age] [-l log_file] [-r realm]"
+           ," [database_pathname]"
+           );
+    exit(1);
+}
+
+/*
+ * kerb_er_reply creates an error reply packet and sends it to the
+ * client. 
+ */
+
+static void
+kerb_err_reply(struct sockaddr_in *client, KTEXT pkt, long int err, char *string)
+{
+    static KTEXT_ST e_pkt_st;
+    KTEXT   e_pkt = &e_pkt_st;
+    static char e_msg[128];
+
+    strcpy(e_msg, "\nKerberos error -- ");
+    strcat(e_msg, string);
+    cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
+                req_time_ws, err, e_msg);
+    sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr*)client, S_AD_SZ);
+}
+
+static void
+hang(void)
+{
+    if (pause_int == -1) {
+       klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
+       for (;;)
+           pause();
+    } else {
+       char buf[256];
+       sprintf(buf,  "Kerberos will wait %d seconds before dying so as not to loop init", pause_int);
+       klog(L_KRB_PERR, buf);
+       sleep(pause_int);
+       klog(L_KRB_PERR, "Do svedania....\n");
+       exit(1);
+    }
+}
+
+/*
+ * Given a pointer to a long containing the number of seconds
+ * since the beginning of time (midnight 1 Jan 1970 GMT), return
+ * a string containing the local time in the form:
+ *
+ * "25-Jan-88 10:17:56"
+ */
+
+static char *
+strtime(time_t *t)
+{
+    static char st_data[40];
+    static char *st = st_data;
+    struct tm *tm;
+    char *month_sname(int n);
+
+    tm = localtime(t);
+    (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
+                   month_sname(tm->tm_mon + 1),tm->tm_year,
+                   tm->tm_hour, tm->tm_min, tm->tm_sec);
+    return st;
+}
+
+static int
+check_princ(char *p_name, char *instance, unsigned int lifetime, Principal *p)
+{
+    static int n;
+    static int more;
+
+    n = kerb_get_principal(p_name, instance, p, 1, &more);
+    klog(L_ALL_REQ,
+        "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
+        p_name, instance, lifetime, n, 0);
+    
+    if (n < 0) {
+       lt = klog(L_KRB_PERR, "Database unavailable!");
+       hang();
+    }
+    
+    /*
+     * if more than one p_name, pick one, randomly create a session key,
+     * compute maximum lifetime, lookup authorizations if applicable,
+     * and stuff into cipher. 
+     */
+    if (n == 0) {
+       /* service unknown, log error, skip to next request */
+       lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
+           instance, 0);
+       return KERB_ERR_PRINCIPAL_UNKNOWN;
+    }
+    if (more) {
+       /* not unique, log error */
+       lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
+                 p_name, instance, 0);
+       return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
+    }
+    /* If the user's key is null, we want to return an error */
+    if ((p->key_low == 0) && (p->key_high == 0)) {
+       /* User has a null key */
+       lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
+           instance, 0);
+       return KERB_ERR_NULL_KEY;
+    }
+    if (master_key_version != p->kdc_key_ver) {
+       /* log error reply */
+       lt = klog(L_ERR_MKV,
+           "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d",
+           master_key_version, p->name, p->instance, p->kdc_key_ver,
+           0);
+       return KERB_ERR_NAME_MAST_KEY_VER;
+    }
+    /* make sure the service hasn't expired */
+    if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) {
+       /* service did expire, log it */
+       lt = klog(L_ERR_SEXP,
+           "EXPIRED \"%s\" \"%s\"  %s", p->name, p->instance,
+            strtime((time_t*)&(p->exp_date)), 0);
+       return KERB_ERR_NAME_EXP;
+    }
+    /* ok is zero */
+    return 0;
+}
+
+/* Set the key for krb_rd_req so we can check tgt */
+static int
+set_tgtkey(char *r)
+                               /* Realm for desired key */
+{
+    int     n;
+    static char lastrealm[REALM_SZ];
+    Principal p_st;
+    Principal *p = &p_st;
+    des_cblock key;
+
+    if (!strcmp(lastrealm, r))
+       return (KSUCCESS);
+
+    log("Getting key for %s", r);
+
+    n = kerb_get_principal("krbtgt", r, p, 1, &more);
+    if (n == 0)
+       return (KFAILURE);
+
+    /* unseal tgt key from master key */
+    bcopy(&p->key_low, key, 4);
+    bcopy(&p->key_high, ((long *) key) + 1, 4);
+    kdb_encrypt_key(&key, &key, &master_key,
+                   master_key_schedule, DES_DECRYPT);
+    krb_set_key(key, 0);
+    strcpy(lastrealm, r);
+    return (KSUCCESS);
+}
+
+static void
+kerberos(struct sockaddr_in *client, KTEXT pkt)
+{
+    static KTEXT_ST rpkt_st;
+    KTEXT   rpkt = &rpkt_st;
+    static KTEXT_ST ciph_st;
+    KTEXT   ciph = &ciph_st;
+    static KTEXT_ST tk_st;
+    KTEXT   tk = &tk_st;
+    static KTEXT_ST auth_st;
+    KTEXT   auth = &auth_st;
+    AUTH_DAT ad_st;
+    AUTH_DAT *ad = &ad_st;
+
+
+    static struct in_addr client_host;
+    static int msg_byte_order;
+    static int swap_bytes;
+    static u_char k_flags;
+    u_long  lifetime;
+    int     i;
+    des_cblock key;
+    des_key_schedule key_s;
+    char   *ptr;
+
+
+
+    ciph->length = 0;
+
+    client_host = client->sin_addr;
+
+    /* eval macros and correct the byte order and alignment as needed */
+    req_version = pkt_version(pkt);    /* 1 byte, version */
+    req_msg_type = pkt_msg_type(pkt);  /* 1 byte, Kerberos msg type */
+
+    req_act_vno = req_version;
+
+    /* check packet version */
+    if (req_version != KRB_PROT_VERSION) {
+       lt = klog(L_KRB_PERR,
+       "KRB prot version mismatch: KRB =%d request = %d",
+                 KRB_PROT_VERSION, req_version, 0);
+       /* send an error reply */
+       kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+       return;
+    }
+    msg_byte_order = req_msg_type & 1;
+
+    swap_bytes = 0;
+    if (msg_byte_order != HOST_BYTE_ORDER) {
+       swap_bytes++;
+    }
+    klog(L_KRB_PINFO,
+       "Prot version: %d, Byte order: %d, Message type: %d",
+        req_version, msg_byte_order, req_msg_type);
+
+    switch (req_msg_type & ~1) {
+
+    case AUTH_MSG_KDC_REQUEST:
+       {
+           u_long  req_life;   /* Requested liftime */
+           char   *service;    /* Service name */
+           char   *instance;   /* Service instance */
+
+           n_auth_req++;
+           tk->length = 0;
+           k_flags = 0;        /* various kerberos flags */
+
+
+           /* set up and correct for byte order and alignment */
+           req_name_ptr = (char *) pkt_a_name(pkt);
+           req_inst_ptr = (char *) pkt_a_inst(pkt);
+           req_realm_ptr = (char *) pkt_a_realm(pkt);
+           bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws));
+           /* time has to be diddled */
+           if (swap_bytes) {
+               swap_u_long(req_time_ws);
+           }
+           ptr = (char *) pkt_time_ws(pkt) + 4;
+
+           req_life = (unsigned char) (*ptr++);
+
+           service = ptr;
+           instance = ptr + strlen(service) + 1;
+
+           rpkt = &rpkt_st;
+           klog(L_INI_REQ,
+           "Initial ticket request Host: %s User: \"%s\" \"%s\"",
+              inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+
+           if ((i = check_princ(req_name_ptr, req_inst_ptr, 0,
+               &a_name_data))) {
+               kerb_err_reply(client, pkt, i, lt);
+               return;
+           }
+           tk->length = 0;     /* init */
+           if (strcmp(service, "krbtgt"))
+               klog(L_NTGT_INTK,
+                   "INITIAL request from %s.%s for %s.%s",
+                    req_name_ptr, req_inst_ptr, service, instance, 0);
+           /* this does all the checking */
+           if ((i = check_princ(service, instance, 0,
+               &s_name_data))) {
+               kerb_err_reply(client, pkt, i, lt);
+               return;
+           }
+           /* Bound requested lifetime with service and user */
+           lifetime = min(req_life, ((u_long) s_name_data.max_life));
+           lifetime = min(lifetime, ((u_long) a_name_data.max_life));
+
+#ifdef NOENCRYPTION
+           bzero(session_key, sizeof(des_cblock));
+#else
+           des_new_random_key(&session_key);
+#endif
+           /* unseal server's key from master key */
+           bcopy(&s_name_data.key_low, key, 4);
+           bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+           kdb_encrypt_key(&key, &key, &master_key,
+                           master_key_schedule, DES_DECRYPT);
+           /* construct and seal the ticket */
+           krb_create_ticket(tk, k_flags, a_name_data.name,
+               a_name_data.instance, local_realm,
+                client_host.s_addr, session_key, lifetime, kerb_time.tv_sec,
+                        s_name_data.name, s_name_data.instance, &key);
+           bzero(key, sizeof(key));
+           bzero(key_s, sizeof(key_s));
+
+           /*
+            * get the user's key, unseal it from the server's key, and
+            * use it to seal the cipher 
+            */
+
+           /* a_name_data.key_low a_name_data.key_high */
+           bcopy(&a_name_data.key_low, key, 4);
+           bcopy(&a_name_data.key_high, ((long *) key) + 1, 4);
+
+           /* unseal the a_name key from the master key */
+           kdb_encrypt_key(&key, &key, &master_key, 
+                           master_key_schedule, DES_DECRYPT);
+
+           create_ciph(ciph, session_key, s_name_data.name,
+                       s_name_data.instance, local_realm, lifetime,
+                 s_name_data.key_version, tk, kerb_time.tv_sec, &key);
+
+           /* clear session key */
+           bzero(session_key, sizeof(session_key));
+
+           bzero(key, sizeof(key));
+
+
+
+           /* always send a reply packet */
+           rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
+               req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
+               a_name_data.key_version, ciph);
+           sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr*)client, S_AD_SZ);
+           bzero(&a_name_data, sizeof(a_name_data));
+           bzero(&s_name_data, sizeof(s_name_data));
+           break;
+       }
+    case AUTH_MSG_APPL_REQUEST:
+       {
+           u_long  time_ws;    /* Workstation time */
+           u_long  req_life;   /* Requested liftime */
+           char   *service;    /* Service name */
+           char   *instance;   /* Service instance */
+           int     kerno;      /* Kerberos error number */
+           char    tktrlm[REALM_SZ];
+
+           n_appl_req++;
+           tk->length = 0;
+           k_flags = 0;        /* various kerberos flags */
+
+           auth->length = 4 + strlen((char*)pkt->dat + 3);
+           auth->length += (int) *(pkt->dat + auth->length) +
+               (int) *(pkt->dat + auth->length + 1) + 2;
+
+           bcopy(pkt->dat, auth->dat, auth->length);
+
+           strncpy(tktrlm, (char*)(auth->dat + 3), REALM_SZ);
+           if (set_tgtkey(tktrlm)) {
+               lt = klog(L_ERR_UNK,
+                   "FAILED realm %s unknown. Host: %s ",
+                         tktrlm, inet_ntoa(client_host));
+               kerb_err_reply(client, pkt, kerno, lt);
+               return;
+           }
+           kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr,
+               ad, 0);
+
+           if (kerno) {
+               klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
+                    inet_ntoa(client_host), krb_err_txt[kerno]);
+               kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+               return;
+           }
+           ptr = (char *) pkt->dat + auth->length;
+
+           bcopy(ptr, &time_ws, 4);
+           ptr += 4;
+
+           req_life = (unsigned char) (*ptr++);
+
+           service = ptr;
+           instance = ptr + strlen(service) + 1;
+
+           klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
+            ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host),
+                service, instance, 0);
+
+           if (strcmp(ad->prealm, tktrlm)) {
+               kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+                    "Can't hop realms");
+               return;
+           }
+           if (!strcmp(service, "changepw")) {
+               kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+                    "Can't authorize password changed based on TGT");
+               return;
+           }
+           kerno = check_princ(service, instance, req_life,
+               &s_name_data);
+           if (kerno) {
+               kerb_err_reply(client, pkt, kerno, lt);
+               return;
+           }
+           /* Bound requested lifetime with service and user */
+           lifetime = min(req_life,
+             krb_time_to_life(kerb_time.tv_sec,krb_life_to_time(ad->time_sec,ad->life)));
+           lifetime = min(lifetime, ((u_long) s_name_data.max_life));
+
+           /* unseal server's key from master key */
+           bcopy(&s_name_data.key_low, key, 4);
+           bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+           kdb_encrypt_key(&key, &key, &master_key,
+                           master_key_schedule, DES_DECRYPT);
+           /* construct and seal the ticket */
+
+#ifdef NOENCRYPTION
+           bzero(session_key, sizeof(des_cblock));
+#else
+           des_new_random_key(&session_key);
+#endif
+
+           krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
+                             ad->prealm, client_host.s_addr,
+                             session_key, lifetime, kerb_time.tv_sec,
+                             s_name_data.name, s_name_data.instance,
+                             &key);
+           bzero(key, sizeof(key));
+           bzero(key_s, sizeof(key_s));
+
+           create_ciph(ciph, session_key, service, instance,
+                       local_realm,
+                       lifetime, s_name_data.key_version, tk,
+                       kerb_time.tv_sec, &ad->session);
+
+           /* clear session key */
+           bzero(session_key, sizeof(session_key));
+
+           bzero(ad->session, sizeof(ad->session));
+
+           rpkt = create_auth_reply(ad->pname, ad->pinst,
+                                    ad->prealm, time_ws,
+                                    0, 0, 0, ciph);
+           sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr*)client, S_AD_SZ);
+           bzero(&s_name_data, sizeof(s_name_data));
+           break;
+       }
+
+
+#ifdef notdef_DIE
+    case AUTH_MSG_DIE:
+       {
+           lt = klog(L_DEATH_REQ,
+               "Host: %s User: \"%s\" \"%s\" Kerberos killed",
+               inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+           exit(0);
+       }
+#endif /* notdef_DIE */
+
+    default:
+       {
+           lt = klog(L_KRB_PERR,
+               "Unknown message type: %d from %s port %u",
+               req_msg_type, inet_ntoa(client_host),
+               ntohs(client->sin_port));
+           break;
+       }
+    }
+}
+
+/*
+ * setup_disc 
+ *
+ * disconnect all descriptors, remove ourself from the process
+ * group that spawned us. 
+ */
+
+static void
+setup_disc(void)
+{
+    int     s;
+
+    for (s = 0; s < 3; s++) {
+       (void) close(s);
+    }
+
+    (void) open("/dev/null", 0);
+    (void) dup2(0, 1);
+    (void) dup2(0, 2);
+
+    setsid();
+
+    (void) chdir("/tmp");
+    return;
+}
+
+/*
+ * Make sure that database isn't stale.
+ *
+ * Exit if it is; we don't want to tell lies.
+ */
+
+static void check_db_age(void)
+{
+    long age;
+    
+    if (max_age != -1) {
+       /* Requires existance of kerb_get_db_age() */
+       gettimeofday(&kerb_time, 0);
+       age = kerb_get_db_age();
+       if (age == 0) {
+           klog(L_KRB_PERR, "Database currently being updated!");
+           hang();
+       }
+       if ((age + max_age) < kerb_time.tv_sec) {
+           klog(L_KRB_PERR, "Database out of date!");
+           hang();
+           /* NOTREACHED */
+       }
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    struct sockaddr_in from;
+    register int n;
+    int     on = 1;
+    int     child;
+    struct servent *sp;
+    int     fromlen;
+    static KTEXT_ST pkt_st;
+    KTEXT   pkt = &pkt_st;
+    int     kerror;
+    int c;
+    extern char *optarg;
+    extern int optind;
+
+    progname = argv[0];
+
+    while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) {
+       switch(c) {
+       case 's':
+           /*
+            * Set parameters to slave server defaults.
+            */
+           if (max_age == -1 && !nflag)
+               max_age = ONE_DAY;      /* 24 hours */
+           if (pause_int == -1)
+               pause_int = FIVE_MINUTES; /* 5 minutes */
+           if (lflag == 0) {
+               log_file = KRBSLAVELOG;
+               lflag++;
+           }
+           break;
+       case 'n':
+           max_age = -1;       /* don't check max age. */
+           nflag++;
+           break;
+       case 'm':
+           mflag++;            /* running manually; prompt for master key */
+           break;
+       case 'p':
+           /* Set pause interval. */
+           if (!isdigit(optarg[0]))
+               usage();
+           pause_int = atoi(optarg);
+           if ((pause_int < 5) ||  (pause_int > ONE_HOUR)) {
+               fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n");
+               usage();
+           }
+           break;
+       case 'a':
+           /* Set max age. */
+           if (!isdigit(optarg[0])) 
+               usage();
+           max_age = atoi(optarg);
+           if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) {
+               fprintf(stderr, "max_age must be between one hour and three days, in seconds\n");
+               usage();
+           }
+           break;
+       case 'l':
+           /* Set alternate log file */
+           lflag++;
+           log_file = optarg;
+           break;
+       case 'r':
+           /* Set realm name */
+           rflag++;
+           strcpy(local_realm, optarg);
+           break;
+       default:
+           usage();
+           break;
+       }
+    }
+
+    if (optind == (argc-1)) {
+       if (kerb_db_set_name(argv[optind]) != 0) {
+           fprintf(stderr, "Could not set alternate database name\n");
+           exit(1);
+       }
+       optind++;
+    }
+
+    if (optind != argc)
+       usage();
+       
+    printf("Kerberos server starting\n");
+    
+    if ((!nflag) && (max_age != -1))
+       printf("\tMaximum database age: %d seconds\n", max_age);
+    if (pause_int != -1)
+       printf("\tSleep for %d seconds on error\n", pause_int);
+    else
+       printf("\tSleep forever on error\n");
+    if (mflag)
+       printf("\tMaster key will be entered manually\n");
+    
+    printf("\tLog file is %s\n", lflag ? log_file : KRBLOG);
+
+    if (lflag)
+       kset_logfile(log_file);
+    
+    /* find our hostname, and use it as the instance */
+    if (gethostname(k_instance, INST_SZ)) {
+       fprintf(stderr, "%s: gethostname error\n", progname);
+       exit(1);
+    }
+
+    if ((sp = getservbyname("kerberos", "udp")) == 0) {
+       fprintf(stderr, "%s: udp/kerberos unknown service\n", progname);
+       exit(1);
+    }
+    sina.sin_port = sp->s_port;
+
+    if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+       fprintf(stderr, "%s: Can't open socket\n", progname);
+       exit(1);
+    }
+    if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+       fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname);
+
+    if (bind(f, (struct sockaddr*)&sina, sizeof(sina)) < 0) {
+       fprintf(stderr, "%s: Can't bind socket\n", progname);
+       exit(1);
+    }
+    /* do all the database and cache inits */
+    if ((n = kerb_init())) {
+       if (mflag) {
+           printf("Kerberos db and cache init ");
+           printf("failed = %d ...exiting\n", n);
+           exit(-1);
+       } else {
+           klog(L_KRB_PERR,
+           "Kerberos db and cache init failed = %d ...exiting", n);
+           hang();
+       }
+    }
+
+    /* Make sure database isn't stale */
+    check_db_age();
+    
+    /* setup master key */
+    if (kdb_get_master_key (mflag, &master_key, master_key_schedule) != 0) {
+      klog (L_KRB_PERR, "kerberos: couldn't get master key.\n");
+      exit (-1);
+    }
+    kerror = kdb_verify_master_key (&master_key, master_key_schedule, stdout);
+    if (kerror < 0) {
+      klog (L_KRB_PERR, "Can't verify master key.");
+      bzero (master_key, sizeof (master_key));
+      bzero (master_key_schedule, sizeof (master_key_schedule));
+      exit (-1);
+    }
+
+    master_key_version = (u_char) kerror;
+
+    fprintf(stdout, "\nCurrent Kerberos master key version is %d\n",
+           master_key_version);
+    des_init_random_number_generator(&master_key);
+
+    if (!rflag) {
+       /* Look up our local realm */
+       krb_get_lrealm(local_realm, 1);
+    }
+    fprintf(stdout, "Local realm: %s\n", local_realm);
+    fflush(stdout);
+
+    if (set_tgtkey(local_realm)) {
+       /* Ticket granting service unknown */
+       klog(L_KRB_PERR, "Ticket granting ticket service unknown");
+       fprintf(stderr, "Ticket granting ticket service unknown\n");
+       exit(1);
+    }
+    if (mflag) {
+       if ((child = fork()) != 0) {
+           printf("Kerberos started, PID=%d\n", child);
+           exit(0);
+       }
+       setup_disc();
+    }
+    /* receive loop */
+    for (;;) {
+       fromlen = S_AD_SZ;
+       n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr*)&from, &fromlen);
+       if (n > 0) {
+           pkt->length = n;
+           pkt->mbz = 0; /* force zeros to catch runaway strings */
+           /* see what is left in the input queue */
+           ioctl(f, FIONREAD, &q_bytes);
+           gettimeofday(&kerb_time, NULL);
+           q_n++;
+           max_q_n = max(max_q_n, q_n);
+           n_packets++;
+           klog(L_NET_INFO,
+        "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d",
+                q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0);
+           max_q_bytes = max(max_q_bytes, q_bytes);
+           if (!q_bytes)
+               q_n = 0;        /* reset consecutive packets */
+           kerberos(&from, pkt);
+       } else
+           klog(L_NET_ERR,
+           "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0);
+    }
+}
diff --git a/kerberosIV/kinit/Makefile b/kerberosIV/kinit/Makefile
new file mode 100644 (file)
index 0000000..3bf26ce
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $
+
+PROG=  kinit
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+BINDIR=        /usr/bin
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kinit/kinit.1 b/kerberosIV/kinit/kinit.1
new file mode 100644 (file)
index 0000000..2fa87fc
--- /dev/null
@@ -0,0 +1,132 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kinit.1,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $
+.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kinit \- Kerberos login utility
+.SH SYNOPSIS
+.B kinit
+[
+.B \-irvl
+]
+.SH DESCRIPTION
+The
+.I kinit
+command is used to login to the
+Kerberos
+authentication and authorization system.
+Note that only registered
+Kerberos
+users can use the
+Kerberos
+system.
+For information about registering as a
+Kerberos
+user,
+see the
+.I kerberos(1)
+manual page.
+.PP
+If you are logged in to a workstation that is running the
+.I toehold
+service,
+you do not have to use
+.I kinit.
+The
+.I toehold
+login procedure will log you into
+Kerberos
+automatically.
+You will need to use
+.I kinit
+only in those situations in which
+your original tickets have expired.
+(Tickets expire in about a day.)
+Note as well that
+.I toehold
+will automatically destroy your tickets when you logout from the workstation.
+.PP
+When you use
+.I kinit
+without options,
+the utility
+prompts for your username and Kerberos password,
+and tries to authenticate your login with the local
+Kerberos
+server.
+.PP
+If
+Kerberos
+authenticates the login attempt,
+.I kinit
+retrieves your initial ticket and puts it in the ticket file specified by
+your KRBTKFILE environment variable.
+If this variable is undefined,
+your ticket will be stored in the
+.IR /tmp
+directory,
+in the file
+.I tktuid ,
+where
+.I uid
+specifies your user identification number.
+.PP
+If you have logged in to
+Kerberos
+without the benefit of the workstation
+.I toehold
+system,
+make sure you use the
+.I kdestroy
+command to destroy any active tickets before you end your login session.
+You may want to put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+.PP
+The options to
+.I kinit
+are as follows:
+.TP 7
+.B \-i
+.I kinit
+prompts you for a
+Kerberos
+instance.
+.TP
+.B \-r
+.I kinit
+prompts you for a
+Kerberos
+realm.
+This option lets you authenticate yourself with a remote
+Kerberos
+server.
+.TP
+.B \-v
+Verbose mode.
+.I kinit
+prints the name of the ticket file used, and
+a status message indicating the success or failure of
+your login attempt.
+.TP
+.B \-l
+.I kinit
+prompts you for a ticket lifetime in minutes.  Due to protocol
+restrictions in Kerberos Version 4, this value must be between 5 and
+1275 minutes.
+.SH SEE ALSO
+.PP
+kerberos(1), kdestroy(1), klist(1), toehold(1)
+.SH BUGS
+The
+.B \-r
+option has not been fully implemented.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
diff --git a/kerberosIV/kinit/kinit.c b/kerberosIV/kinit/kinit.c
new file mode 100644 (file)
index 0000000..75176eb
--- /dev/null
@@ -0,0 +1,184 @@
+/*     $Id: kinit.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Routine to initialize user to Kerberos.  Prompts optionally for
+ * user, instance and realm.  Authenticates user and gets a ticket
+ * for the Kerberos ticket-granting service for future use. 
+ *
+ * Options are: 
+ *
+ *   -i[instance]
+ *   -r[realm]
+ *   -v[erbose]
+ *   -l[ifetime]
+ */
+
+#include <kuser_locl.h>
+#include <sys/param.h>
+
+#define        LIFE    DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */
+
+char   *progname;
+
+static void
+get_input(s, size, stream)
+char *s;
+int size;
+FILE *stream;
+{
+       char *p;
+
+       if (fgets(s, size, stream) == NULL)
+         exit(1);
+       if ( (p = strchr(s, '\n')) != NULL)
+               *p = '\0';
+}
+
+
+static void
+usage()
+{
+    fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname);
+    exit(1);
+}
+
+int
+main(argc, argv)
+    int argc;
+    char   *argv[];
+{
+    char    aname[ANAME_SZ];
+    char    inst[INST_SZ];
+    char    realm[REALM_SZ];
+    char    buf[MAXHOSTNAMELEN];
+    char   *username = NULL;
+    int     iflag, rflag, vflag, lflag, lifetime, k_errno;
+    register char *cp;
+    register i;
+
+    *inst = *realm = '\0';
+    iflag = rflag = vflag = lflag = 0;
+    lifetime = LIFE;
+    progname = (cp = strrchr(*argv, '/')) ? cp + 1 : *argv;
+
+    while (--argc) {
+       if ((*++argv)[0] != '-') {
+           if (username)
+               usage();
+           username = *argv;
+           continue;
+       }
+       for (i = 1; (*argv)[i] != '\0'; i++)
+           switch ((*argv)[i]) {
+           case 'i':           /* Instance */
+               ++iflag;
+               continue;
+           case 'r':           /* Realm */
+               ++rflag;
+               continue;
+           case 'v':           /* Verbose */
+               ++vflag;
+               continue;
+           case 'l':
+               ++lflag;
+               continue;
+           default:
+               usage();
+               exit(1);
+           }
+    }
+    if (username &&
+       (k_errno = kname_parse(aname, inst, realm, username))
+       != KSUCCESS) {
+       fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+       iflag = rflag = 1;
+       username = NULL;
+    }
+    if (gethostname(buf, MAXHOSTNAMELEN)) {
+       fprintf(stderr, "%s: gethostname failed\n", progname);
+       exit(1);
+    }
+    printf("%s (%s)\n", ORGANIZATION, buf);
+    if (username) {
+       printf("Kerberos Initialization for \"%s", aname);
+       if (*inst)
+           printf(".%s", inst);
+       if (*realm)
+           printf("@%s", realm);
+       printf("\"\n");
+    } else {
+       printf("Kerberos Initialization\n");
+       printf("Kerberos name: ");
+       get_input(aname, sizeof(aname), stdin);
+       if (!*aname)
+           exit(0);
+       if (!k_isname(aname)) {
+           fprintf(stderr, "%s: bad Kerberos name format\n",
+                   progname);
+           exit(1);
+       }
+    }
+    /* optional instance */
+    if (iflag) {
+       printf("Kerberos instance: ");
+       get_input(inst, sizeof(inst), stdin);
+       if (!k_isinst(inst)) {
+           fprintf(stderr, "%s: bad Kerberos instance format\n",
+                   progname);
+           exit(1);
+       }
+    }
+    if (rflag) {
+       printf("Kerberos realm: ");
+       get_input(realm, sizeof(realm), stdin);
+       if (!k_isrealm(realm)) {
+           fprintf(stderr, "%s: bad Kerberos realm format\n",
+                   progname);
+           exit(1);
+       }
+    }
+    if (lflag) {
+        printf("Kerberos ticket lifetime (minutes): ");
+        get_input(buf, sizeof(buf), stdin);
+        lifetime = atoi(buf);
+        if (lifetime < 5)
+             lifetime = 1;
+        else
+             lifetime /= krb_time_to_life(0, lifetime*60);
+        /* This should be changed if the maximum ticket lifetime */
+        /* changes */
+        if (lifetime > 255)
+             lifetime = 255;
+    }
+    if (!*realm && krb_get_lrealm(realm, 1)) {
+       fprintf(stderr, "%s: krb_get_lrealm failed\n", progname);
+       exit(1);
+    }
+    k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm,
+                               lifetime, 0);
+    if (vflag) {
+       printf("Kerberos realm %s:\n", realm);
+       printf("%s\n", krb_err_txt[k_errno]);
+    } else if (k_errno) {
+       fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+       exit(1);
+    }
+    exit(0);
+}
diff --git a/kerberosIV/klist/Makefile b/kerberosIV/klist/Makefile
new file mode 100644 (file)
index 0000000..8a3dd2e
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $
+
+PROG=  klist
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+BINDIR=        /usr/bin
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/klist/klist.1 b/kerberosIV/klist/klist.1
new file mode 100644 (file)
index 0000000..e16d25e
--- /dev/null
@@ -0,0 +1,83 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: klist.1,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $
+.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+klist \- list currently held Kerberos tickets
+.SH SYNOPSIS
+.B klist
+[
+\fB\-s \fR|\fB \-t\fR
+] [
+.B \-file
+name ] [
+.B \-srvtab
+]
+.br
+.SH DESCRIPTION
+.I klist
+prints the name of the tickets file and the
+identity of the principal the tickets are for (as listed in the
+tickets file), and 
+lists the principal names of all Kerberos tickets currently held by
+the user, along with the issue and expire time for each authenticator.
+Principal names are listed in the form
+.I name.instance@realm,
+with the '.' omitted if the instance is null,
+and the '@' omitted if the realm is null.
+
+If given the
+.B \-s
+option,
+.I klist
+does not print the issue and expire times, the name of the tickets file,
+or the identity of the principal.
+
+If given the
+.B \-t
+option, 
+.B klist
+checks for the existence of a non-expired ticket-granting-ticket in the
+ticket file.  If one is present, it exits with status 0, else it exits
+with status 1.  No output is generated when this option is specified. 
+
+If given the
+.B \-file
+option, the following argument is used as the ticket file.
+Otherwise, if the
+.B KRBTKFILE
+environment variable is set, it is used.
+If this environment variable
+is not set, the file
+.B /tmp/tkt[uid]
+is used, where
+.B uid
+is the current user-id of the user.
+
+If given the
+.B \-srvtab
+option, the file is treated as a service key file, and the names of the
+keys contained therein are printed.  If no file is
+specified with a
+.B \-file
+option, the default is
+.IR /etc/srvtab .
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm
+.TP
+/tmp/tkt[uid]
+as the default ticket file ([uid] is the decimal UID of the user).
+.TP
+/etc/srvtab
+as the default service key file
+.SH SEE ALSO
+.PP
+kerberos(1), kinit(1), kdestroy(1)
+.SH BUGS
+When reading a file as a service key file, very little sanity or error
+checking is performed.
diff --git a/kerberosIV/klist/klist.c b/kerberosIV/klist/klist.c
new file mode 100644 (file)
index 0000000..a7ced8c
--- /dev/null
@@ -0,0 +1,282 @@
+/*     $Id: klist.c,v 1.1.1.1 1995/12/14 06:52:50 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Lists your current Kerberos tickets.
+ * Written by Bill Sommerfeld, MIT Project Athena.
+ */
+
+#include <kuser_locl.h>
+
+char   *whoami;                        /* What was I invoked as?? */
+
+static char *
+short_date(dp)
+    time_t *dp;
+{
+    register char *cp;
+
+    if (*dp == (time_t)(-1L)) return "***  Never  *** ";
+    cp = ctime(dp) + 4;
+    cp[15] = '\0';
+    return (cp);
+}
+
+static void
+display_tktfile(file, tgt_test, long_form)
+char *file;
+int tgt_test, long_form;
+{
+    char    pname[ANAME_SZ];
+    char    pinst[INST_SZ];
+    char    prealm[REALM_SZ];
+    char    buf1[20], buf2[20];
+    int     k_errno;
+    CREDENTIALS c;
+    int     header = 1;
+
+    if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL))
+       file = TKT_FILE;
+
+    if (long_form)
+       printf("Ticket file:    %s\n", file);
+
+    /* 
+     * Since krb_get_tf_realm will return a ticket_file error, 
+     * we will call tf_init and tf_close first to filter out
+     * things like no ticket file.  Otherwise, the error that 
+     * the user would see would be 
+     * klist: can't find realm of ticket file: No ticket file (tf_util)
+     * instead of
+     * klist: No ticket file (tf_util)
+     */
+
+    /* Open ticket file */
+    if ((k_errno = tf_init(file, R_TKT_FIL))) {
+       if (!tgt_test)
+               fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+       exit(1);
+    }
+    /* Close ticket file */
+    (void) tf_close();
+
+    /* 
+     * We must find the realm of the ticket file here before calling
+     * tf_init because since the realm of the ticket file is not
+     * really stored in the principal section of the file, the
+     * routine we use must itself call tf_init and tf_close.
+     */
+    if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) {
+       if (!tgt_test)
+           fprintf(stderr, "%s: can't find realm of ticket file: %s\n",
+                   whoami, krb_err_txt[k_errno]);
+       exit(1);
+    }
+
+    /* Open ticket file */
+    if ((k_errno = tf_init(file, R_TKT_FIL))) {
+       if (!tgt_test)
+               fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+       exit(1);
+    }
+    /* Get principal name and instance */
+    if ((k_errno = tf_get_pname(pname)) ||
+       (k_errno = tf_get_pinst(pinst))) {
+           if (!tgt_test)
+                   fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+           exit(1);
+    }
+
+    /* 
+     * You may think that this is the obvious place to get the
+     * realm of the ticket file, but it can't be done here as the
+     * routine to do this must open the ticket file.  This is why 
+     * it was done before tf_init.
+     */
+       
+    if (!tgt_test && long_form)
+       printf("Principal:\t%s%s%s%s%s\n\n", pname,
+              (pinst[0] ? "." : ""), pinst,
+              (prealm[0] ? "@" : ""), prealm);
+    while ((k_errno = tf_get_cred(&c)) == KSUCCESS) {
+       if (!tgt_test && long_form && header) {
+           printf("%-15s  %-15s  %s\n",
+                  "  Issued", "  Expires", "  Principal");
+           header = 0;
+       }
+       if (tgt_test) {
+           c.issue_date = krb_life_to_time(c.issue_date, c.lifetime);
+           if (!strcmp(c.service, TICKET_GRANTING_TICKET) &&
+               !strcmp(c.instance, prealm)) {
+               if (time(0) < c.issue_date)
+                   exit(0);            /* tgt hasn't expired */
+               else
+                   exit(1);            /* has expired */
+           }
+           continue;                   /* not a tgt */
+       }
+       if (long_form) {
+           (void) strcpy(buf1, short_date(&c.issue_date));
+           c.issue_date = krb_life_to_time(c.issue_date, c.lifetime);
+           if (time(0) < (unsigned long) c.issue_date)
+               (void) strcpy(buf2, short_date(&c.issue_date));
+           else
+               (void) strcpy(buf2, ">>> Expired <<< ");
+           printf("%s  %s  ", buf1, buf2);
+       }
+       printf("%s%s%s%s%s\n",
+              c.service, (c.instance[0] ? "." : ""), c.instance,
+              (c.realm[0] ? "@" : ""), c.realm);
+    }
+    if (tgt_test)
+       exit(1);                        /* no tgt found */
+    if (header && long_form && k_errno == EOF) {
+       printf("No tickets in file.\n");
+    }
+}
+
+/* adapted from getst() in librkb */
+/*
+ * ok_getst() takes a file descriptor, a string and a count.  It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte.  When finished, what has been read exists in
+ * the given string "s".  If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated.  ok_getst() returns the number of characters read, including
+ * the null terminator.
+ *
+ * If there is a read error, it returns -1 (like the read(2) system call)
+ */
+
+static int
+ok_getst(fd, s, n)
+    int fd;
+    register char *s;
+    int n;
+{
+    register count = n;
+    int err;
+    while ((err = read(fd, s, 1)) > 0 && --count)
+        if (*s++ == '\0')
+            return (n - count);
+    if (err < 0)
+       return(-1);
+    *s = '\0';
+    return (n - count);
+}
+
+static void
+display_srvtab(file)
+char *file;
+{
+    int stab;
+    char serv[SNAME_SZ];
+    char inst[INST_SZ];
+    char rlm[REALM_SZ];
+    unsigned char key[8];
+    unsigned char vno;
+    int count;
+
+    printf("Server key file:   %s\n", file);
+       
+    if ((stab = open(file, O_RDONLY, 0400)) < 0) {
+       perror(file);
+       exit(1);
+    }
+    printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm",
+          "Key Version");
+    printf("------------------------------------------------------\n");
+
+    /* argh. getst doesn't return error codes, it silently fails */
+    while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
+          && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
+          && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
+       if (((count = read(stab,(char *) &vno,1)) != 1) ||
+            ((count = read(stab,(char *) key,8)) != 8)) {
+           if (count < 0)
+               perror("reading from key file");
+           else
+               fprintf(stderr, "key file truncated\n");
+           exit(1);
+       }
+       printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno);
+    }
+    if (count < 0)
+       perror(file);
+    (void) close(stab);
+}
+
+static void
+usage()
+{
+    fprintf(stderr,
+        "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami);
+    exit(1);
+}
+
+/* ARGSUSED */
+int
+main(argc, argv)
+    int     argc;
+    char  **argv;
+{
+    int     long_form = 1;
+    int     tgt_test = 0;
+    int     do_srvtab = 0;
+    char   *tkt_file = NULL;
+    char   *cp;
+
+    whoami = (cp = strrchr(*argv, '/')) ? cp + 1 : *argv;
+
+    while (*(++argv)) {
+       if (!strcmp(*argv, "-s")) {
+           long_form = 0;
+           continue;
+       }
+       if (!strcmp(*argv, "-t")) {
+           tgt_test = 1;
+           long_form = 0;
+           continue;
+       }
+       if (!strcmp(*argv, "-l")) {     /* now default */
+           continue;
+       }
+       if (!strcmp(*argv, "-file")) {
+           if (*(++argv)) {
+               tkt_file = *argv;
+               continue;
+           } else
+               usage();
+       }
+       if (!strcmp(*argv, "-srvtab")) {
+               if (tkt_file == NULL)   /* if no other file spec'ed,
+                                          set file to default srvtab */
+                   tkt_file = KEYFILE;
+               do_srvtab = 1;
+               continue;
+       }
+       usage();
+    }
+
+    if (do_srvtab)
+       display_srvtab(tkt_file);
+    else
+       display_tktfile(tkt_file, tgt_test, long_form);
+    exit(0);
+}
diff --git a/kerberosIV/kpasswdd/Makefile b/kerberosIV/kpasswdd/Makefile
new file mode 100644 (file)
index 0000000..7de4dc6
--- /dev/null
@@ -0,0 +1,13 @@
+#      from: @(#)Makefile      8.1 (Berkeley) 6/4/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:54 tholo Exp $
+
+PROG=  kpasswdd
+SRCS=  kpasswdd.c des_rw.c
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../../usr.bin/passwd
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   kpasswdd.8
+BINDIR=/usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kpasswdd/kpasswdd.8 b/kerberosIV/kpasswdd/kpasswdd.8
new file mode 100644 (file)
index 0000000..791667e
--- /dev/null
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1990, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    from @(#)kpasswdd.8     8.1 (Berkeley) 6/9/93
+.\"    $Id: kpasswdd.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $
+.\"
+.Dd June 9, 1993
+.Dt KPASSWDD 8
+.Os
+.Sh NAME
+.Nm kpasswdd
+.Nd Kerberos password changing daemon
+.Sh SYNOPSIS
+.Nm kpasswdd
+.Sh DESCRIPTION
+.Nm Kpasswdd
+is the server for the
+.Xr passwd 1
+program.
+The server provides a remote password changing facility
+with Kerberos authentication.
+A user must provide the old Kerberos password, encrypted
+in a random session key, to the server.
+.Nm Kpasswdd
+runs only on the Kerberos server, as it directly updates the
+Kerberos database.
+.Sh SEE ALSO
+.Xr kerberos 1 ,
+.Xr passwd 1
+.Sh HISTORY
+The
+.Nm kpasswdd
+utility first appeared in 4.4BSD.
diff --git a/kerberosIV/kpasswdd/kpasswdd.c b/kerberosIV/kpasswdd/kpasswdd.c
new file mode 100644 (file)
index 0000000..5fa1ec8
--- /dev/null
@@ -0,0 +1,273 @@
+/*     $Id: kpasswdd.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $       */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)kpasswdd.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * kpasswdd - update a principal's passwd field in the Kerberos
+ *           database.  Called from inetd.
+ * K. Fall
+ * 12-Dec-88
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include <stdio.h>
+#include "kpasswd_proto.h"
+
+static struct kpasswd_data     kpwd_data;
+static des_cblock              master_key, key;
+static Key_schedule            master_key_schedule,
+                               key_schedule, random_sched;
+long                           mkeyversion;
+AUTH_DAT                       kdata;
+static Principal               principal_data;
+static struct update_data      ud_data;
+
+char                           inst[INST_SZ];
+char                           version[9];
+KTEXT_ST                       ticket;
+
+char   *progname;              /* for the library */
+
+main()
+{
+       struct  sockaddr_in     foreign;
+       int                     foreign_len = sizeof(foreign);
+       int                     rval, more;
+       static  char    name[] = "kpasswdd";
+
+       static  struct rlimit   rl = { 0, 0 };
+
+       progname = name;
+       openlog("kpasswdd", LOG_CONS | LOG_PID, LOG_AUTH);
+
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGTSTP, SIG_IGN);
+       if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+               syslog(LOG_ERR, "setrlimit: %m");
+               exit(1);
+       }
+
+       if (getpeername(0, &foreign, &foreign_len) < 0) {
+               syslog(LOG_ERR,"getpeername: %m");
+               exit(1);
+       }
+
+       strcpy(inst, "*");
+       rval = krb_recvauth(
+               0L,                             /* options--!MUTUAL */
+               0,                              /* file desc */
+               &ticket,                        /* client's ticket */
+               SERVICE,                        /* expected service */
+               inst,                           /* expected instance */
+               &foreign,                       /* foreign addr */
+               (struct sockaddr_in *) 0,       /* local addr */
+               &kdata,                         /* returned krb data */
+               "",                             /* service keys file */
+               (bit_64 *) NULL,                /* returned key schedule */
+               version
+       );
+
+
+       if (rval != KSUCCESS) {
+               syslog(LOG_NOTICE, "krb_recvauth: %s", krb_err_txt[rval]);
+               cleanup();
+               exit(1);
+       }
+
+       if (*version == '\0') {
+               /* indicates error on client's side (no tickets, etc.) */
+               cleanup();
+               exit(0);
+       } else if (strcmp(version, "KPWDV0.1") != 0) {
+               syslog(LOG_NOTICE,
+                       "kpasswdd version conflict (recv'd %s)",
+                       version);
+               cleanup();
+               exit(1);
+       }
+
+
+       /* get master key */
+       if (kdb_get_master_key(0, &master_key, master_key_schedule) != 0) {
+               syslog(LOG_ERR, "couldn't get master key");
+               cleanup();
+               exit(1);
+       }
+
+       mkeyversion = kdb_get_master_key(NULL, &master_key, master_key_schedule);
+
+       if (mkeyversion < 0) {
+               syslog(LOG_NOTICE, "couldn't verify master key");
+               cleanup();
+               exit(1);
+       }
+
+       /* get principal info */
+       rval = kerb_get_principal(
+               kdata.pname,
+               kdata.pinst,
+               &principal_data,
+               1,
+               &more
+       );
+
+       if (rval < 0) {
+               syslog(LOG_NOTICE,
+                       "error retrieving principal record for %s.%s",
+                       kdata.pname, kdata.pinst);
+               cleanup();
+               exit(1);
+       }
+
+       if (rval != 1 || (more != 0)) {
+               syslog(LOG_NOTICE, "more than 1 dbase entry for %s.%s",
+                       kdata.pname, kdata.pinst);
+               cleanup();
+               exit(1);
+       }
+
+       /* get the user's key */
+
+       bcopy(&principal_data.key_low, key, 4);
+       bcopy(&principal_data.key_high, ((long *) key) + 1, 4);
+       kdb_encrypt_key(&key, &key, &master_key, master_key_schedule,
+               DECRYPT);
+       key_sched(&key, key_schedule);
+       des_set_key(&key, key_schedule);
+
+
+       /* get random key and send it over {random} Kperson */
+
+       random_key(kpwd_data.random_key);
+       strcpy(kpwd_data.secure_msg, SECURE_STRING);
+       if (des_write(0, &kpwd_data, sizeof(kpwd_data)) != sizeof(kpwd_data)) {
+               syslog(LOG_NOTICE, "error writing initial data");
+               cleanup();
+               exit(1);
+       }
+
+       bzero(key, sizeof(key));
+       bzero(key_schedule, sizeof(key_schedule));
+
+       /* now read update info: { info }Krandom */
+
+       key_sched(&kpwd_data.random_key, random_sched);
+       des_set_key(&kpwd_data.random_key, random_sched);
+       if (des_read(0, &ud_data, sizeof(ud_data)) != sizeof(ud_data)) {
+               syslog(LOG_NOTICE, "update aborted");
+               cleanup();
+               exit(1);
+       }
+
+       /* validate info string by looking at the embedded string */
+
+       if (strcmp(ud_data.secure_msg, SECURE_STRING) != 0) {
+               syslog(LOG_NOTICE, "invalid update from %s",
+                       inet_ntoa(foreign.sin_addr));
+               cleanup();
+               exit(1);
+       }
+
+       /* produce the new key entry in the database { key }Kmaster */
+       string_to_key(ud_data.pw, &key);
+       kdb_encrypt_key(&key, &key,
+               &master_key, master_key_schedule,
+               ENCRYPT);
+       bcopy(key, &principal_data.key_low, 4);
+       bcopy(((long *) key) + 1,
+               &principal_data.key_high, 4);
+       bzero(key, sizeof(key));
+       principal_data.key_version++;
+       if (kerb_put_principal(&principal_data, 1)) {
+               syslog(LOG_ERR, "couldn't write new record for %s.%s",
+                       principal_data.name, principal_data.instance);
+               cleanup();
+               exit(1);
+       }
+
+       syslog(LOG_NOTICE,"wrote new password field for %s.%s from %s",
+               principal_data.name,
+               principal_data.instance,
+               inet_ntoa(foreign.sin_addr)
+       );
+
+       send_ack(0, "Update complete.\n");
+       cleanup();
+       exit(0);
+}
+
+cleanup()
+{
+       bzero(&kpwd_data, sizeof(kpwd_data));
+       bzero(&master_key, sizeof(master_key));
+       bzero(master_key_schedule, sizeof(master_key_schedule));
+       bzero(key, sizeof(key));
+       bzero(key_schedule, sizeof(key_schedule));
+       bzero(random_sched, sizeof(random_sched));
+       bzero(&principal_data, sizeof(principal_data));
+       bzero(&ud_data, sizeof(ud_data));
+}
+
+send_ack(remote, msg)
+       int     remote;
+       char    *msg;
+{
+       int     cc;
+       cc = des_write(remote, msg, strlen(msg) + 1);
+       if (cc <= 0) {
+               syslog(LOG_NOTICE, "error writing ack");
+               cleanup();
+               exit(1);
+       }
+}
diff --git a/kerberosIV/kprop/Makefile b/kerberosIV/kprop/Makefile
new file mode 100644 (file)
index 0000000..09c9035
--- /dev/null
@@ -0,0 +1,8 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $
+
+PROG=  kprop
+LDADD+=        -lkrb -ldes
+DPADD+=        ${LIBKRB} ${LIBDES}
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kprop/kprop.c b/kerberosIV/kprop/kprop.c
new file mode 100644 (file)
index 0000000..b61cb79
--- /dev/null
@@ -0,0 +1,538 @@
+/*     $Id: kprop.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $  */
+
+/*-
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ */
+
+#include <slav_locl.h>
+#include <kprop.h>
+#include <sys/param.h>
+
+static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION;
+
+int     debug = 0;
+
+char    my_realm[REALM_SZ];
+int     princ_data_size = 3 * sizeof(long) + 3 * sizeof(unsigned char);
+short   transfer_mode, net_transfer_mode;
+int force_flag;
+static char ok[] = ".dump_ok";
+
+struct slave_host {
+    u_long  net_addr;
+    char   *name;
+    char   *instance;
+    char   *realm;
+    int           not_time_yet;
+    int    succeeded;
+    struct slave_host *next;
+};
+
+static void
+Death(char *s)
+{
+    fprintf(stderr, "kprop: ");
+    perror(s);
+    exit(1);
+}
+
+static
+int get_slaves(struct slave_host **psl, char *file, time_t ok_mtime)
+{
+    FILE   *fin;
+    char    namebuf[128], *inst;
+    char   *pc;
+    struct hostent *host;
+    struct slave_host **th;
+    char    path[256];
+    char   *ppath;
+    struct stat stbuf;
+
+    if ((fin = fopen(file, "r")) == NULL) {
+       fprintf(stderr, "Can't open slave host file, '%s'.\n", file);
+       exit(-1);
+    }
+    strcpy(path, file);
+    if ((ppath = strrchr(path, '/'))) {
+       ppath += 1;
+    } else {
+       ppath = path;
+    }
+    for (th = psl; fgets(namebuf, sizeof namebuf, fin); th = &(*th)->next) {
+       if ((pc = strchr(namebuf, '\n'))) {
+           *pc = '\0';
+       } else {
+           fprintf(stderr, "Host name too long (>= %d chars) in '%s'.\n",
+                   (int)(sizeof(namebuf)), file);
+           exit(-1);
+       }
+       host = gethostbyname(namebuf);
+       if (host == NULL) {
+           fprintf(stderr, "Unknown host '%s' in '%s'.\n", namebuf, file);
+           exit(-1);
+       }
+       (*th) = (struct slave_host *) malloc(sizeof(struct slave_host));
+       if (!*th) {
+           fprintf(stderr, "No memory reading host list from '%s'.\n",
+                   file);
+           exit(-1);
+       }
+       bzero( (*th) , (sizeof(struct slave_host)) );
+       (*th)->name = malloc(strlen(namebuf) + 1);
+       if (!(*th)->name) {
+           fprintf(stderr, "No memory reading host list from '%s'.\n",
+                   file);
+           exit(-1);
+       }
+       /* get kerberos cannonical instance name */
+       strcpy((*th)->name, namebuf);
+       inst = krb_get_phost ((*th)->name);
+       (*th)->instance = malloc(strlen(inst) + 1);
+       if (!(*th)->instance) {
+           fprintf(stderr, "No memory reading host list from '%s'.\n",
+                   file);
+           exit(-1);
+       }
+       strcpy((*th)->instance, inst);
+       /* what a concept, slave servers in different realms! */
+       (*th)->realm = my_realm;
+       bcopy(host->h_addr, (char *)&(*th)->net_addr, sizeof(host->h_addr));
+       (*th)->not_time_yet = 0;
+       (*th)->succeeded = 0;
+       (*th)->next = NULL;
+       strcat(strcpy(ppath, (*th)->name), "-last-prop");
+       if (!force_flag && !stat(path, &stbuf) && stbuf.st_mtime > ok_mtime) {
+           (*th)->not_time_yet = 1;
+           (*th)->succeeded = 1;       /* no change since last success */
+       }
+    }
+    fclose(fin);
+    return (1);
+}
+
+/* The master -> slave protocol looks like this:
+     1) 8 byte version string
+     2) 2 bytes of "transfer mode" (net byte order of course)
+     3) ticket/authentication send by sendauth
+     4) 4 bytes of "block" length (u_long)
+     5) data
+
+     4 and 5 repeat til EOF ...
+*/
+
+static int
+prop_to_slaves(struct slave_host *sl, int fd, char *fslv)
+{
+    char buf[KPROP_BUFSIZ];
+    char obuf[KPROP_BUFSIZ + 64        /* leave room for private msg overhead */ ];
+    struct servent *sp;
+    struct sockaddr_in sin, my_sin;
+    int     i, n, s;
+    struct slave_host *cs;     /* current slave */
+    char   path[256], my_host_name[MAXHOSTNAMELEN], *p_my_host_name;
+    char   kprop_service_instance[INST_SZ];
+    char   *pc;
+    u_long cksum;
+    u_long length, nlength;
+    long   kerror;
+    KTEXT_ST     ticket;
+    CREDENTIALS  cred;
+    MSG_DAT msg_dat;
+    static char tkstring[] = "/tmp/kproptktXXXXXX";
+    
+    des_key_schedule session_sched;
+
+    (void) mktemp(tkstring);
+    krb_set_tkt_string(tkstring);
+    
+    if ((sp = getservbyname("krb_prop", "tcp")) == 0) {
+       fprintf(stderr, "tcp/krb_prop: service unknown.\n");
+       exit(1);
+    }
+
+    bzero(&sin, sizeof sin);
+    sin.sin_family = AF_INET;
+    sin.sin_port = sp->s_port;
+    sin.sin_addr.s_addr = INADDR_ANY;
+
+    strcpy(path, fslv);
+    if ((pc = strrchr(path, '/'))) {
+       pc += 1;
+    } else {
+       pc = path;
+    }
+
+    for (i = 0; i < 5; i++) {  /* try each slave five times max */
+       for (cs = sl; cs; cs = cs->next) {
+           if (!cs->succeeded) {
+               if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+                   perror("kprop: socket");
+                   exit(1);
+               }
+               bcopy(&cs->net_addr, &sin.sin_addr,
+                     sizeof cs->net_addr);
+
+               if (connect(s, (struct sockaddr *) &sin, sizeof sin) < 0) {
+                   fprintf(stderr, "%s: ", cs->name);
+                   perror("connect");
+                   close(s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+               
+               /* for krb_mk_{priv, safe} */
+               bzero (&my_sin, sizeof my_sin);
+               n = sizeof my_sin;
+               if (getsockname (s, (struct sockaddr *) &my_sin, &n) != 0) {
+                   fprintf (stderr, "kprop: can't get socketname.");
+                   perror ("getsockname");
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+               if (n != sizeof (my_sin)) {
+                   fprintf (stderr, "kprop: can't get socketname. len");
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+               
+               /* Get ticket */
+               kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, 
+                                    cs->instance, cs->realm, (u_long) 0);
+               /* if ticket has expired try to get a new one, but
+                * first get a TGT ...
+                */
+               if (kerror != MK_AP_OK) {
+                   if (gethostname (my_host_name, sizeof(my_host_name)) != 0) {
+                       fprintf (stderr, "%s:", cs->name);
+                       perror ("getting my hostname");
+                       close (s);
+                       break;  /* next one can't work either! */
+                   }
+                   /* get canonical kerberos service instance name */
+                   p_my_host_name = krb_get_phost (my_host_name);
+                   /* copy it to make sure gethostbyname static doesn't
+                    * screw us. */
+                   strcpy (kprop_service_instance, p_my_host_name);
+                   kerror = krb_get_svc_in_tkt (KPROP_SERVICE_NAME, 
+#if 0
+                                                kprop_service_instance,
+#else
+                                                KRB_MASTER,
+#endif
+                                                my_realm,
+                                                TGT_SERVICE_NAME,
+                                                my_realm,
+                                                96,
+                                                KPROP_SRVTAB);
+                   if (kerror != INTK_OK) {
+                       fprintf (stderr,
+                                "%s: %s.  While getting initial ticket\n",
+                                cs->name, krb_err_txt[kerror]);
+                       close (s);
+                       goto punt;
+                   }
+                   kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, 
+                                        cs->instance, cs->realm, (u_long) 0);
+               }
+               if (kerror != MK_AP_OK) {
+                   fprintf (stderr, "%s: %s. Calling krb_mk_req.",
+                            cs->name, krb_err_txt[kerror]);
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }                   
+
+               if (write(s, kprop_version, sizeof(kprop_version))
+                   != sizeof(kprop_version)) {
+                   fprintf (stderr, "%s: ", cs->name);
+                   perror ("write (version) error");
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+
+               net_transfer_mode = htons (transfer_mode);
+               if (write(s, &net_transfer_mode, sizeof(net_transfer_mode))
+                   != sizeof(net_transfer_mode)) {
+                   fprintf (stderr, "%s: ", cs->name);
+                   perror ("write (transfer_mode) error");
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+
+               kerror = krb_get_cred (KPROP_SERVICE_NAME, cs->instance,
+                                      cs->realm, &cred);
+               if (kerror != KSUCCESS) {
+                   fprintf (stderr, "%s: %s.  Getting session key.", 
+                            cs->name, krb_err_txt[kerror]);
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+#ifdef NOENCRYPTION
+               bzero((char *)session_sched, sizeof(session_sched));
+#else
+               if (des_key_sched (&cred.session, session_sched)) {
+                   fprintf (stderr, "%s: can't make key schedule.",
+                            cs->name);
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+#endif
+               /* SAFE (quad_cksum) and CLEAR are just not good enough */
+               cksum = 0;
+#ifdef not_working_yet
+               if (transfer_mode != KPROP_TRANSFER_PRIVATE) {
+                   cksum = get_data_checksum(fd, session_sched);
+                   lseek(fd, 0L, 0);
+               }
+               else
+#endif
+               {
+                   struct stat st;
+                   fstat (fd, &st);
+                   cksum = st.st_size;
+               }
+               kerror = krb_sendauth(KOPT_DO_MUTUAL,
+                                     s,
+                                     &ticket,
+                                     KPROP_SERVICE_NAME,
+                                     cs->instance,
+                                     cs->realm,
+                                     cksum,
+                                     &msg_dat,
+                                     &cred,
+                                     session_sched,
+                                     &my_sin,
+                                     &sin,
+                                     KPROP_PROT_VERSION);
+               if (kerror != KSUCCESS) {
+                   fprintf (stderr, "%s: %s.  Calling krb_sendauth.", 
+                            cs->name, krb_err_txt[kerror]);
+                   close (s);
+                   continue;   /*** NEXT SLAVE ***/
+               }
+
+               lseek(fd, 0L, SEEK_SET); /* Rewind file before rereading it. */
+               while ((n = read(fd, buf, sizeof buf))) {
+                   if (n < 0) {
+                       perror("input file read error");
+                       exit(1);
+                   }
+                   switch (transfer_mode) {
+                   case KPROP_TRANSFER_PRIVATE:
+                   case KPROP_TRANSFER_SAFE:
+                       if (transfer_mode == KPROP_TRANSFER_PRIVATE)
+                           length = krb_mk_priv (buf, obuf, n, 
+                                                 session_sched, &cred.session,
+                                                 &my_sin, &sin);
+                       else
+                           length = krb_mk_safe (buf, obuf, n,
+                                                 &cred.session,
+                                                 &my_sin, &sin);
+                       if (length == -1) {
+                           fprintf (stderr, "%s: %s failed.",
+                                    cs->name,
+                                    (transfer_mode == KPROP_TRANSFER_PRIVATE) 
+                                    ? "krb_rd_priv" : "krb_rd_safe");
+                           close (s);
+                           continue; /*** NEXT SLAVE ***/
+                       }
+                       nlength = htonl(length);
+                       if (write(s, &nlength, sizeof nlength)
+                           != sizeof nlength) {
+                           fprintf (stderr, "%s: ", cs->name);
+                           perror ("write error");
+                           close (s);
+                           continue; /*** NEXT SLAVE ***/
+                       }
+                       if (write(s, obuf, length) != length) {
+                           fprintf(stderr, "%s: ", cs->name);
+                           perror("write error");
+                           close(s);
+                           continue; /*** NEXT SLAVE ***/
+                       }
+                       break;
+                   case KPROP_TRANSFER_CLEAR:
+                       if (write(s, buf, n) != n) {
+                           fprintf(stderr, "%s: ", cs->name);
+                           perror("write error");
+                           close(s);
+                           continue; /*** NEXT SLAVE ***/
+                       }
+                       break;
+                   }
+               }
+               close(s);
+               cs->succeeded = 1;
+               fprintf(stderr, "%s: success.\n", cs->name);
+               strcat(strcpy(pc, cs->name), "-last-prop");
+               unlink(path);
+               close(creat(path, 0600));
+           }
+       }
+    }
+punt:
+    
+    dest_tkt();
+    for (cs = sl; cs; cs = cs->next) {
+       if (!cs->succeeded)
+           return (0);         /* didn't get this slave */
+    }
+    return (1);
+}
+
+int
+main(int argc, char **argv)
+{
+    int     fd, i;
+    char   *floc, *floc_ok;
+    char   *fslv;
+    struct stat stbuf, stbuf_ok;
+    time_t   l_init, l_final;
+    char   *pc;
+    int    l_diff;
+    static struct slave_host *slave_host_list = NULL;
+    struct slave_host *sh;
+
+    transfer_mode = KPROP_TRANSFER_PRIVATE;
+
+    time(&l_init);
+    pc = ctime(&l_init);
+    pc[strlen(pc) - 1] = '\0';
+    printf("\nStart slave propagation: %s\n", pc);
+    floc = (char *) NULL;
+    fslv = (char *) NULL;
+
+    if (krb_get_lrealm(my_realm,1) != KSUCCESS)
+      Death ("Getting my kerberos realm.  Check krb.conf");
+
+    for (i = 1; i < argc; i++) 
+      switch (argv[i][0]) {
+      case '-':
+       if (strcmp (argv[i], "-private") == 0) 
+         transfer_mode = KPROP_TRANSFER_PRIVATE;
+#ifdef not_safe_yet
+       else if (strcmp (argv[i], "-safe") == 0) 
+         transfer_mode = KPROP_TRANSFER_SAFE;
+       else if (strcmp (argv[i], "-clear") == 0) 
+         transfer_mode = KPROP_TRANSFER_CLEAR;
+#endif
+       else if (strcmp (argv[i], "-realm") == 0) {
+           i++;
+           if (i < argc)
+               strcpy(my_realm, argv[i]);
+           else
+               goto usage;
+       } else if (strcmp (argv[i], "-force") == 0)
+           force_flag++;
+       else {
+         fprintf (stderr, "kprop: unknown control argument %s.\n",
+                  argv[i]);
+         exit (1);
+       }
+       break;
+      default:
+       /* positional arguments are marginal at best ... */
+       if (floc == (char *) NULL)
+         floc = argv[i];
+       else {
+         if (fslv == (char *) NULL)
+           fslv = argv[i];
+         else {
+         usage:
+                 /* already got floc and fslv, what is this? */
+           fprintf(stderr,
+                   "\nUsage: kprop [-force] [-realm realm] [-private|-safe|-clear] data_file slaves_file\n\n");
+           exit(1);
+         }
+       }
+      }
+    if ((floc == (char *)NULL) || (fslv == (char *)NULL))
+           goto usage;
+    
+    if ((floc_ok = (char *) malloc(strlen(floc) + strlen(ok) + 1))
+       == NULL) {
+       Death(floc);
+    }
+    strcat(strcpy(floc_ok, floc), ok);
+
+    if ((fd = open(floc, O_RDONLY)) < 0) {
+       Death(floc);
+    }
+    if (flock(fd, LOCK_EX | LOCK_NB)) {
+       Death(floc);
+    }
+    if (stat(floc, &stbuf)) {
+       Death(floc);
+    }
+    if (stat(floc_ok, &stbuf_ok)) {
+       Death(floc_ok);
+    }
+    if (stbuf.st_mtime > stbuf_ok.st_mtime) {
+       fprintf(stderr, "kprop: '%s' more recent than '%s'.\n",
+               floc, floc_ok);
+       exit(1);
+    }
+    if (!get_slaves(&slave_host_list, fslv, stbuf_ok.st_mtime)) {
+       fprintf(stderr,
+               "kprop: can't read slave host file '%s'.\n", fslv);
+       exit(1);
+    }
+#ifdef KPROP_DBG
+    {
+       struct slave_host *sh;
+       int     i;
+       fprintf(stderr, "\n\n");
+       fflush(stderr);
+       for (sh = slave_host_list; sh; sh = sh->next) {
+           fprintf(stderr, "slave %d: %s, %s", i++, sh->name,
+                   inet_ntoa(sh->net_addr));
+           fflush(stderr);
+       }
+    }
+#endif                         /* KPROP_DBG */
+
+    if (!prop_to_slaves(slave_host_list, fd, fslv)) {
+       fprintf(stderr,
+               "kprop: propagation failed.\n");
+       exit(1);
+    }
+    if (flock(fd, LOCK_UN)) {
+       Death(floc);
+    }
+    fprintf(stderr, "\n\n");
+    for (sh = slave_host_list; sh; sh = sh->next) {
+       fprintf(stderr, "%s:\t\t%s\n", sh->name,
+               (sh->not_time_yet? "Not time yet" : (sh->succeeded ? "Succeeded" : "FAILED")));
+    }
+
+    time(&l_final);
+    l_diff = l_final - l_init;
+    printf("propagation finished, %d:%02d:%02d elapsed\n",
+          l_diff / 3600, (l_diff % 3600) / 60, l_diff % 60);
+
+    exit(0);
+}
+
+#ifdef doesnt_work_yet
+u_long get_data_checksum(fd, key_sched)
+     int fd;
+     des_key_schedule key_sched;
+{
+       unsigned long cksum = 0;
+       int n;
+       char buf[BUFSIZ];
+       long obuf[2];
+
+       while (n = read(fd, buf, sizeof buf)) {
+           if (n < 0) {
+               fprintf(stderr, "Input data file read error: ");
+               perror("read");
+               exit(1);
+           }
+           cksum = cbc_cksum(buf, obuf, n, key_sched, key_sched);
+       }
+       return cksum;
+}
+#endif
diff --git a/kerberosIV/kpropd/Makefile b/kerberosIV/kpropd/Makefile
new file mode 100644 (file)
index 0000000..3d12f9a
--- /dev/null
@@ -0,0 +1,9 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $
+
+PROG=  kpropd
+LDADD+=        -lkrb -ldes
+DPADD+=        ${LIBKRB} ${LIBDES}
+NOMAN= noman
+BINDIR=/usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kpropd/kpropd.c b/kerberosIV/kpropd/kpropd.c
new file mode 100644 (file)
index 0000000..91b547a
--- /dev/null
@@ -0,0 +1,412 @@
+/*     $Id: kpropd.c,v 1.1.1.1 1995/12/14 06:52:52 tholo Exp $ */
+
+/*-
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ */
+
+/*
+ * This program is run on slave servers, to catch updates "pushed"
+ * from the master kerberos server in a realm.
+ */
+
+#include <slav_locl.h>
+#include <kprop.h>
+
+static char *kdb_util_path = "kdb_util";
+
+static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION;
+
+int     debug = 0;
+
+char   *logfile = K_LOGFIL;
+
+char    errmsg[256];
+int     pause_int = 300;       /* 5 minutes in seconds */
+
+static char    buf[KPROP_BUFSIZ+64 /* leave room for private msg overhead */];
+
+static void 
+SlowDeath(void)
+{
+  klog(L_KRB_PERR, "kpropd will pause before dying so as not to loop init");
+  sleep(pause_int);
+  klog(L_KRB_PERR, "AAAAAHHHHhhhh....");
+  exit(1);
+}
+
+static void
+usage(void)
+{
+  fprintf(stderr, "\nUsage: kpropd [-r realm] [-s srvtab] [-l logfile] fname\n\n");
+  SlowDeath();
+}
+
+static void
+recv_auth (int in, int out, int private, struct sockaddr_in *remote, struct sockaddr_in *local, AUTH_DAT *ad)
+{
+  u_long length;
+  long kerror;
+  int n;
+  MSG_DAT msg_data;
+  des_key_schedule session_sched;
+
+  if (private)
+#ifdef NOENCRYPTION
+    bzero((char *)session_sched, sizeof(session_sched));
+#else
+  if (des_key_sched (&ad->session, session_sched)) {
+    klog (L_KRB_PERR, "kpropd: can't make key schedule");
+    SlowDeath();
+  }
+#endif
+
+  while (1) {
+    n = krb_net_read (in, (char *)&length, sizeof length);
+    if (n == 0) break;
+    if (n < 0) {
+      sprintf (errmsg, "kpropd: read: %s", strerror(errno));
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    length = ntohl (length);
+    if (length > sizeof buf) {
+      sprintf (errmsg, "kpropd: read length %ld, bigger than buf %d",
+              length, (int)(sizeof(buf)));
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    n = krb_net_read(in, buf, length);
+    if (n < 0) {
+      sprintf(errmsg, "kpropd: read: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if (private)
+      kerror = krb_rd_priv (buf, n, session_sched, &ad->session, 
+                           remote, local, &msg_data);
+    else
+      kerror = krb_rd_safe (buf, n, &ad->session,
+                           remote, local, &msg_data);
+    if (kerror != KSUCCESS) {
+      sprintf (errmsg, "kpropd: %s: %s",
+              private ? "krb_rd_priv" : "krb_rd_safe",
+              krb_err_txt[kerror]);
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if (write(out, msg_data.app_data, msg_data.app_length) != 
+       msg_data.app_length) {
+      sprintf(errmsg, "kpropd: write: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+  }
+}
+
+static void
+recv_clear (int in, int out)
+{
+  int n;
+
+  while (1) {
+    n = read (in, buf, sizeof buf);
+    if (n == 0) break;
+    if (n < 0) {
+      sprintf (errmsg, "kpropd: read: %s", strerror(errno));
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if (write(out, buf, n) != n) {
+      sprintf(errmsg, "kpropd: write: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+  }
+}
+
+int
+main(int argc, char **argv)
+{
+  struct sockaddr_in from;
+  struct sockaddr_in sin;
+  struct servent *sp;
+  int     s, s2, fd, n, fdlock;
+  int     from_len;
+  char    local_file[256];
+  char    local_temp[256];
+  struct hostent *hp;
+  char    hostname[256];
+  char    from_str[128];
+  long    kerror;
+  AUTH_DAT auth_dat;
+  KTEXT_ST ticket;
+  char my_instance[INST_SZ];
+  char my_realm[REALM_SZ];
+  char cmd[1024];
+  short net_transfer_mode, transfer_mode;
+  des_key_schedule session_sched;
+  char version[9];
+  int c;
+  extern char *optarg;
+  extern int optind;
+  int rflag = 0;
+  char *srvtab = "";
+  char *local_db = DBM_FILE;
+
+  if (argv[argc - 1][0] == 'k' && isdigit(argv[argc - 1][1])) {
+    argc--;                    /* ttys file hack */
+  }
+  while ((c = getopt(argc, argv, "r:s:d:l:p:P:")) != EOF) {
+    switch(c) {
+    case 'r':
+      rflag++;
+      strcpy(my_realm, optarg);
+      break;
+    case 's':
+      srvtab = optarg;
+      break;
+    case 'd':
+      local_db = optarg;
+      break;
+    case 'l':
+      logfile = optarg;
+      break;       
+    case 'p':
+    case 'P':
+      kdb_util_path = optarg;
+      break;
+    default:
+      usage();
+      break;
+    }
+  }
+  if (optind != argc-1)
+    usage();
+
+  kset_logfile(logfile);
+
+  klog(L_KRB_PERR, "\n\n***** kpropd started *****");
+
+  strcpy(local_file, argv[optind]);
+  strcat(strcpy(local_temp, argv[optind]), ".tmp");
+
+  if ((sp = getservbyname("krb_prop", "tcp")) == NULL) {
+    klog(L_KRB_PERR, "kpropd: tcp/krb_prop: unknown service.");
+    SlowDeath();
+  }
+  bzero((char *)&sin, sizeof(sin));
+  sin.sin_port = sp->s_port;
+  sin.sin_family = AF_INET;
+
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    sprintf(errmsg, "kpropd: socket: %s", strerror(errno));
+    klog(L_KRB_PERR, errmsg);
+    SlowDeath();
+  }
+  if (bind(s, (struct sockaddr*)&sin, sizeof sin) < 0) {
+    sprintf(errmsg, "kpropd: bind: %s", strerror(errno));
+    klog(L_KRB_PERR, errmsg);
+    SlowDeath();
+  }
+  if (!rflag) {
+    kerror = krb_get_lrealm(my_realm,1);
+    if (kerror != KSUCCESS) {
+      sprintf (errmsg, "kpropd: Can't get local realm. %s",
+              krb_err_txt[kerror]);
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+  }
+    
+  /* Responder uses KPROP_SERVICE_NAME.'hostname' and requestor always
+   uses KPROP_SERVICE_NAME.KRB_MASTER (rcmd.kerberos) */
+  strcpy(my_instance, "*");
+    
+  klog(L_KRB_PERR, "Established socket");
+
+  listen(s, 5);
+  for (;;) {
+    from_len = sizeof from;
+    if ((s2 = accept(s, (struct sockaddr *) &from, &from_len)) < 0) {
+      sprintf(errmsg, "kpropd: accept: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      continue;
+    }
+    strcpy(from_str, inet_ntoa(from.sin_addr));
+
+    if ((hp = gethostbyaddr((char*)&(from.sin_addr.s_addr), from_len, AF_INET)) == NULL) {
+      strcpy(hostname, "UNKNOWN");
+    } else {
+      strcpy(hostname, hp->h_name);
+    }
+
+    sprintf(errmsg, "Connection from %s, %s", hostname, from_str);
+    klog(L_KRB_PERR, errmsg);
+
+    /* for krb_rd_{priv, safe} */
+    n = sizeof sin;
+    if (getsockname (s2, (struct sockaddr *) &sin, &n) != 0) {
+      fprintf (stderr, "kpropd: can't get socketname.\n");
+      perror ("getsockname");
+      SlowDeath();
+    }
+    if (n != sizeof (sin)) {
+      fprintf (stderr, "kpropd: can't get socketname. len");
+      SlowDeath();
+    }
+
+    if ((fdlock = open(local_temp, O_WRONLY | O_CREAT, 0600)) < 0) {
+      sprintf(errmsg, "kpropd: open: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if (flock(fdlock, LOCK_EX | LOCK_NB)) {
+      sprintf(errmsg, "kpropd: flock: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if ((fd = creat(local_temp, 0600)) < 0) {
+      sprintf(errmsg, "kpropd: creat: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    if ((n = read (s2, buf, sizeof (kprop_version)))
+       != sizeof (kprop_version)) {
+      klog (L_KRB_PERR, "kpropd: can't read kprop protocol version str.");
+      SlowDeath();
+    }
+    if (strncmp (buf, kprop_version, sizeof (kprop_version))
+       != 0) {
+      sprintf (errmsg, "kpropd: unsupported version %s", buf);
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+
+    if ((n = read (s2, &net_transfer_mode, sizeof (net_transfer_mode)))
+       != sizeof (net_transfer_mode)) {
+      klog (L_KRB_PERR, "kpropd: can't read transfer mode.");
+      SlowDeath();
+    }
+    transfer_mode = ntohs (net_transfer_mode);
+    kerror = krb_recvauth(KOPT_DO_MUTUAL, s2, &ticket,
+                         KPROP_SERVICE_NAME,
+                         my_instance,
+                         &from,
+                         &sin,
+                         &auth_dat,
+                         srvtab,
+                         session_sched,
+                         version);
+    if (kerror != KSUCCESS) {
+      sprintf (errmsg, "kpropd: %s: Calling getkdata", 
+              krb_err_txt[kerror]);
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+       
+    sprintf (errmsg, "kpropd: Connection from %s.%s@%s",
+            auth_dat.pname, auth_dat.pinst, auth_dat.prealm);
+    klog (L_KRB_PERR, errmsg);
+
+    /* AUTHORIZATION is done here.  We might want to expand this to
+     * read an acl file at some point, but allowing for now
+     * KPROP_SERVICE_NAME.KRB_MASTER@local-realm is fine ... */
+
+    if ((strcmp (KPROP_SERVICE_NAME, auth_dat.pname) != 0) ||
+       (strcmp (KRB_MASTER, auth_dat.pinst) != 0) ||
+       (strcmp (my_realm, auth_dat.prealm) != 0)) {
+      klog (L_KRB_PERR, "Authorization denied!");
+      SlowDeath();
+    }
+
+    switch (transfer_mode) {
+    case KPROP_TRANSFER_PRIVATE: 
+      recv_auth (s2, fd, 1     /* private */, &from, &sin, &auth_dat);
+      break;
+    case KPROP_TRANSFER_SAFE: 
+      recv_auth (s2, fd, 0     /* safe */, &from, &sin, &auth_dat);
+      break;
+    case KPROP_TRANSFER_CLEAR: 
+      recv_clear (s2, fd);
+      break;
+    default: 
+      sprintf (errmsg, "kpropd: bad transfer mode %d", transfer_mode);
+      klog (L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+
+    if (transfer_mode != KPROP_TRANSFER_PRIVATE) {
+      klog(L_KRB_PERR, "kpropd: non-private transfers not supported\n");
+      SlowDeath();
+#ifdef doesnt_work_yet
+      lseek(fd, (long) 0, L_SET);
+      if (auth_dat.checksum != get_data_checksum (fd, session_sched)) {
+       klog(L_KRB_PERR, "kpropd: checksum doesn't match");
+       SlowDeath();
+      }
+#endif
+    } else
+
+      {
+       struct stat st;
+       fstat(fd, &st);
+       if (st.st_size != auth_dat.checksum) {
+         klog(L_KRB_PERR, "kpropd: length doesn't match");
+         SlowDeath();
+       }
+      }
+    close(fd);
+    close(s2);
+    klog(L_KRB_PERR, "File received.");
+
+    if (rename(local_temp, local_file) < 0) {
+      sprintf(errmsg, "kpropd: rename: %s", strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    klog(L_KRB_PERR, "Temp file renamed to %s", local_file);
+
+    if (flock(fdlock, LOCK_UN)) {
+      sprintf(errmsg, "kpropd: flock (unlock): %s",
+             strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+    close(fdlock);
+    sprintf(cmd, "%s load %s %s\n", kdb_util_path, local_file, local_db);
+    if (system (cmd) != 0) {
+      klog (L_KRB_PERR, "Couldn't load database");
+      SlowDeath();
+    }
+  }
+}
+
+#ifdef doesnt_work_yet
+unsigned long get_data_checksum(fd, key_sched)
+     int fd;
+     des_key_schedule key_sched;
+{
+  unsigned long cksum = 0;
+  unsigned long cbc_cksum();
+  int n;
+  char buf[BUFSIZ];
+  char obuf[8];
+
+  while (n = read(fd, buf, sizeof buf)) {
+    if (n < 0) {
+      sprintf(errmsg, "kpropd: read (in checksum test): %s",
+             strerror(errno));
+      klog(L_KRB_PERR, errmsg);
+      SlowDeath();
+    }
+#ifndef NOENCRYPTION
+    cksum += des_cbc_cksum(buf, obuf, n, key_sched, key_sched);
+#endif
+  }
+  return cksum;
+}
+#endif
diff --git a/kerberosIV/krb/Makefile b/kerberosIV/krb/Makefile
new file mode 100644 (file)
index 0000000..80fc074
--- /dev/null
@@ -0,0 +1,42 @@
+#      @(#)Makefile    8.1 (Berkeley) 6/1/93
+
+LIB=   krb
+CFLAGS+=-I${.CURDIR}
+SRCS=  cr_err_reply.c create_auth_reply.c create_ciph.c \
+       create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
+       dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c get_admhst.c \
+       get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c get_phost.c \
+       get_pw_tkt.c get_request.c get_svc_in_tkt.c get_tf_fullname.c \
+       get_tf_realm.c getrealm.c getst.c in_tkt.c k_localtime.c klog.c \
+       kname_parse.c kntoln.c kparse.c krb_equiv.c krb_err.c krb_err_txt.c \
+       krb_get_in_tkt.c kuserok.c lifetime.c log.c mk_err.c mk_priv.c \
+       mk_req.c mk_safe.c month_sname.c netread.c netwrite.c one.c \
+       pkt_cipher.c pkt_clen.c rd_err.c rd_priv.c rd_req.c rd_safe.c \
+       read_service_key.c recvauth.c save_credentials.c send_to_kdc.c \
+       sendauth.c str2key.c tf_util.c tkt_string.c
+MAN=   kerberos.3 krb_realmofhost.3 krb_sendauth.3 krb_set_tkt_string.3 \
+       kuserok.3 tf_util.3
+MLINKS+=kerberos.3 krb_mk_req.3 kerberos.3 krb_rd_req.3 kerberos.3 krb_kntoln.3 \
+       kerberos.3 krb_set_key.3 kerberos.3 krb_get_cred.3 kerberos.3 krb_mk_priv.3 \
+       kerberos.3 krb_rd_priv.3 kerberos.3 krb_mk_safe.3 kerberos.3 krb_rd_safe.3 \
+       kerberos.3 krb_mk_err.3 kerberos.3 krb_rd_err.3 kerberos.3 krb_ck_repl.3
+MLINKS+=krb_realmofhost.3 krb_get_phost.3 krb_realmofhost.3 krb_get_krbhst.3 \
+       krb_realmofhost.3 krb_get_admhst.3 krb_realmofhost.3 krb_get_lrealm.3
+MLINKS+=krb_sendauth.3 krb_recvauth.3 krb_sendauth.3 krb_net_write.3 \
+       krb_sendauth.3 krb_net_read.3
+MLINKS+=tf_util.3 tf_init.3 tf_util.3 tf_get_pname.3 tf_util.3 tf_get_pinst.3 \
+       tf_util.3 tf_get_cred.3 tf_util.3 tf_close.3
+
+LDADD+=        ${COM_ERR}
+CLEANFILES+=   krb_err.c krb_err.h
+
+krb_err.c krb_err.h: krb_err.et
+       test -e krb_err.et || ln -s ${.CURDIR}/krb_err.et .
+       ${COMPILE_ET} krb_err.et
+       -test -h krb_err.et && rm krb_err.et
+
+beforeinstall:
+       -cd ${.OBJDIR}; cmp -s krb_err.h ${DESTDIR}/usr/include/kerberosIV/krb_err.h || \
+           install -c -o ${BINOWN} -g ${BINGRP} -m 444 krb_err.h ${DESTDIR}/usr/include/kerberosIV
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/krb/cr_err_reply.c b/kerberosIV/krb/cr_err_reply.c
new file mode 100644 (file)
index 0000000..e2db618
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/cr_err_reply.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * req_act_vno used to be defined as an extern ("defined in server").
+ * However, that does noone anything good, so we define our own so
+ * that the shared libraries do not turn up with an undefined variable!
+ */
+static int my_req_act_vno = KRB_PROT_VERSION;
+
+/*
+ * This routine is used by the Kerberos authentication server to
+ * create an error reply packet to send back to its client.
+ *
+ * It takes a pointer to the packet to be built, the name, instance,
+ * and realm of the principal, the client's timestamp, an error code
+ * and an error string as arguments.  Its return value is undefined.
+ *
+ * The packet is built in the following format:
+ * 
+ * type                        variable           data
+ *                     or constant
+ * ----                        -----------        ----
+ *
+ * unsigned char       req_ack_vno        protocol version number
+ * 
+ * unsigned char       AUTH_MSG_ERR_REPLY protocol message type
+ * 
+ * [least significant  HOST_BYTE_ORDER    sender's (server's) byte
+ * bit of above field]                    order
+ * 
+ * string              pname              principal's name
+ * 
+ * string              pinst              principal's instance
+ * 
+ * string              prealm             principal's realm
+ * 
+ * unsigned long       time_ws            client's timestamp
+ * 
+ * unsigned long       e                  error code
+ * 
+ * string              e_string           error text
+ */
+
+void
+cr_err_reply(pkt, pname, pinst, prealm, time_ws, e, e_string)
+       KTEXT pkt;
+       char *pname;            /* Principal's name */
+       char *pinst;            /* Principal's instance */
+       char *prealm;           /* Principal's authentication domain */
+       u_int32_t time_ws;      /* Workstation time */
+       u_int32_t e;            /* Error code */
+       char *e_string;         /* Text of error */
+{
+    u_char *v = (u_char *) pkt->dat; /* Prot vers number */
+    u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */
+
+    /* Create fixed part of packet */
+    *v = (unsigned char) my_req_act_vno; /* KRB_PROT_VERSION; */
+    *t = (unsigned char) AUTH_MSG_ERR_REPLY;
+    *t |= HOST_BYTE_ORDER;
+
+    if (pname == 0)
+        pname = "";
+    if (pinst == 0)
+        pinst = "";
+    if (prealm == 0)
+        prealm = "";
+
+    /* Add the basic info */
+    (void) strcpy((char *) (pkt->dat+2),pname);
+    pkt->length = 3 + strlen(pname);
+    (void) strcpy((char *)(pkt->dat+pkt->length),pinst);
+    pkt->length += 1 + strlen(pinst);
+    (void) strcpy((char *)(pkt->dat+pkt->length),prealm);
+    pkt->length += 1 + strlen(prealm);
+    /* ws timestamp */
+    bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4);
+    pkt->length += 4;
+    /* err code */
+    bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4);
+    pkt->length += 4;
+    /* err text */
+    (void) strcpy((char *)(pkt->dat+pkt->length),e_string);
+    pkt->length += 1 + strlen(e_string);
+
+    /* And return */
+    return;
+}
diff --git a/kerberosIV/krb/create_auth_reply.c b/kerberosIV/krb/create_auth_reply.c
new file mode 100644 (file)
index 0000000..0918470
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_auth_reply.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine is called by the Kerberos authentication server
+ * to create a reply to an authentication request.  The routine
+ * takes the user's name, instance, and realm, the client's
+ * timestamp, the number of tickets, the user's key version
+ * number and the ciphertext containing the tickets themselves.
+ * It constructs a packet and returns a pointer to it.
+ *
+ * Notes: The packet returned by this routine is static.  Thus, if you
+ * intend to keep the result beyond the next call to this routine, you
+ * must copy it elsewhere.
+ *
+ * The packet is built in the following format:
+ * 
+ *                     variable
+ * type                        or constant        data
+ * ----                        -----------        ----
+ * 
+ * unsigned char       KRB_PROT_VERSION   protocol version number
+ * 
+ * unsigned char       AUTH_MSG_KDC_REPLY protocol message type
+ * 
+ * [least significant  HOST_BYTE_ORDER    sender's (server's) byte
+ *  bit of above field]                           order
+ * 
+ * string              pname              principal's name
+ * 
+ * string              pinst              principal's instance
+ * 
+ * string              prealm             principal's realm
+ * 
+ * unsigned long       time_ws            client's timestamp
+ * 
+ * unsigned char       n                  number of tickets
+ * 
+ * unsigned long       x_date             expiration date
+ * 
+ * unsigned char       kvno               master key version
+ * 
+ * short               w_1                cipher length
+ * 
+ * ---                 cipher->dat        cipher data
+ */
+
+KTEXT
+create_auth_reply(pname, pinst, prealm, time_ws, n, x_date, kvno, cipher)
+       char *pname;            /* Principal's name */
+       char *pinst;            /* Principal's instance */
+       char *prealm;           /* Principal's authentication domain */
+       int32_t time_ws;        /* Workstation time */
+       int n;                  /* Number of tickets */
+       u_int32_t x_date;       /* Principal's expiration date */
+       int kvno;               /* Principal's key version number */
+       KTEXT cipher;           /* Cipher text with tickets and
+                                * session keys */
+{
+    static  KTEXT_ST pkt_st;
+    KTEXT pkt = &pkt_st;
+    unsigned char *v =  pkt->dat; /* Prot vers number */
+    unsigned char *t = (pkt->dat+1); /* Prot message type */
+    short w_l;                 /* Cipher length */
+
+    /* Create fixed part of packet */
+    *v = (unsigned char) KRB_PROT_VERSION;
+    *t = (unsigned char) AUTH_MSG_KDC_REPLY;
+    *t |= HOST_BYTE_ORDER;
+
+    if (n != 0)
+       *v = 3;
+
+    /* Add the basic info */
+    (void) strcpy((char *) (pkt->dat+2), pname);
+    pkt->length = 3 + strlen(pname);
+    (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
+    pkt->length += 1 + strlen(pinst);
+    (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
+    pkt->length += 1 + strlen(prealm);
+    /* Workstation timestamp */
+    bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
+    pkt->length += 4;
+    *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+    /* Expiration date */
+    bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
+    pkt->length += 4;
+
+    /* Now send the ciphertext and info to help decode it */
+    *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
+    w_l = (short) cipher->length;
+    bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
+    pkt->length += 2;
+    bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
+         cipher->length);
+    pkt->length += cipher->length;
+
+    /* And return the packet */
+    return pkt;
+}
diff --git a/kerberosIV/krb/create_ciph.c b/kerberosIV/krb/create_ciph.c
new file mode 100644 (file)
index 0000000..ddc6ef7
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_ciph.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine is used by the authentication server to create
+ * a packet for its client, containing a ticket for the requested
+ * service (given in "tkt"), and some information about the ticket,
+ *
+ * Returns KSUCCESS no matter what.
+ *
+ * The length of the cipher is stored in c->length; the format of
+ * c->dat is as follows:
+ *
+ *                     variable
+ * type                        or constant        data
+ * ----                        -----------        ----
+ * 
+ * 
+ * 8 bytes             session         session key for client, service
+ * 
+ * string              service         service name
+ * 
+ * string              instance        service instance
+ * 
+ * string              realm           KDC realm
+ * 
+ * unsigned char       life            ticket lifetime
+ * 
+ * unsigned char       kvno            service key version number
+ * 
+ * unsigned char       tkt->length     length of following ticket
+ * 
+ * data                        tkt->dat        ticket for service
+ * 
+ * 4 bytes             kdc_time        KDC's timestamp
+ *
+ * <=7 bytes           null               null pad to 8 byte multiple
+ *
+ */
+
+int
+create_ciph(c, session, service, instance, realm,
+           life, kvno, tkt, kdc_time, key)
+       KTEXT c;                /* Text block to hold ciphertext */
+       unsigned char *session; /* Session key to send to user */
+       char *service;          /* Service name on ticket */
+       char *instance;         /* Instance name on ticket */
+       char *realm;            /* Realm of this KDC */
+       u_int32_t life;         /* Lifetime of the ticket */
+       int kvno;               /* Key version number for service */
+       KTEXT tkt;              /* The ticket for the service */
+       u_int32_t kdc_time;     /* KDC time */
+       des_cblock *key;        /* Key to encrypt ciphertext with */
+{
+    char            *ptr;
+    des_key_schedule    key_s;
+
+    ptr = (char *) c->dat;
+
+    bcopy((char *) session, ptr, 8);
+    ptr += 8;
+
+    (void) strcpy(ptr,service);
+    ptr += strlen(service) + 1;
+
+    (void) strcpy(ptr,instance);
+    ptr += strlen(instance) + 1;
+
+    (void) strcpy(ptr,realm);
+    ptr += strlen(realm) + 1;
+
+    *(ptr++) = (unsigned char) life;
+    *(ptr++) = (unsigned char) kvno;
+    *(ptr++) = (unsigned char) tkt->length;
+
+    bcopy((char *)(tkt->dat),ptr,tkt->length);
+    ptr += tkt->length;
+
+    bcopy((char *) &kdc_time,ptr,4);
+    ptr += 4;
+
+    /* guarantee null padded encrypted data to multiple of 8 bytes */
+    bzero(ptr, 7);
+
+    c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+
+#ifndef NOENCRYPTION
+    des_key_sched(key,key_s);
+    des_pcbc_encrypt((des_cblock *)c->dat,(des_cblock *)c->dat,(long) c->length,key_s,
+       key, DES_ENCRYPT);
+#endif /* NOENCRYPTION */
+
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/create_death_packet.c b/kerberosIV/krb/create_death_packet.c
new file mode 100644 (file)
index 0000000..60bd7ec
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_death_packet.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine creates a packet to type AUTH_MSG_DIE which is sent to
+ * the Kerberos server to make it shut down.  It is used only in the
+ * development environment.
+ *
+ * It takes a string "a_name" which is sent in the packet.  A pointer
+ * to the packet is returned.
+ *
+ * The format of the killer packet is:
+ *
+ * type                        variable                data
+ *                     or constant
+ * ----                        -----------             ----
+ *
+ * unsigned char       KRB_PROT_VERSION        protocol version number
+ * 
+ * unsigned char       AUTH_MSG_DIE            message type
+ * 
+ * [least significant  HOST_BYTE_ORDER         byte order of sender
+ *  bit of above field]
+ * 
+ * string              a_name                  presumably, name of
+ *                                             principal sending killer
+ *                                             packet
+ */
+
+#ifdef DEBUG
+KTEXT
+krb_create_death_packet(a_name)
+    char *a_name;
+{
+    static KTEXT_ST pkt_st;
+    KTEXT pkt = &pkt_st;
+
+    unsigned char *v =  pkt->dat;
+    unsigned char *t =  (pkt->dat+1);
+    *v = (unsigned char) KRB_PROT_VERSION;
+    *t = (unsigned char) AUTH_MSG_DIE;
+    *t |= HOST_BYTE_ORDER;
+    (void) strcpy((char *) (pkt->dat+2),a_name);
+    pkt->length = 3 + strlen(a_name);
+    return pkt;
+}
+#endif /* DEBUG */
diff --git a/kerberosIV/krb/create_ticket.c b/kerberosIV/krb/create_ticket.c
new file mode 100644 (file)
index 0000000..4de275b
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/create_ticket.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed.  It then constructs a ticket and returns, leaving the
+ * newly created ticket in tkt.
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket.  When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ * 
+ *                     variable
+ * type                        or constant        data
+ * ----                        -----------        ----
+ *
+ * tkt->length         length of ticket (multiple of 8 bytes)
+ * 
+ * tkt->dat:
+ * 
+ * unsigned char       flags              namely, HOST_BYTE_ORDER
+ * 
+ * string              pname              client's name
+ * 
+ * string              pinstance          client's instance
+ * 
+ * string              prealm             client's realm
+ * 
+ * 4 bytes             paddress           client's address
+ * 
+ * 8 bytes             session            session key
+ * 
+ * 1 byte              life               ticket lifetime
+ * 
+ * 4 bytes             time_sec           KDC timestamp
+ * 
+ * string              sname              service's name
+ * 
+ * string              sinstance          service's instance
+ * 
+ * <=7 bytes           null               null pad to 8 byte multiple
+ *
+ */
+
+int
+krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+                 session, life, time_sec, sname, sinstance, key)
+       KTEXT tkt;              /* Gets filled in by the ticket */
+       unsigned char flags;    /* Various Kerberos flags */
+       char *pname;            /* Principal's name */
+       char *pinstance;        /* Principal's instance */
+       char *prealm;           /* Principal's authentication domain */
+       int32_t paddress;       /* Net address of requesting entity */
+       char *session;          /* Session key inserted in ticket */
+       int16_t life;           /* Lifetime of the ticket */
+       int32_t time_sec;       /* Issue time and date */
+       char *sname;            /* Service Name */
+       char *sinstance;        /* Instance Name */
+       des_cblock *key;        /* Service's secret key */
+{
+    des_key_schedule key_s;
+    register char *data;        /* running index into ticket */
+
+    tkt->length = 0;            /* Clear previous data  */
+    flags |= HOST_BYTE_ORDER;   /* ticket byte order   */
+    bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
+    data = ((char *)tkt->dat) + sizeof(flags);
+    (void) strcpy(data, pname);
+    data += 1 + strlen(pname);
+    (void) strcpy(data, pinstance);
+    data += 1 + strlen(pinstance);
+    (void) strcpy(data, prealm);
+    data += 1 + strlen(prealm);
+    bcopy((char *) &paddress, data, 4);
+    data += 4;
+
+    bcopy((char *) session, data, 8);
+    data += 8;
+    *(data++) = (char) life;
+    /* issue time */
+    bcopy((char *) &time_sec, data, 4);
+    data += 4;
+    (void) strcpy(data, sname);
+    data += 1 + strlen(sname);
+    (void) strcpy(data, sinstance);
+    data += 1 + strlen(sinstance);
+
+    /* guarantee null padded ticket to multiple of 8 bytes */
+    bzero(data, 7);
+    tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+    /* Check length of ticket */
+    if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+        bzero(tkt->dat, tkt->length);
+        tkt->length = 0;
+        return KFAILURE /* XXX */;
+    }
+
+#ifndef NOENCRYPTION
+    des_key_sched(key,key_s);
+    des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length,
+       key_s,key, DES_ENCRYPT);
+#endif
+    return 0;
+}
diff --git a/kerberosIV/krb/debug_decl.c b/kerberosIV/krb/debug_decl.c
new file mode 100644 (file)
index 0000000..97ab1ac
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/debug_decl.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/* Declare global debugging variables. */
+
+int krb_ap_req_debug = 0;
+int krb_debug = 0;
diff --git a/kerberosIV/krb/decomp_ticket.c b/kerberosIV/krb/decomp_ticket.c
new file mode 100644 (file)
index 0000000..c8778dc
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/decomp_ticket.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine takes a ticket and pointers to the variables that
+ * should be filled in based on the information in the ticket.  It
+ * fills in values for its arguments.
+ *
+ * Note: if the client realm field in the ticket is the null string,
+ * then the "prealm" variable is filled in with the local realm (as
+ * defined by KRB_REALM).
+ *
+ * If the ticket byte order is different than the host's byte order
+ * (as indicated by the byte order bit of the "flags" field), then
+ * the KDC timestamp "time_sec" is byte-swapped.  The other fields
+ * potentially affected by byte order, "paddress" and "session" are
+ * not byte-swapped.
+ *
+ * The routine returns KFAILURE if any of the "pname", "pinstance",
+ * or "prealm" fields is too big, otherwise it returns KSUCCESS.
+ *
+ * The corresponding routine to generate tickets is create_ticket.
+ * When changes are made to this routine, the corresponding changes
+ * should also be made to that file.
+ *
+ * See create_ticket.c for the format of the ticket packet.
+ */
+
+int
+decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
+             life, time_sec, sname, sinstance, key, key_s)
+       KTEXT tkt;              /* The ticket to be decoded */
+       unsigned char *flags;   /* Kerberos ticket flags */
+       char *pname;            /* Authentication name */
+       char *pinstance;        /* Principal's instance */
+       char *prealm;           /* Principal's authentication domain */
+       u_int32_t *paddress;    /* Net address of entity
+                                 * requesting ticket */
+       unsigned char *session; /* Session key inserted in ticket */
+       int *life;              /* Lifetime of the ticket */
+       u_int32_t *time_sec;    /* Issue time and date */
+       char *sname;            /* Service name */
+       char *sinstance;        /* Service instance */
+       des_cblock *key;        /* Service's secret key
+                                 * (to decrypt the ticket) */
+       struct des_ks_struct *key_s; /* The precomputed key schedule */
+{
+    static int tkt_swap_bytes;
+    unsigned char *uptr;
+    char *ptr = (char *)tkt->dat;
+
+#ifndef NOENCRYPTION
+    des_pcbc_encrypt((des_cblock *)tkt->dat,(des_cblock *)tkt->dat,(long)tkt->length,
+       key_s,key, DES_DECRYPT);
+#endif /* ! NOENCRYPTION */
+
+    *flags = *ptr;              /* get flags byte */
+    ptr += sizeof(*flags);
+    tkt_swap_bytes = 0;
+    if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
+        tkt_swap_bytes++;
+
+    if (strlen(ptr) > ANAME_SZ)
+        return(KFAILURE);
+    (void) strcpy(pname,ptr);   /* pname */
+    ptr += strlen(pname) + 1;
+
+    if (strlen(ptr) > INST_SZ)
+        return(KFAILURE);
+    (void) strcpy(pinstance,ptr); /* instance */
+    ptr += strlen(pinstance) + 1;
+
+    if (strlen(ptr) > REALM_SZ)
+        return(KFAILURE);
+    (void) strcpy(prealm,ptr);  /* realm */
+    ptr += strlen(prealm) + 1;
+    /* temporary hack until realms are dealt with properly */
+    if (*prealm == 0)
+        (void) strcpy(prealm,KRB_REALM);
+
+    bcopy(ptr,(char *)paddress,4); /* net address */
+    ptr += 4;
+
+    bcopy(ptr,(char *)session,8); /* session key */
+    ptr+= 8;
+#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
+    if (tkt_swap_bytes)
+        swap_C_Block(session);
+#endif
+
+    /* get lifetime, being certain we don't get negative lifetimes */
+    uptr = (unsigned char *) ptr++;
+    *life = (int) *uptr;
+
+    bcopy(ptr,(char *) time_sec,4); /* issue time */
+    ptr += 4;
+    if (tkt_swap_bytes)
+        swap_u_long(*time_sec);
+
+    (void) strcpy(sname,ptr);   /* service name */
+    ptr += 1 + strlen(sname);
+
+    (void) strcpy(sinstance,ptr); /* instance */
+    ptr += 1 + strlen(sinstance);
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/dest_tkt.c b/kerberosIV/krb/dest_tkt.c
new file mode 100644 (file)
index 0000000..1f6d83a
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/dest_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+/*
+ * dest_tkt() is used to destroy the ticket store upon logout.
+ * If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
+ * Otherwise the function returns RET_OK on success, KFAILURE on
+ * failure.
+ *
+ * The ticket file (TKT_FILE) is defined in "krb.h".
+ */
+
+int
+dest_tkt()
+{
+    char *file = TKT_FILE;
+    int i,fd;
+    struct stat statb;
+    char buf[BUFSIZ];
+#ifdef TKT_SHMEM
+    char shmidname[MaxPathLen];
+#endif /* TKT_SHMEM */
+
+    errno = 0;
+    if (lstat(file,&statb) < 0)
+       goto out;
+
+    if (!(statb.st_mode & S_IFREG)
+#ifdef notdef
+       || statb.st_mode & 077
+#endif
+       )
+       goto out;
+
+    if ((fd = open(file, O_RDWR, 0)) < 0)
+       goto out;
+
+    bzero(buf, BUFSIZ);
+
+    for (i = 0; i < statb.st_size; i += BUFSIZ)
+       if (write(fd, buf, BUFSIZ) != BUFSIZ) {
+           (void) fsync(fd);
+           (void) close(fd);
+           goto out;
+       }
+
+    (void) fsync(fd);
+    (void) close(fd);
+
+    (void) unlink(file);
+
+out:
+    if (errno == ENOENT) return RET_TKFIL;
+    else if (errno != 0) return KFAILURE;
+#ifdef TKT_SHMEM
+    /* 
+     * handle the shared memory case 
+     */
+    (void) strcpy(shmidname, file);
+    (void) strcat(shmidname, ".shm");
+    if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
+       return(i);
+#endif /* TKT_SHMEM */
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/extract_ticket.c b/kerberosIV/krb/extract_ticket.c
new file mode 100644 (file)
index 0000000..a3cd877
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/extract_ticket.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine is obsolete.
+ *
+ * This routine accepts the ciphertext returned by kerberos and
+ * extracts the nth ticket.  It also fills in the variables passed as
+ * session, liftime and kvno.
+ */
+
+void
+extract_ticket(cipher, n, session, lifetime, kvno, realm, ticket)
+       KTEXT cipher;           /* The ciphertext */
+       int n;                  /* Which ticket */
+       char *session;          /* The session key for this tkt */
+       int *lifetime;          /* The life of this ticket */
+       int *kvno;              /* The kvno for the service */
+       char *realm;            /* Realm in which tkt issued */
+       KTEXT ticket;           /* The ticket itself */
+{
+    char *ptr;
+    int i;
+
+    /* Start after the ticket lengths */
+    ptr = (char *) cipher->dat;
+    ptr = ptr + 1 + (int) *(cipher->dat);
+
+    /* Step through earlier tickets */
+    for (i = 1; i < n; i++)
+       ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
+    bcopy(ptr, (char *) session, 8); /* Save the session key */
+    ptr += 8;
+    *lifetime = (unsigned char) *(ptr++); /* Save the life of the ticket */
+    *kvno = *(ptr++);          /* Save the kvno */
+    (void) strcpy(realm,ptr);  /* instance */
+    ptr += strlen(realm) + 1;
+
+    /* Save the ticket if its length is non zero */
+    ticket->length = *(cipher->dat+n);
+    if (ticket->length)
+       bcopy(ptr, (char *) (ticket->dat), ticket->length);
+}
diff --git a/kerberosIV/krb/fgetst.c b/kerberosIV/krb/fgetst.c
new file mode 100644 (file)
index 0000000..46319bd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/fgetst.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * fgetst takes a file descriptor, a character pointer, and a count.
+ * It reads from the file it has either read "count" characters, or
+ * until it reads a null byte.  When finished, what has been read exists
+ * in "s". If "count" characters were actually read, the last is changed
+ * to a null, so the returned string is always null-terminated.  fgetst
+ * returns the number of characters read, including the null terminator. 
+ */
+
+int
+fgetst(f, s, n)
+       FILE *f;
+       register char *s;
+       int n;
+{
+    register count = n;
+    int     ch;                /* NOT char; otherwise you don't see EOF */
+
+    while ((ch = getc(f)) != EOF && ch && --count) {
+       *s++ = ch;
+    }
+    *s = '\0';
+    return (n - count);
+}
diff --git a/kerberosIV/krb/get_ad_tkt.c b/kerberosIV/krb/get_ad_tkt.c
new file mode 100644 (file)
index 0000000..fe5b7fd
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_ad_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+static int swap_bytes;
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion.  The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order.  pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+static int
+pkt_clen(pkt)
+       KTEXT pkt;
+{
+    static unsigned short temp,temp2;
+    int clen = 0;
+
+    /* Start of ticket list */
+    unsigned char *ptr = pkt_a_realm(pkt) + 10
+       + strlen((char *)pkt_a_realm(pkt));
+
+    /* Finally the length */
+    bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+    if (swap_bytes) {
+        /* assume a short is 2 bytes?? */
+        swab((char *)&temp,(char *)&temp2,2);
+        temp = temp2;
+    }
+
+    clen = (int) temp;
+
+    if (krb_debug)
+       printf("Clen is %d\n",clen);
+    return(clen);
+}
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+static struct timeval tt_local = { 0, 0 };
+static unsigned long rep_err_code;
+
+/*
+ * get_ad_tkt obtains a new service ticket from Kerberos, using
+ * the ticket-granting ticket which must be in the ticket file.
+ * It is typically called by krb_mk_req() when the client side
+ * of an application is creating authentication information to be
+ * sent to the server side.
+ *
+ * get_ad_tkt takes four arguments: three pointers to strings which
+ * contain the name, instance, and realm of the service for which the
+ * ticket is to be obtained; and an integer indicating the desired
+ * lifetime of the ticket.
+ *
+ * It returns an error status if the ticket couldn't be obtained,
+ * or AD_OK if all went well.  The ticket is stored in the ticket
+ * cache.
+ *
+ * The request sent to the Kerberos ticket-granting service looks
+ * like this:
+ *
+ * pkt->dat
+ *
+ * TEXT                        original contents of    authenticator+ticket
+ *                     pkt->dat                built in krb_mk_req call
+ * 
+ * 4 bytes             time_ws                 always 0 (?)
+ * char                        lifetime                lifetime argument passed
+ * string              service                 service name argument
+ * string              sinstance               service instance arg.
+ *
+ * See "prot.h" for the reply packet layout and definitions of the
+ * extraction macros like pkt_version(), pkt_msg_type(), etc.
+ */
+
+int
+get_ad_tkt(service, sinstance, realm, lifetime)
+       char *service;
+       char *sinstance;
+       char *realm;
+       int lifetime;
+{
+    static KTEXT_ST pkt_st;
+    KTEXT pkt = & pkt_st;      /* Packet to KDC */
+    static KTEXT_ST rpkt_st;
+    KTEXT rpkt = &rpkt_st;     /* Returned packet */
+    static KTEXT_ST cip_st;
+    KTEXT cip = &cip_st;       /* Returned Ciphertext */
+    static KTEXT_ST tkt_st;
+    KTEXT tkt = &tkt_st;       /* Current ticket */
+    des_cblock ses;                /* Session key for tkt */
+    CREDENTIALS cr;
+    int kvno;                  /* Kvno for session key */
+    char lrealm[REALM_SZ];
+    des_cblock key;            /* Key for decrypting cipher */
+    des_key_schedule key_s;
+    long time_ws = 0;
+
+    char s_name[SNAME_SZ];
+    char s_instance[INST_SZ];
+    int msg_byte_order;
+    int kerror;
+    char rlm[REALM_SZ];
+    char *ptr;
+
+    unsigned long kdc_time;   /* KDC time */
+
+    if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+       return(kerror);
+
+    /* Create skeleton of packet to be sent */
+    (void) gettimeofday(&tt_local,(struct timezone *) 0);
+
+    pkt->length = 0;
+
+    /*
+     * Look for the session key (and other stuff we don't need)
+     * in the ticket file for krbtgt.realm@lrealm where "realm" 
+     * is the service's realm (passed in "realm" argument) and 
+     * lrealm is the realm of our initial ticket.  If we don't 
+     * have this, we will try to get it.
+     */
+    
+    if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+       /*
+        * If realm == lrealm, we have no hope, so let's not even try.
+        */
+       if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
+           return(AD_NOTGT);
+       else{
+           if ((kerror = 
+                get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
+               return(kerror);
+           if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
+               return(kerror);
+       }
+    }
+    
+    /*
+     * Make up a request packet to the "krbtgt.realm@lrealm".
+     * Start by calling krb_mk_req() which puts ticket+authenticator
+     * into "pkt".  Then tack other stuff on the end.
+     */
+    
+    kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+
+    if (kerror)
+       return(AD_NOTGT);
+
+    /* timestamp */
+    bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
+    pkt->length += 4;
+    *(pkt->dat+(pkt->length)++) = (char) lifetime;
+    (void) strcpy((char *) (pkt->dat+pkt->length),service);
+    pkt->length += 1 + strlen(service);
+    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+    pkt->length += 1 + strlen(sinstance);
+
+    rpkt->length = 0;
+
+    /* Send the request to the local ticket-granting server */
+    if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror);
+
+    /* check packet version of the returned packet */
+    if (pkt_version(rpkt) != KRB_PROT_VERSION )
+        return(INTK_PROT);
+
+    /* Check byte order */
+    msg_byte_order = pkt_msg_type(rpkt) & 1;
+    swap_bytes = 0;
+    if (msg_byte_order != HOST_BYTE_ORDER)
+       swap_bytes++;
+
+    switch (pkt_msg_type(rpkt) & ~1) {
+    case AUTH_MSG_KDC_REPLY:
+       break;
+    case AUTH_MSG_ERR_REPLY:
+       bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
+       if (swap_bytes)
+           swap_u_long(rep_err_code);
+       return(rep_err_code);
+
+    default:
+       return(INTK_PROT);
+    }
+
+    /* Extract the ciphertext */
+    cip->length = pkt_clen(rpkt);       /* let clen do the swap */
+
+    bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
+
+#ifndef NOENCRYPTION
+    /* Attempt to decrypt it */
+
+    des_key_sched(&cr.session,key_s);
+    if (krb_debug)  printf("About to do decryption ...");
+    des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)cip->dat,
+                 (long) cip->length,key_s,&cr.session,0);
+#endif /* !NOENCRYPTION */
+    /* Get rid of all traces of key */
+    bzero((char *) cr.session, sizeof(key));
+    bzero((char *) key_s, sizeof(key_s));
+
+    ptr = (char *) cip->dat;
+
+    bcopy(ptr,(char *)ses,8);
+    ptr += 8;
+
+    (void) strcpy(s_name,ptr);
+    ptr += strlen(s_name) + 1;
+
+    (void) strcpy(s_instance,ptr);
+    ptr += strlen(s_instance) + 1;
+
+    (void) strcpy(rlm,ptr);
+    ptr += strlen(rlm) + 1;
+
+    lifetime = (unsigned char) ptr[0];
+    kvno = (unsigned long) ptr[1];
+    tkt->length = (int) ptr[2];
+    ptr += 3;
+    bcopy(ptr,(char *)(tkt->dat),tkt->length);
+    ptr += tkt->length;
+
+    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+        strcmp(rlm, realm))    /* not what we asked for */
+       return(INTK_ERR);       /* we need a better code here XXX */
+
+    /* check KDC time stamp */
+    bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+    if (swap_bytes) swap_u_long(kdc_time);
+
+    ptr += 4;
+
+    (void) gettimeofday(&tt_local,(struct timezone *) 0);
+    if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+        return(RD_AP_TIME);            /* XXX should probably be better
+                                          code */
+    }
+
+    if ((kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
+                                 kvno,tkt,tt_local.tv_sec)))
+       return(kerror);
+
+    return(AD_OK);
+}
diff --git a/kerberosIV/krb/get_admhst.c b/kerberosIV/krb/get_admhst.c
new file mode 100644 (file)
index 0000000..1aedd73
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_admhst.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos database
+ * administration server can be found.
+ *
+ * krb_get_admhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer n, and
+ * returns (in h) the nth administrative host entry from the configuration
+ * file (KRB_CONF, defined in "krb.h") associated with the specified realm.
+ *
+ * On error, get_admhst returns KFAILURE. If all goes well, the routine
+ * returns KSUCCESS.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * a Kerberos admin server.  In the long run, this functionality will be
+ * provided by a nameserver.
+ */
+
+int
+krb_get_admhst(h, r, n)
+       char *h;
+       char *r;
+       int n;
+{
+    FILE *cnffile;
+    char tr[REALM_SZ];
+    char linebuf[BUFSIZ];
+    char scratch[64];
+    register int i;
+
+    if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+        char tbuf[128];
+        char *tdir = (char *) getenv("KRBCONFDIR");
+        strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf));
+        strncat(tbuf, "/krb.conf", sizeof(tbuf));
+        tbuf[sizeof(tbuf)-1] = 0;
+        if ((cnffile = fopen(tbuf,"r")) == NULL)
+            return(KFAILURE);
+    }
+    if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+       /* error reading */
+       (void) fclose(cnffile);
+       return(KFAILURE);
+    }
+    if (!strchr(linebuf, '\n')) {
+       /* didn't all fit into buffer, punt */
+       (void) fclose(cnffile);
+       return(KFAILURE);
+    }
+    for (i = 0; i < n; ) {
+       /* run through the file, looking for admin host */
+       if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+            (void) fclose(cnffile);
+            return(KFAILURE);
+        }
+       /* need to scan for a token after 'admin' to make sure that
+          admin matched correctly */
+       if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
+           continue;
+        if (!strcmp(tr,r))
+            i++;
+    }
+    (void) fclose(cnffile);
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/get_cred.c b/kerberosIV/krb/get_cred.c
new file mode 100644 (file)
index 0000000..a301af4
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_cred.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * krb_get_cred takes a service name, instance, and realm, and a
+ * structure of type CREDENTIALS to be filled in with ticket
+ * information.  It then searches the ticket file for the appropriate
+ * ticket and fills in the structure with the corresponding
+ * information from the file.  If successful, it returns KSUCCESS.
+ * On failure it returns a Kerberos error code.
+ */
+
+int
+krb_get_cred(service, instance, realm, c)
+       char *service;          /* Service name */
+       char *instance;         /* Instance */
+       char *realm;            /* Auth domain */
+       CREDENTIALS *c;         /* Credentials struct */
+{
+    int tf_status;              /* return value of tf function calls */
+
+    /* Open ticket file and lock it for shared reading */
+    if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
+       return(tf_status);
+
+    /* Copy principal's name and instance into the CREDENTIALS struc c */
+
+    if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
+        (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
+       return (tf_status);
+
+    /* Search for requested service credentials and copy into c */
+       
+    while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
+        /* Is this the right ticket? */
+       if ((strcmp(c->service,service) == 0) &&
+           (strcmp(c->instance,instance) == 0) &&
+           (strcmp(c->realm,realm) == 0))
+                  break;
+    }
+    (void) tf_close();
+
+    if (tf_status == EOF)
+       return (GC_NOTKT);
+    return(tf_status);
+}
diff --git a/kerberosIV/krb/get_in_tkt.c b/kerberosIV/krb/get_in_tkt.c
new file mode 100644 (file)
index 0000000..7e5f1ad
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_in_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This file contains two routines: passwd_to_key() converts
+ * a password into a DES key (prompting for the password if
+ * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
+ * a user.
+ */
+
+/*
+ * passwd_to_key(): given a password, return a DES key.
+ * There are extra arguments here which (used to be?)
+ * used by srvtab_to_key().
+ *
+ * If the "passwd" argument is not null, generate a DES
+ * key from it, using string_to_key().
+ *
+ * If the "passwd" argument is null, call des_read_password()
+ * to prompt for a password and then convert it into a DES key.
+ *
+ * In either case, the resulting key is put in the "key" argument,
+ * and 0 is returned.
+ */
+
+/*ARGSUSED */
+static int
+passwd_to_key(user, instance, realm, passwd, key)
+       char *user;
+       char *instance;
+       char *realm;
+       char *passwd;
+       des_cblock *key;
+{
+#ifdef NOENCRYPTION
+    if (!passwd)
+       placebo_read_password(key, "Password: ", 0);
+#else
+    if (passwd)
+       des_string_to_key(passwd,key);
+    else
+       des_read_password(key,"Password: ",0);
+#endif
+    return (0);
+}
+
+/*ARGSUSED */
+static int
+afs_passwd_to_key(user, instance, realm, passwd, key)
+       char *user;
+       char *instance;
+       char *realm;
+       char *passwd;
+       des_cblock *key;
+{
+#ifdef NOENCRYPTION
+    if (!passwd)
+        placebo_read_password(key, "Password: ", 0);
+#else /* Do encyryption */
+    if (passwd)
+        afs_string_to_key(passwd, realm, key);
+    else {
+        des_read_password(key, "Password: ", 0);
+    }
+#endif /* NOENCRYPTION */
+    return (0);
+}
+
+/*
+ * krb_get_pw_in_tkt() takes the name of the server for which the initial
+ * ticket is to be obtained, the name of the principal the ticket is
+ * for, the desired lifetime of the ticket, and the user's password.
+ * It passes its arguments on to krb_get_in_tkt(), which contacts
+ * Kerberos to get the ticket, decrypts it using the password provided,
+ * and stores it away for future use.
+ *
+ * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
+ * the name of a routine (passwd_to_key()) to be used to get the
+ * password in case the "password" argument is null and NULL for the
+ * decryption procedure indicating that krb_get_in_tkt should use the 
+ * default method of decrypting the response from the KDC.
+ *
+ * The result of the call to krb_get_in_tkt() is returned.
+ */
+
+int
+krb_get_pw_in_tkt(user, instance, realm, service, sinstance, life, password)
+       char *user;
+       char *instance;
+       char *realm;
+       char *service;
+       char *sinstance;
+       int life;
+       char *password;
+{
+    char pword[100];           /* storage for the password */
+    int code;
+
+    /* Only request password once! */
+    if (!password) {
+        if (des_read_pw_string(pword, sizeof(pword)-1, "Password: ", 0))
+            pword[0] = '\0'; /* something wrong */
+        password = pword;
+    }
+
+    code = krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+                          passwd_to_key, NULL, password);
+    if (code != INTK_BADPW)
+      goto done;
+
+    code = krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+                          afs_passwd_to_key, NULL, password);
+    if (code != INTK_BADPW)
+      goto done;
+
+  done:
+    if (password == pword)
+        bzero(pword, sizeof(pword));
+    return(code);
+}
+
+#ifdef NOENCRYPTION
+/*
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_in_tkt.c,v $
+ * $Author: tholo $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine prints the supplied string to standard
+ * output as a prompt, and reads a password string without
+ * echoing.
+ */
+
+#ifndef        lint
+static char rcsid_read_password_c[] =
+"Bones$Header: /home/cvs/src/kerberosIV/krb/Attic/get_in_tkt.c,v 1.1.1.1 1995/12/14 06:52:39 tholo Exp $";
+#endif /* lint */
+
+#include <des.h>
+#include "conf.h"
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+
+static jmp_buf env;
+
+static void sig_restore();
+static push_signals(), pop_signals();
+int placebo_read_pw_string();
+
+/*** Routines ****************************************************** */
+int
+placebo_read_password(k,prompt,verify)
+    des_cblock *k;
+    char *prompt;
+    int        verify;
+{
+    int ok;
+    char key_string[BUFSIZ];
+
+    if (setjmp(env)) {
+       ok = -1;
+       goto lose;
+    }
+
+    ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
+    if (ok == 0)
+       bzero(k, sizeof(C_Block));
+
+lose:
+    bzero(key_string, sizeof (key_string));
+    return ok;
+}
+
+/*
+ * This version just returns the string, doesn't map to key.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int
+placebo_read_pw_string(s,max,prompt,verify)
+    char *s;
+    int        max;
+    char *prompt;
+    int        verify;
+{
+    int ok = 0;
+    char *ptr;
+    
+    jmp_buf old_env;
+    struct sgttyb tty_state;
+    char key_string[BUFSIZ];
+
+    if (max > BUFSIZ) {
+       return -1;
+    }
+
+    bcopy(old_env, env, sizeof(env));
+    if (setjmp(env))
+       goto lose;
+
+    /* save terminal state*/
+    if (ioctl(0,TIOCGETP,&tty_state) == -1) 
+       return -1;
+
+    push_signals();
+    /* Turn off echo */
+    tty_state.sg_flags &= ~ECHO;
+    if (ioctl(0,TIOCSETP,&tty_state) == -1)
+       return -1;
+    while (!ok) {
+       printf(prompt);
+       fflush(stdout);
+       if (!fgets(s, max, stdin)) {
+           clearerr(stdin);
+           continue;
+       }
+       if ((ptr = index(s, '\n')))
+           *ptr = '\0';
+       if (verify) {
+           printf("\nVerifying, please re-enter %s",prompt);
+           fflush(stdout);
+           if (!fgets(key_string, sizeof(key_string), stdin)) {
+               clearerr(stdin);
+               continue;
+           }
+            if ((ptr = index(key_string, '\n')))
+           *ptr = '\0';
+           if (strcmp(s,key_string)) {
+               printf("\n\07\07Mismatch - try again\n");
+               fflush(stdout);
+               continue;
+           }
+       }
+       ok = 1;
+    }
+
+lose:
+    if (!ok)
+       bzero(s, max);
+    printf("\n");
+    /* turn echo back on */
+    tty_state.sg_flags |= ECHO;
+    if (ioctl(0,TIOCSETP,&tty_state))
+       ok = 0;
+    pop_signals();
+    bcopy(env, old_env, sizeof(env));
+    if (verify)
+       bzero(key_string, sizeof (key_string));
+    s[max-1] = 0;              /* force termination */
+    return !ok;                        /* return nonzero if not okay */
+}
+
+/*
+ * this can be static since we should never have more than
+ * one set saved....
+ */
+static RETSIGTYPE (*old_sigfunc[NSIG])();
+
+static
+push_signals()
+{
+    register i;
+    for (i = 0; i < NSIG; i++)
+       old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static
+pop_signals()
+{
+    register i;
+    for (i = 0; i < NSIG; i++)
+       signal(i,old_sigfunc[i]);
+}
+
+static void
+sig_restore(sig,code,scp)
+    int sig,code;
+    struct sigcontext *scp;
+{
+    longjmp(env,1);
+}
+#endif /* NOENCRYPTION */
diff --git a/kerberosIV/krb/get_krbhst.c b/kerberosIV/krb/get_krbhst.c
new file mode 100644 (file)
index 0000000..3b386c8
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_krbhst.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos authenti-
+ * cation server can be found.
+ *
+ * krb_get_krbhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer, n, and
+ * returns (in h) the nth entry from the configuration file (KRB_CONF,
+ * defined in "krb.h") associated with the specified realm.
+ *
+ * On end-of-file, krb_get_krbhst returns KFAILURE.  If n=1 and the
+ * configuration file does not exist, krb_get_krbhst will return KRB_HOST
+ * (also defined in "krb.h").  If all goes well, the routine returnes
+ * KSUCCESS.
+ *
+ * The KRB_CONF file contains the name of the local realm in the first
+ * line (not used by this routine), followed by lines indicating realm/host
+ * entries.  The words "admin server" following the hostname indicate that 
+ * the host provides an administrative database server.
+ *
+ * For example:
+ *
+ *     ATHENA.MIT.EDU
+ *     ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ *     ATHENA.MIT.EDU kerberos-2.mit.edu
+ *     LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * kerberos.  In the long run, this functionality will be provided by a
+ * nameserver.
+ */
+
+int
+krb_get_krbhst(h, r, n)
+       char *h;
+       char *r;
+       int n;
+{
+    FILE *cnffile;
+    char tr[REALM_SZ];
+    char linebuf[BUFSIZ];
+    register int i;
+
+    if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+        char tbuf[128];
+        char *tdir = (char *) getenv("KRBCONFDIR");
+        strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf));
+        strncat(tbuf, "/krb.conf", sizeof(tbuf));
+        tbuf[sizeof(tbuf)-1] = 0;
+        if ((cnffile = fopen(tbuf,"r")) == NULL)
+            if (n==1) {
+                (void) strcpy(h,KRB_HOST);
+                return(KSUCCESS);
+            }
+            else
+                return(KFAILURE);
+    }
+    if (fscanf(cnffile,"%s",tr) == EOF)
+        return(KFAILURE);
+    /* run through the file, looking for the nth server for this realm */
+    for (i = 1; i <= n;) {
+       if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+            (void) fclose(cnffile);
+            return(KFAILURE);
+        }
+       if (sscanf(linebuf, "%s %s", tr, h) != 2)
+           continue;
+        if (!strcmp(tr,r))
+            i++;
+    }
+    (void) fclose(cnffile);
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/get_krbrlm.c b/kerberosIV/krb/get_krbrlm.c
new file mode 100644 (file)
index 0000000..1c8ea6e
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_krbrlm.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * krb_get_lrealm takes a pointer to a string, and a number, n.  It fills
+ * in the string, r, with the name of the nth realm specified on the
+ * first line of the kerberos config file (KRB_CONF, defined in "krb.h").
+ * It returns 0 (KSUCCESS) on success, and KFAILURE on failure.  If the
+ * config file does not exist, and if n=1, a successful return will occur
+ * with r = KRB_REALM (also defined in "krb.h").
+ *
+ * NOTE: for archaic & compatibility reasons, this routine will only return
+ * valid results when n = 1.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ */
+
+int
+krb_get_lrealm(r, n)
+       char *r;
+       int n;
+{
+    FILE *cnffile;
+
+    if (n > 1)
+       return(KFAILURE);  /* Temporary restriction */
+
+    if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+        char tbuf[128];
+        char *tdir = (char *) getenv("KRBCONFDIR");
+        strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf));
+        strncat(tbuf, "/krb.conf", sizeof(tbuf));
+        tbuf[sizeof(tbuf)-1] = 0;
+        if ((cnffile = fopen(tbuf,"r")) == NULL)
+            if (n == 1) {
+                (void) strcpy(r, KRB_REALM);
+                return(KSUCCESS);
+            }
+            else
+                return(KFAILURE);
+    }
+
+    if (fscanf(cnffile,"%s",r) != 1) {
+        (void) fclose(cnffile);
+        return(KFAILURE);
+    }
+    (void) fclose(cnffile);
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/get_phost.c b/kerberosIV/krb/get_phost.c
new file mode 100644 (file)
index 0000000..81f7c05
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_phost.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#define USE_FULL_HOST_NAME      0
+
+#include <ctype.h>
+#include <netdb.h>
+
+/*
+ * This routine takes an alias for a host name and returns the first
+ * field, lower case, of its domain name.  For example, if "menel" is
+ * an alias for host officially named "menelaus" (in /etc/hosts), for
+ * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
+ * is returned.
+ *
+ * This is done for historical Athena reasons: the Kerberos name of
+ * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
+ * where "host"is the lowercase for of the host name ("menelaus").
+ * This should go away: the instance should be the domain name
+ * (MENELAUS.MIT.EDU).  But for now we need this routine...
+ *
+ * A pointer to the name is returned, if found, otherwise a pointer
+ * to the original "alias" argument is returned.
+ */
+
+char *
+krb_get_phost(alias)
+       char *alias;
+{
+    struct hostent *h;
+    char *phost = alias;
+    if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
+#if     USE_FULL_HOST_NAME
+        char *p;
+#else /* USE_FULL_HOST_NAME */
+        char *p = strchr( h->h_name, '.' ); 
+        if (p) 
+            *p = 0; 
+#endif /* USE_FULL_HOST_NAME */
+        p = phost = h->h_name;
+        do {
+            if (isupper(*p)) *p=tolower(*p);
+        } while (*p++);
+    }
+    return(phost);
+}
diff --git a/kerberosIV/krb/get_pw_tkt.c b/kerberosIV/krb/get_pw_tkt.c
new file mode 100644 (file)
index 0000000..a94ff23
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_pw_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * Get a ticket for the password-changing server ("changepw.KRB_MASTER").
+ *
+ * Given the name, instance, realm, and current password of the
+ * principal for which the user wants a password-changing-ticket,
+ * return either:
+ *
+ *     GT_PW_BADPW if current password was wrong,
+ *     GT_PW_NULL  if principal had a NULL password,
+ *     or the result of the krb_get_pw_in_tkt() call.
+ *
+ * First, try to get a ticket for "user.instance@realm" to use the
+ * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
+ * The requested lifetime for the ticket is "1", and the current
+ * password is the "cpw" argument given.
+ *
+ * If the password was bad, give up.
+ *
+ * If the principal had a NULL password in the Kerberos database
+ * (indicating that the principal is known to Kerberos, but hasn't
+ * got a password yet), try instead to get a ticket for the principal
+ * "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
+ * Use the password "changepwkrb" instead of "cpw".  Return GT_PW_NULL
+ * if all goes well, otherwise the error.
+ *
+ * If this routine succeeds, a ticket and session key for either the
+ * principal "user.instance@realm" or "default.changepw@realm" to use
+ * the password-changing server will be in the user's ticket file.
+ */
+
+int
+get_pw_tkt(user, instance, realm, cpw)
+       char *user;
+       char *instance;
+       char *realm;
+       char *cpw;
+{
+    int kerror;
+
+    kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
+                              KRB_MASTER, 1, cpw);
+
+    if (kerror == INTK_BADPW)
+       return(GT_PW_BADPW);
+
+    if (kerror == KDC_NULL_KEY) {
+       kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
+                                  KRB_MASTER,1,"changepwkrb");
+       if (kerror)
+           return(kerror);
+       return(GT_PW_NULL);
+    }
+
+    return(kerror);
+}
diff --git a/kerberosIV/krb/get_request.c b/kerberosIV/krb/get_request.c
new file mode 100644 (file)
index 0000000..b7bf008
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_request.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This procedure is obsolete.  It is used in the kerberos_slave
+ * code for Version 3 tickets.
+ *
+ * This procedure sets s_name, and instance to point to
+ * the corresponding fields from tne nth request in the packet.
+ * it returns the lifetime requested.  Garbage will be returned
+ * if there are less than n requests in the packet.
+ */
+
+int
+get_request(pkt, n, s_name, instance)
+       KTEXT pkt;              /* The packet itself */
+       int n;                  /* Which request do we want */
+       char **s_name;          /* Service name to be filled in */
+       char **instance;        /* Instance name to be filled in */
+{
+    /* Go to the beginning of the request list */
+    char *ptr = (char *) pkt_a_realm(pkt) + 6 +
+       strlen((char *)pkt_a_realm(pkt));
+
+    /* Read requests until we hit the right one */
+    while (n-- > 1) {
+        ptr++;
+        ptr += 1 + strlen(ptr);
+        ptr += 1 + strlen(ptr);
+    }
+
+    /* Set the arguments to point to the right place */
+    *s_name = 1 + ptr;
+    *instance = 2 + ptr + strlen(*s_name);
+
+    /* Return the requested lifetime */
+    return((int) *ptr);
+}
diff --git a/kerberosIV/krb/get_svc_in_tkt.c b/kerberosIV/krb/get_svc_in_tkt.c
new file mode 100644 (file)
index 0000000..dd388c2
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_svc_in_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This file contains two routines: srvtab_to_key(), which gets
+ * a server's key from a srvtab file, and krb_get_svc_in_tkt() which
+ * gets an initial ticket for a server.
+ */
+
+/*
+ * srvtab_to_key(): given a "srvtab" file (where the keys for the
+ * service on a host are stored), return the private key of the
+ * given service (user.instance@realm).
+ *
+ * srvtab_to_key() passes its arguments on to read_service_key(),
+ * plus one additional argument, the key version number.
+ * (Currently, the key version number is always 0; this value
+ * is treated as a wildcard by read_service_key().)
+ *
+ * If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
+ * is passed in its place.
+ *
+ * It returns the return value of the read_service_key() call.
+ * The service key is placed in "key".
+ */
+
+static int 
+srvtab_to_key(user, instance, realm, srvtab, key)
+       char *user;
+       char *instance;
+       char *realm;
+       char *srvtab;
+       unsigned char *key;
+{
+    if (!srvtab)
+        srvtab = KEYFILE;
+
+    return(read_service_key(user, instance, realm, 0, srvtab,
+                            (char *)key));
+}
+
+/*
+ * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
+ * plus two additional arguments: a pointer to the srvtab_to_key()
+ * function to be used to get the key from the key file and a NULL
+ * for the decryption procedure indicating that krb_get_in_tkt should 
+ * use the default method of decrypting the response from the KDC.
+ *
+ * It returns the return value of the krb_get_in_tkt() call.
+ */
+
+int
+krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+       char *user;
+       char *instance;
+       char *realm;
+       char *service;
+       char *sinstance;
+       int life;
+       char *srvtab;
+{
+    return(krb_get_in_tkt(user, instance, realm, service, sinstance,
+                          life, srvtab_to_key, NULL, srvtab));
+}
diff --git a/kerberosIV/krb/get_tf_fullname.c b/kerberosIV/krb/get_tf_fullname.c
new file mode 100644 (file)
index 0000000..13b64d3
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_tf_fullname.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This file contains a routine to extract the fullname of a user
+ * from the ticket file.
+ */
+
+/*
+ * krb_get_tf_fullname() takes four arguments: the name of the 
+ * ticket file, and variables for name, instance, and realm to be
+ * returned in.  Since the realm of a ticket file is not really fully 
+ * supported, the realm used will be that of the the first ticket in 
+ * the file as this is the one that was obtained with a password by
+ * krb_get_in_tkt().
+ */
+
+int
+krb_get_tf_fullname(ticket_file, name, instance, realm)
+       char *ticket_file;
+       char *name;
+       char *instance;
+       char *realm;
+{
+    int tf_status;
+    CREDENTIALS c;
+
+    if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
+       return(tf_status);
+
+    if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
+       ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
+       return (tf_status);
+    
+    if (name)
+       strcpy(name, c.pname);
+    if (instance)
+       strcpy(instance, c.pinst);
+    if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
+       if (realm)
+           strcpy(realm, c.realm);
+    }
+    else {
+       if (tf_status == EOF)
+           return(KFAILURE);
+       else
+           return(tf_status);
+    }    
+    (void) tf_close();
+    
+    return(tf_status);
+}
diff --git a/kerberosIV/krb/get_tf_realm.c b/kerberosIV/krb/get_tf_realm.c
new file mode 100644 (file)
index 0000000..0195fc7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/get_tf_realm.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This file contains a routine to extract the realm of a kerberos
+ * ticket file.
+ */
+
+/*
+ * krb_get_tf_realm() takes two arguments: the name of a ticket 
+ * and a variable to store the name of the realm in.
+ * 
+ */
+
+int
+krb_get_tf_realm(ticket_file, realm)
+       char *ticket_file;
+       char *realm;
+{
+    return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
+}
diff --git a/kerberosIV/krb/getrealm.c b/kerberosIV/krb/getrealm.c
new file mode 100644 (file)
index 0000000..f4bd245
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/getrealm.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#define MATCH_SUBDOMAINS        0
+
+/* for Ultrix and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+/*
+ * krb_realmofhost.
+ * Given a fully-qualified domain-style primary host name,
+ * return the name of the Kerberos realm for the host.
+ * If the hostname contains no discernable domain, or an error occurs,
+ * return the local realm name, as supplied by get_krbrlm().
+ * If the hostname contains a domain, but no translation is found,
+ * the hostname's domain is converted to upper-case and returned.
+ *
+ * The format of each line of the translation file is:
+ * domain_name kerberos_realm
+ * -or-
+ * host_name kerberos_realm
+ *
+ * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
+ * host names should be in the usual form (e.g. FOO.BAR.BAZ)
+ */
+
+static char ret_realm[REALM_SZ+1];
+
+char *
+krb_realmofhost(host)
+       char *host;
+{
+       char *domain;
+       FILE *trans_file;
+       char trans_host[MAXHOSTNAMELEN+1];
+       char trans_realm[REALM_SZ+1];
+       int retval;
+
+       domain = strchr(host, '.');
+
+       /* prepare default */
+       if (domain) {
+               char *cp;
+
+               strncpy(ret_realm, &domain[1], REALM_SZ);
+               ret_realm[REALM_SZ] = '\0';
+               /* Upper-case realm */
+               for (cp = ret_realm; *cp; cp++)
+                       if (islower(*cp))
+                               *cp = toupper(*cp);
+       } else {
+               krb_get_lrealm(ret_realm, 1);
+       }
+
+       if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
+               char tbuf[128];
+               char *tdir = (char *) getenv("KRBCONFDIR");
+               strncpy(tbuf, tdir ? tdir : "/etc", sizeof(tbuf));
+               strncat(tbuf, "/krb.realms", sizeof(tbuf));
+               tbuf[sizeof(tbuf)-1] = 0;
+               if ((trans_file = fopen(tbuf,"r")) == NULL)
+                        return(ret_realm); /* krb_errno = KRB_NO_TRANS */
+       }
+       while (1) {
+               if ((retval = fscanf(trans_file, "%s %s",
+                                    trans_host, trans_realm)) != 2) {
+                       if (retval == EOF) {
+                               fclose(trans_file);
+                               return(ret_realm);
+                       }
+                       continue;       /* ignore broken lines */
+               }
+               trans_host[MAXHOSTNAMELEN] = '\0';
+               trans_realm[REALM_SZ] = '\0';
+               if (!strcasecmp(trans_host, host)) {
+                       /* exact match of hostname, so return the realm */
+                       (void) strcpy(ret_realm, trans_realm);
+                       fclose(trans_file);
+                       return(ret_realm);
+               }
+               if ((trans_host[0] == '.') && domain) { 
+#if     MATCH_SUBDOMAINS
+                        char *cp;
+                        for (cp = domain; cp != NULL; cp = strchr(cp+1, '.')) {
+                                /* this is a domain match */
+                                if (!strcasecmp(trans_host, cp)) {
+                                        /* domain match, save for later */
+                                        (void) strcpy(ret_realm, trans_realm);
+                                        continue;
+                                }
+                        }
+#else /* MATCH_SUBDOMAINS */
+                       /* this is a domain match */ 
+                       if (!strcasecmp(trans_host, domain)) { 
+                               /* domain match, save for later */ 
+                               (void) strcpy(ret_realm, trans_realm); 
+                               continue; 
+                       } 
+#endif /* MATCH_SUBDOMAINS */
+               }
+       }
+}
diff --git a/kerberosIV/krb/getst.c b/kerberosIV/krb/getst.c
new file mode 100644 (file)
index 0000000..fa3d233
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/getst.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * getst() takes a file descriptor, a string and a count.  It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte.  When finished, what has been read exists in
+ * the given string "s".  If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated.  getst() returns the number of characters read, including
+ * the null terminator.
+ */
+
+int
+getst(fd, s, n)
+       int fd;
+       register char *s;
+       int n;
+{
+    register count = n;
+    while (read(fd, s, 1) > 0 && --count)
+        if (*s++ == '\0')
+            return (n - count);
+    *s = '\0';
+    return (n - count);
+}
diff --git a/kerberosIV/krb/in_tkt.c b/kerberosIV/krb/in_tkt.c
new file mode 100644 (file)
index 0000000..bddb2d8
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/in_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+/*
+ * in_tkt() is used to initialize the ticket store.  It creates the
+ * file to contain the tickets and writes the given user's name "pname"
+ * and instance "pinst" in the file.  in_tkt() returns KSUCCESS on
+ * success, or KFAILURE if something goes wrong.
+ */
+
+int
+in_tkt(pname, pinst)
+       char *pname;
+       char *pinst;
+{
+    int tktfile;
+    uid_t me, metoo;
+    struct stat buf;
+    int count;
+    char *file = TKT_FILE;
+    int fd;
+    register int i;
+    char charbuf[BUFSIZ];
+#ifdef TKT_SHMEM
+    char shmidname[MaxPathLen];
+#endif /* TKT_SHMEM */
+
+    me = getuid ();
+    metoo = geteuid();
+    if (lstat(file,&buf) == 0) {
+       if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+           buf.st_mode & 077) {
+           if (krb_debug)
+               fprintf(stderr,"Error initializing %s",file);
+           return(KFAILURE);
+       }
+       /* file already exists, and permissions appear ok, so nuke it */
+       if ((fd = open(file, O_RDWR, 0)) < 0)
+           goto out; /* can't zero it, but we can still try truncating it */
+
+       bzero(charbuf, sizeof(charbuf));
+
+       for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+           if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
+               (void) fsync(fd);
+               (void) close(fd);
+               goto out;
+           }
+       
+       (void) fsync(fd);
+       (void) close(fd);
+    }
+ out:
+    /* arrange so the file is owned by the ruid
+       (swap real & effective uid if necessary).
+       This isn't a security problem, since the ticket file, if it already
+       exists, has the right uid (== ruid) and mode. */
+    if (me != metoo) {
+       if (setreuid(metoo, me) < 0) {
+           /* can't switch??? barf! */
+           if (krb_debug)
+               perror("in_tkt: setreuid");
+           return(KFAILURE);
+       } else
+           if (krb_debug)
+               printf("swapped UID's %d and %d\n",(int)metoo,(int)me);
+    }
+    if ((tktfile = creat(file,0600)) < 0) {
+       if (krb_debug)
+           fprintf(stderr,"Error initializing %s",TKT_FILE);
+        return(KFAILURE);
+    }
+    if (me != metoo) {
+       if (setreuid(me, metoo) < 0) {
+           /* can't switch??? barf! */
+           if (krb_debug)
+               perror("in_tkt: setreuid2");
+           return(KFAILURE);
+       } else
+           if (krb_debug)
+               printf("swapped UID's %d and %d\n",(int)me,(int)metoo);
+    }
+    if (lstat(file,&buf) < 0) {
+       if (krb_debug)
+           fprintf(stderr,"Error initializing %s",TKT_FILE);
+        return(KFAILURE);
+    }
+
+    if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+        buf.st_mode & 077) {
+       if (krb_debug)
+           fprintf(stderr,"Error initializing %s",TKT_FILE);
+        return(KFAILURE);
+    }
+
+    count = strlen(pname)+1;
+    if (write(tktfile,pname,count) != count) {
+        (void) close(tktfile);
+        return(KFAILURE);
+    }
+    count = strlen(pinst)+1;
+    if (write(tktfile,pinst,count) != count) {
+        (void) close(tktfile);
+        return(KFAILURE);
+    }
+    (void) close(tktfile);
+#ifdef TKT_SHMEM
+    (void) strcpy(shmidname, file);
+    (void) strcat(shmidname, ".shm");
+    return(krb_shm_create(shmidname));
+#else /* !TKT_SHMEM */
+    return(KSUCCESS);
+#endif /* TKT_SHMEM */
+}
diff --git a/kerberosIV/krb/k_localtime.c b/kerberosIV/krb/k_localtime.c
new file mode 100644 (file)
index 0000000..88aa16f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/k_localtime.c,v $
+ *
+ * $Locker:  $
+ */
+
+/*
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <kerberosIV/krb.h>
+
+#include <time.h>
+
+struct tm *
+k_localtime(tp)
+       u_int32_t *tp;
+{
+  time_t t;
+  t = *tp;
+  return localtime(&t);
+}
diff --git a/kerberosIV/krb/kerberos.3 b/kerberosIV/krb/kerberos.3
new file mode 100644 (file)
index 0000000..5a6649a
--- /dev/null
@@ -0,0 +1,462 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/kerberos.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/kerberos.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred,
+krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err,
+krb_rd_err, krb_ck_repl \- Kerberos authentication library
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+int krb_mk_req(authent,service,instance,realm,checksum)
+KTEXT authent;
+char *service;
+char *instance;
+char *realm;
+u_long checksum;
+.PP
+.ft B
+int krb_rd_req(authent,service,instance,from_addr,ad,fn)
+KTEXT authent;
+char *service;
+char *instance;
+u_long from_addr;
+AUTH_DAT *ad;
+char *fn;
+.PP
+.ft B
+int krb_kntoln(ad,lname)
+AUTH_DAT *ad;
+char *lname;
+.PP
+.ft B
+int krb_set_key(key,cvt)
+char *key;
+int cvt;
+.PP
+.ft B
+int krb_get_cred(service,instance,realm,c)
+char *service;
+char *instance;
+char *realm;
+CREDENTIALS *c;
+.PP
+.ft B
+long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+des_key_schedule schedule;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data)
+u_char *in;
+u_long in_length;
+Key_schedule schedule;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_safe(in,out,in_length,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_safe(in,length,key,sender,receiver,msg_data)
+u_char *in;
+u_long length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_err(out,code,string)
+u_char *out;
+long code;
+char *string;
+.PP
+.ft B
+long krb_rd_err(in,length,code,msg_data)
+u_char *in;
+u_long length;
+long code;
+MSG_DAT *msg_data;
+.fi
+.ft R
+.SH DESCRIPTION
+This library supports network authentication and various related
+operations.  The library contains many routines beyond those described
+in this man page, but they are not intended to be used directly.
+Instead, they are called by the routines that are described, the
+authentication server and the login program.
+.PP
+.I krb_err_txt[]
+contains text string descriptions of various Kerberos error codes returned
+by some of the routines below.
+.PP
+.I krb_mk_req
+takes a pointer to a text structure in which an authenticator is to be
+built.  It also takes the name, instance, and realm of the service to be
+used and an optional checksum.  It is up to the application to decide
+how to generate the checksum.
+.I krb_mk_req
+then retrieves a ticket for the desired service and creates an
+authenticator.  The authenticator is built in
+.I authent
+and is accessible
+to the calling procedure.
+.PP
+It is up to the application to get the authenticator to the service
+where it will be read by
+.I krb_rd_req.
+Unless an attacker posesses the session key contained in the ticket, it
+will be unable to modify the authenticator.  Thus, the checksum can be
+used to verify the authenticity of the other data that will pass through
+a connection.
+.PP
+.I krb_rd_req
+takes an authenticator of type
+.B KTEXT,
+a service name, an instance, the address of the
+host originating the request, and a pointer to a structure of type
+.B AUTH_DAT
+which is filled in with information obtained from the authenticator.
+It also optionally takes the name of the file in which it will find the
+secret key(s) for the service.
+If the supplied
+.I instance
+contains "*", then the first service key with the same service name
+found in the service key file will be used, and the
+.I instance
+argument will be filled in with the chosen instance.  This means that
+the caller must provide space for such an instance name.
+.PP
+It is used to find out information about the principal when a request
+has been made to a service.  It is up to the application protocol to get
+the authenticator from the client to the service.  The authenticator is
+then passed to
+.I krb_rd_req
+to extract the desired information.
+.PP
+.I krb_rd_req
+returns zero (RD_AP_OK) upon successful authentication.  If a packet was
+forged, modified, or replayed, authentication will fail.  If the
+authentication fails, a non-zero value is returned indicating the
+particular problem encountered.  See
+.I krb.h
+for the list of error codes.
+.PP
+If the last argument is the null string (""), krb_rd_req will use the
+file /etc/srvtab to find its keys.  If the last argument is NULL, it
+will assume that the key has been set by
+.I krb_set_key
+and will not bother looking further.
+.PP
+.I krb_kntoln
+converts a Kerberos name to a local name.  It takes a structure
+of type AUTH_DAT and uses the name and instance to look in the database
+/etc/aname to find the corresponding local name.  The local name is
+returned and can be used by an application to change uids, directories,
+or other parameters.  It is not an integral part of Kerberos, but is
+instead provided to support the use of Kerberos in existing utilities.
+.PP
+.I krb_set_key
+takes as an argument a des key.  It then creates
+a key schedule from it and saves the original key to be used as an
+initialization vector.
+It is used to set the server's key which
+must be used to decrypt tickets.
+.PP
+If called with a non-zero second argument,
+.I krb_set_key
+will first convert the input from a string of arbitrary length to a DES
+key by encrypting it with a one-way function.
+.PP
+In most cases it should not be necessary to call
+.I krb_set_key.
+The necessary keys will usually be obtained and set inside
+.I krb_rd_req.  krb_set_key
+is provided for those applications that do not wish to place the
+application keys on disk.
+.PP
+.I krb_get_cred
+searches the caller's ticket file for a ticket for the given service, instance,
+and realm; and, if a ticket is found, fills in the given CREDENTIALS structure
+with the ticket information.
+.PP
+If the ticket was found,
+.I krb_get_cred
+returns GC_OK.
+If the ticket file can't be found, can't be read, doesn't belong to
+the user (other than root), isn't a regular file, or is in the wrong
+mode, the error GC_TKFIL is returned.
+.PP
+.I krb_mk_priv
+creates an encrypted, authenticated
+message from any arbitrary application data, pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key
+and the key schedule,
+.I schedule,
+are used to encrypt the data and some header information using
+.I pcbc_encrypt.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+In addition to providing privacy, this protocol message protects
+against modifications, insertions or replays.  The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+.PP
+.I krb_rd_priv
+decrypts and authenticates a received
+.I krb_mk_priv
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+and the key schedule,
+.I schedule,
+are used to decrypt and verify the received message.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h.
+The routine fills in the
+.I app_data
+field with a pointer to the decrypted application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender.  (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of).  The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_safe
+creates an authenticated, but unencrypted message from any arbitrary
+application data,
+pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key,
+is used to seed the
+.I quad_cksum()
+checksum algorithm used as part of the authentication.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+This message does not provide privacy, but does protect (via detection)
+against modifications, insertions or replays.  The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+The authentication provided by this routine is not as strong as that
+provided by
+.I krb_mk_priv
+or by computing the checksum using
+.I cbc_cksum
+instead, both of which authenticate via DES.
+.PP
+
+.I krb_rd_safe
+authenticates a received
+.I krb_mk_safe
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+is used to seed the quad_cksum() routine as part of the authentication.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields:
+the
+.I app_data
+field with a pointer to the application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender.
+(The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of).  The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_err
+constructs an application level error message that may be used along
+with
+.I krb_mk_priv
+or
+.I krb_mk_safe.
+.I out
+is a pointer to the output buffer,
+.I code
+is an application specific error code, and
+.I string
+is an application specific error string.
+
+.PP
+.I krb_rd_err
+unpacks a received
+.I krb_mk_err
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+.I code
+is a pointer to a value to be filled in with the error
+value provided by the application.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields: the
+.I app_data
+field with a pointer to the application error text,
+.I app_length
+with the length of the
+.I app_data
+field, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender.  (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of).
+
+The routine returns zero if the error message has been successfully received,
+or a Kerberos error code.
+.PP
+The
+.I KTEXT
+structure is used to pass around text of varying lengths.  It consists
+of a buffer for the data, and a length.  krb_rd_req takes an argument of this
+type containing the authenticator, and krb_mk_req returns the
+authenticator in a structure of this type.  KTEXT itself is really a
+pointer to the structure.   The actual structure is of type KTEXT_ST.
+.PP
+The
+.I AUTH_DAT
+structure is filled in by krb_rd_req.  It must be allocated before
+calling krb_rd_req, and a pointer to it is passed.  The structure is
+filled in with data obtained from Kerberos.
+.I MSG_DAT
+structure is filled in by either krb_rd_priv, krb_rd_safe, or
+krb_rd_err.  It must be allocated before the call and a pointer to it
+is passed.  The structure is
+filled in with data obtained from Kerberos.
+.PP
+.SH FILES
+/usr/include/krb.h
+.br
+/usr/lib/libkrb.a
+.br
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.br
+/etc/aname
+.br
+/etc/srvtab
+.br
+/tmp/tkt[uid]
+.SH "SEE ALSO"
+kerberos(1), des_crypt(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The caller of
+.I krb_rd_req, krb_rd_priv, and krb_rd_safe
+must check time order and for replay attempts.
+.I krb_ck_repl
+is not implemented yet.
+.SH AUTHORS
+Clifford Neuman, MIT Project Athena
+.br
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.SH RESTRICTIONS
+COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology
diff --git a/kerberosIV/krb/klog.c b/kerberosIV/krb/klog.c
new file mode 100644 (file)
index 0000000..5e7ea6c
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/klog.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static int is_open;
+static char logtxt[1000];
+
+/*
+ * This file contains two logging routines: kset_logfile()
+ * to determine the file to which log entries should be written;
+ * and klog() to write log entries to the file.
+ */
+
+/*
+ * klog() is used to add entries to the logfile (see kset_logfile()
+ * below).  Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format" string.
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * If the given log type "type" is unknown, or if the log file
+ * cannot be opened, no entry is made to the log file.
+ *
+ * The return value is always a pointer to the formatted log
+ * text string "logtxt".
+ */
+
+char *
+klog(type, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0)
+     int type;
+     char *format;
+     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a0;
+{
+    FILE *logfile;
+    time_t now;
+    char *month_sname(int n);
+    struct tm *tm;
+    static int logtype_array[NLOGTYPE] = {0,0};
+    static int array_initialized;
+
+    if (!(array_initialized++)) {
+        logtype_array[L_NET_ERR] = 1;
+        logtype_array[L_KRB_PERR] = 1;
+        logtype_array[L_KRB_PWARN] = 1;
+        logtype_array[L_APPL_REQ] = 1;
+        logtype_array[L_INI_REQ] = 1;
+        logtype_array[L_DEATH_REQ] = 1;
+        logtype_array[L_NTGT_INTK] = 1;
+        logtype_array[L_ERR_SEXP] = 1;
+        logtype_array[L_ERR_MKV] = 1;
+        logtype_array[L_ERR_NKY] = 1;
+        logtype_array[L_ERR_NUN] = 1;
+        logtype_array[L_ERR_UNK] = 1;
+    }
+
+    (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+
+    if (!logtype_array[type])
+       return(logtxt);
+
+    if ((logfile = fopen(log_name,"a")) == NULL)
+        return(logtxt);
+
+    (void) time(&now);
+    tm = localtime(&now);
+
+    fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+            month_sname(tm->tm_mon + 1),tm->tm_year,
+            tm->tm_hour, tm->tm_min, tm->tm_sec);
+    fprintf(logfile,"%s\n",logtxt);
+    (void) fclose(logfile);
+    return(logtxt);
+}
+
+/*
+ * kset_logfile() changes the name of the file to which
+ * messages are logged.  If kset_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+void
+kset_logfile(filename)
+       char *filename;
+{
+    log_name = filename;
+    is_open = 0;
+}
diff --git a/kerberosIV/krb/kname_parse.c b/kerberosIV/krb/kname_parse.c
new file mode 100644 (file)
index 0000000..33036ac
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/kname_parse.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#define INSTANCE_DOTS_OK        0
+
+/* max size of full name */
+#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
+
+#define NAME    0              /* which field are we in? */
+#define INST    1
+#define REALM   2
+
+/*
+ * This file contains four routines for handling Kerberos names.
+ *
+ * kname_parse() breaks a Kerberos name into its name, instance,
+ * and realm components.
+ *
+ * k_isname(), k_isinst(), and k_isrealm() check a given string to see if
+ * it's a syntactically legitimate respective part of a Kerberos name,
+ * returning 1 if it is, 0 if it isn't.
+ *
+ * Definition of "syntactically legitimate" names is according to
+ * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
+ * names", version dated 21 Dec 1987.
+ */
+
+/*
+ * kname_parse() takes a Kerberos name "fullname" of the form:
+ *
+ *             username[.instance][@realm]
+ *
+ * and returns the three components ("name", "instance", and "realm"
+ * in the example above) in the given arguments "np", "ip", and "rp".
+ *
+ * If successful, it returns KSUCCESS.  If there was an error,
+ * KNAME_FMT is returned.
+ */
+
+int
+kname_parse(np, ip, rp, fullname)
+       char *np;
+       char *ip;
+       char *rp;
+       char *fullname;
+{
+    static char buf[FULL_SZ];
+    char *rnext, *wnext;       /* next char to read, write */
+    register char c;
+    int backslash;
+    int field;
+
+    backslash = 0;
+    rnext = buf;
+    wnext = np;
+    field = NAME;
+
+    if (strlen(fullname) > FULL_SZ)
+        return KNAME_FMT;
+    (void) strcpy(buf, fullname);
+
+    while ((c = *rnext++)) {
+        if (backslash) {
+            *wnext++ = c;
+            backslash = 0;
+            continue;
+        }
+        switch (c) {
+        case '\\':
+            backslash++;
+            break;
+        case '.':
+            switch (field) {
+            case NAME:
+                if (wnext == np)
+                    return KNAME_FMT;
+                *wnext = '\0';
+                field = INST;
+                wnext = ip;
+                break;
+            case INST:
+#if     INSTANCE_DOTS_OK
+                *wnext++ = c;
+                break;
+#else /* INSTANCE_DOTS_OK */
+                return KNAME_FMT; 
+#endif /* INSTANCE_DOTS_OK */
+                /* break; */
+            case REALM:
+                *wnext++ = c;
+                break;
+            default:
+                fprintf(stderr, "unknown field value\n");
+                exit(1);
+            }
+            break;
+        case '@':
+            switch (field) {
+            case NAME:
+                if (wnext == np)
+                    return KNAME_FMT;
+                *ip = '\0';
+                /* fall through */
+            case INST:
+                *wnext = '\0';
+                field = REALM;
+                wnext = rp;
+                break;
+            case REALM:
+                return KNAME_FMT;
+            default:
+                fprintf(stderr, "unknown field value\n");
+                exit(1);
+            }
+            break;
+        default:
+            *wnext++ = c;
+        }
+    }
+    *wnext = '\0';
+    if ((strlen(np) > ANAME_SZ - 1) ||
+        (strlen(ip) > INST_SZ  - 1) ||
+        (strlen(rp) > REALM_SZ - 1))
+        return KNAME_FMT;
+    return KSUCCESS;
+}
+
+/*
+ * k_isname() returns 1 if the given name is a syntactically legitimate
+ * Kerberos name; returns 0 if it's not.
+ */
+
+int
+k_isname(s)
+       char *s;
+{
+    register char c;
+    int backslash = 0;
+
+    if (!*s)
+        return 0;
+    if (strlen(s) > ANAME_SZ - 1)
+        return 0;
+    while ((c = *s++)) {
+        if (backslash) {
+            backslash = 0;
+            continue;
+        }
+        switch(c) {
+        case '\\':
+            backslash = 1;
+            break;
+        case '.':
+            return 0;
+            /* break; */
+        case '@':
+            return 0;
+            /* break; */
+        }
+    }
+    return 1;
+}
+
+
+/*
+ * k_isinst() returns 1 if the given name is a syntactically legitimate
+ * Kerberos instance; returns 0 if it's not.
+ */
+
+int
+k_isinst(s)
+       char *s;
+{
+    register char c;
+    int backslash = 0;
+
+    if (strlen(s) > INST_SZ - 1)
+        return 0;
+    while ((c = *s++)) {
+        if (backslash) {
+            backslash = 0;
+            continue;
+        }
+        switch(c) {
+        case '\\':
+            backslash = 1;
+            break;
+        case '.':
+#if     INSTANCE_DOTS_OK
+            break;
+#else /* INSTANCE_DOTS_OK */
+            return 0; 
+#endif /* INSTANCE_DOTS_OK */
+            /* break; */
+        case '@':
+            return 0;
+            /* break; */
+        }
+    }
+    return 1;
+}
+
+/*
+ * k_isrealm() returns 1 if the given name is a syntactically legitimate
+ * Kerberos realm; returns 0 if it's not.
+ */
+
+int
+k_isrealm(s)
+       char *s;
+{
+    register char c;
+    int backslash = 0;
+
+    if (!*s)
+        return 0;
+    if (strlen(s) > REALM_SZ - 1)
+        return 0;
+    while ((c = *s++)) {
+        if (backslash) {
+            backslash = 0;
+            continue;
+        }
+        switch(c) {
+        case '\\':
+            backslash = 1;
+            break;
+        case '@':
+            return 0;
+            /* break; */
+        }
+    }
+    return 1;
+}
diff --git a/kerberosIV/krb/kntoln.c b/kerberosIV/krb/kntoln.c
new file mode 100644 (file)
index 0000000..52aca33
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/kntoln.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * krb_kntoln converts an auth name into a local name by looking up
+ * the auth name in the /etc/aname file.  The format of the aname
+ * file is:
+ *
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | anl | inl | rll | lnl | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | 1by | 1by | 1by | 1by | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ *
+ * If the /etc/aname file can not be opened it will set the
+ * local name to the auth name.  Thus, in this case it performs as
+ * the identity function.
+ *
+ * The name instance and realm are passed to krb_kntoln through
+ * the AUTH_DAT structure (ad).
+ *
+ * Now here's what it *really* does:
+ *
+ * Given a Kerberos name in an AUTH_DAT structure, check that the
+ * instance is null, and that the realm is the same as the local
+ * realm, and return the principal's name in "lname".  Return
+ * KSUCCESS if all goes well, otherwise KFAILURE.
+ */
+
+#include "krb_locl.h"
+
+int
+krb_kntoln(ad, lname)
+       AUTH_DAT *ad;
+       char *lname;
+{
+    static char lrealm[REALM_SZ] = "";
+
+    if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
+        return(KFAILURE);
+
+    if (strcmp(ad->pinst,""))
+        return(KFAILURE);
+    if (strcmp(ad->prealm,lrealm))
+        return(KFAILURE);
+    (void) strcpy(lname,ad->pname);
+    return(KSUCCESS);
+}
diff --git a/kerberosIV/krb/kparse.c b/kerberosIV/krb/kparse.c
new file mode 100644 (file)
index 0000000..1e23482
--- /dev/null
@@ -0,0 +1,789 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/kparse.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * Purpose:
+ * This module was developed to parse the "~/.klogin" files for
+ * Kerberos-authenticated rlogin/rcp/rsh services.  However, it is
+ * general purpose and can be used to parse any such parameter file.
+ *
+ * The parameter file should consist of one or more entries, with each
+ * entry on a separate line and consisting of zero or more
+ * "keyword=value" combinations.  The keyword is case insensitive, but
+ * the value is not.  Any string may be enclosed in quotes, and
+ * c-style "\" literals are supported.  A comma may be used to
+ * separate the k/v combinations, and multiple commas are ignored.
+ * Whitespace (blank or tab) may be used freely and is ignored.
+ *
+ * Full error processing is available.  When PS_BAD_KEYWORD or
+ * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
+ * contains a meaningful error message.
+ *
+ * Keywords and their default values are programmed by an external
+ * table.
+ *
+ * Routines:
+ * fGetParameterSet()      parse one line of the parameter file
+ * fGetKeywordValue()      parse one "keyword=value" combo
+ * fGetToken()             parse one token
+ *
+ * " <- emacs fix
+ */
+
+#include "krb_locl.h"
+
+#include <kerberosIV/kparse.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define MAXKEY          80
+#define MAXVALUE        80
+
+int LineNbr=1;         /* current line nbr in parameter file */
+char ErrorMsg[80];     /* meaningful only when KV_SYNTAX, PS_SYNTAX,
+                         * or PS_BAD_KEYWORD is returned by
+                         * fGetKeywordValue or fGetParameterSet */
+
+int
+fGetParameterSet(fp, parm, parmcount)
+       FILE *fp;
+       parmtable *parm;
+       int parmcount;
+{
+    int rc,i;
+    char keyword[MAXKEY];
+    char value[MAXVALUE];
+
+    while (TRUE) {
+        rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
+
+        switch (rc) {
+
+        case KV_EOF:
+            return(PS_EOF);
+
+        case KV_EOL:
+            return(PS_OKAY);
+
+        case KV_SYNTAX:
+            return(PS_SYNTAX);
+
+        case KV_OKAY:
+            /*
+             * got a reasonable keyword/value pair.  Search the
+             * parameter table to see if we recognize the keyword; if
+             * not, return an error.  If we DO recognize it, make sure
+             * it has not already been given.  If not already given,
+             * save the value.
+             */
+            for (i=0; i<parmcount; i++) {
+                if (strcmp(strutol(keyword),parm[i].keyword)==0) {
+                    if (parm[i].value) {
+                        sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
+                                keyword);
+                        return(PS_BAD_KEYWORD);
+                    }
+                    parm[i].value = strsave( value );
+                    break;
+                }
+            }
+            if (i >= parmcount) {
+                sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
+                       keyword);
+                return(PS_BAD_KEYWORD);
+            }
+            break;
+
+        default:
+            sprintf(ErrorMsg,
+                   "panic: bad return (%d) from fGetToken()",rc);
+            break;
+        }
+    }
+}
+
+/*
+ * Routine: ParmCompare
+ *
+ * Purpose:
+ * ParmCompare checks a specified value for a particular keyword.
+ * fails if keyword not found or keyword found but the value was
+ * different. Like strcmp, ParmCompare returns 0 for a match found, -1
+ * otherwise
+ */
+int
+ParmCompare(parm, parmcount, keyword, value)
+       parmtable *parm;
+       int parmcount;
+       char *keyword;
+       char *value;
+{
+    int i;
+
+    for (i=0; i<parmcount; i++) {
+        if (strcmp(parm[i].keyword,keyword)==0) {
+            if (parm[i].value) {
+                return(strcmp(parm[i].value,value));
+            } else {
+                return(strcmp(parm[i].defvalue,value));
+            }
+        }
+    }
+    return(-1);
+}
+
+void
+FreeParameterSet(parm, parmcount)
+       parmtable *parm;
+       int parmcount;
+{
+    int i;
+
+    for (i=0; i<parmcount; i++) {
+        if (parm[i].value) {
+            free(parm[i].value);
+            parm[i].value = (char *)NULL;
+        }
+    }
+}
+
+int
+fGetKeywordValue(fp, keyword, klen, value, vlen)
+       FILE *fp;
+       char *keyword;
+       int klen;
+       char *value;
+       int vlen;
+{
+    int rc;
+    int gotit;
+
+    *keyword = *value = '\0';   /* preset strings to NULL */
+
+    /*
+     * Looking for a keyword.
+     *          return an exception for EOF or BAD_QSTRING
+     *          ignore leading WHITEspace
+     *          ignore any number of leading commas
+     *          newline means we have all the parms for this
+     *                 statement; give an indication that there is
+     *                 nothing more on this line.
+     *          stop looking if we find QSTRING, STRING, or NUMBER
+     *          return syntax error for any other PUNKtuation
+     */
+    gotit = FALSE;
+    do {
+        rc = fGetToken(fp,keyword,klen);
+
+        switch (rc) {
+
+        case GTOK_WHITE:
+            break;
+
+        case GTOK_EOF:
+            return(KV_EOF);
+
+        case GTOK_BAD_QSTRING:
+            sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
+            return(KV_SYNTAX);
+
+        case GTOK_PUNK:
+            if (strcmp("\n",keyword)==0) {
+                return(KV_EOL);
+            } else if (strcmp(",",keyword)!=0) {
+                sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
+            }
+            break;
+
+        case GTOK_STRING:
+        case GTOK_QSTRING:
+        case GTOK_NUMBER:
+            gotit = TRUE;
+            break;
+
+        default:
+            sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
+            return(KV_SYNTAX);
+        }
+
+    } while (!gotit);
+
+    /*
+     * now we expect an equal sign.
+     *          skip any whitespace
+     *          stop looking if we find an equal sign
+     *          anything else causes a syntax error
+     */
+    gotit = FALSE;
+    do {
+        rc = fGetToken(fp,value,vlen);
+
+        switch (rc) {
+
+        case GTOK_WHITE:
+            break;
+
+        case GTOK_BAD_QSTRING:
+            sprintf(ErrorMsg,
+                   "expecting \'=\', found unterminated string \"%s",
+                    value);
+            return(KV_SYNTAX);
+
+        case GTOK_PUNK:
+            if (strcmp("=",value)==0) {
+                gotit = TRUE;
+            } else {
+                if (strcmp("\n",value)==0) {
+                    sprintf(ErrorMsg,"expecting \"=\", found newline");
+                    fUngetChar('\n',fp);
+                } else {
+                    sprintf(ErrorMsg,
+                           "expecting rvalue, found \'%s\'",keyword);
+                }
+                return(KV_SYNTAX);
+            }
+            break;
+
+        case GTOK_STRING:
+        case GTOK_QSTRING:
+        case GTOK_NUMBER:
+            sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
+            return(KV_SYNTAX);
+
+        case GTOK_EOF:
+            sprintf(ErrorMsg,"expecting \'=\', found EOF");
+            return(KV_SYNTAX);
+
+        default:
+            sprintf(ErrorMsg,
+                   "panic: bad return (%d) from fGetToken()",rc);
+            return(KV_SYNTAX);
+        }
+
+    } while ( !gotit );
+
+    /*
+     * got the keyword and equal sign, now get a value.
+     *          ignore any whitespace
+     *          any punctuation is a syntax error
+     */
+    gotit = FALSE;
+    do {
+        rc = fGetToken(fp,value,vlen);
+
+        switch (rc) {
+
+        case GTOK_WHITE:
+            break;
+
+        case GTOK_EOF:
+            sprintf(ErrorMsg,"expecting rvalue, found EOF");
+            return(KV_SYNTAX);
+
+        case GTOK_BAD_QSTRING:
+            sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
+            return(KV_SYNTAX);
+
+        case GTOK_PUNK:
+            if (strcmp("\n",value)==0) {
+                sprintf(ErrorMsg,"expecting rvalue, found newline");
+                fUngetChar('\n',fp);
+            } else {
+                sprintf(ErrorMsg,
+                       "expecting rvalue, found \'%s\'",value);
+            }
+            return(KV_SYNTAX);
+            break;
+
+        case GTOK_STRING:
+        case GTOK_QSTRING:
+        case GTOK_NUMBER:
+            gotit = TRUE;
+            return(KV_OKAY);
+
+        default:
+            sprintf(ErrorMsg,
+                   "panic: bad return (%d) from fGetToken()",rc);
+            return(KV_SYNTAX);
+        }
+
+    } while ( !gotit );
+    /*NOTREACHED*/
+    return(KV_SYNTAX);
+}
+
+/*
+ * Routine Name: fGetToken
+ *
+ * Function: read the next token from the specified file.
+ * A token is defined as a group of characters
+ * terminated by a white space char (SPACE, CR,
+ * LF, FF, TAB). The token returned is stripped of
+ * both leading and trailing white space, and is
+ * terminated by a NULL terminator.  An alternate
+ * definition of a token is a string enclosed in
+ * single or double quotes.
+ *
+ * Explicit Parameters:
+ * fp              pointer to the input FILE
+ * dest    pointer to destination buffer
+ * maxlen  length of the destination buffer. The buffer
+ * length INCLUDES the NULL terminator.
+ *
+ * Implicit Parameters: stderr  where the "token too long" message goes
+ *
+ * External Procedures: fgetc
+ *
+ * Side Effects:                None
+ *
+ * Return Value:                A token classification value, as
+ *                             defined in kparse.h. Note that the
+ *                             classification for end of file is
+ *                             always zero.
+ */
+int
+fGetToken(fp, dest, maxlen)
+       FILE *fp;
+       char *dest;
+       int maxlen;
+{
+    int ch='\0';
+    int len=0;
+    char *p = dest;
+    int digits;
+
+    ch=fGetChar(fp);
+
+    /*
+     * check for a quoted string.  If found, take all characters
+     * that fit until a closing quote is found.  Note that this
+     * algorithm will not behave well for a string which is too long.
+     */
+    if (ISQUOTE(ch)) {
+        int done = FALSE;
+        do {
+            ch = fGetChar(fp);
+            done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
+                   ||ISQUOTE(ch));
+            if (ch=='\\')
+                ch = fGetLiteral(fp);
+            if (!done)
+                *p++ = ch;
+            else if ((ch!=EOF) && !ISQUOTE(ch))
+                fUngetChar(ch,fp);
+        } while (!done);
+        *p = '\0';
+        if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
+        return(GTOK_QSTRING);
+    }
+
+    /*
+     * Not a quoted string.  If its a token character (rules are
+     * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
+     * token chars following it until we run out of space.
+     */
+    digits=TRUE;
+    if (ISTOKENCHAR(ch)) {
+        while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
+            if (!isdigit(ch)) digits=FALSE;
+            *p++ = ch;
+            len++;
+            ch = fGetChar(fp);
+        };
+        *p = '\0';
+
+        if (ch!=EOF) {
+            fUngetChar(ch,fp);
+        }
+        if (digits) {
+            return(GTOK_NUMBER);
+        } else {
+            return(GTOK_STRING);
+        }
+    }
+
+    /*
+     * Neither a quoted string nor a token character.  Return a string
+     * with just that one character in it.
+     */
+    if (ch==EOF) {
+        return(GTOK_EOF);
+    }
+    if (!ISWHITESPACE(ch)) {
+        *p++ = ch;
+        *p='\0';
+    } else {
+        *p++ = ' ';            /* white space is always the
+                                * blank character */
+        *p='\0';
+        /*
+         * The character is a white space. Flush all additional white
+         * space.
+         */
+        while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
+            ;
+        if (ch!=EOF) {
+            fUngetChar(ch,fp);
+        }
+        return(GTOK_WHITE);
+    }
+    return(GTOK_PUNK);
+}
+
+/*
+ * fGetLiteral is called after we find a '\' in the input stream.  A
+ * string of numbers following the backslash are converted to the
+ * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
+ * are all supported.  If the char after the \ is not a number, we
+ * special case certain values (\n, \f, \r, \b) or return a literal
+ * otherwise (useful for \", for example).
+ *
+ * " <- emacs fix
+ */
+
+int
+fGetLiteral(fp)
+       FILE *fp;
+{
+    int ch;
+    int n=0;
+    int base;
+
+    ch = fGetChar(fp);
+
+    if (!isdigit(ch)) {
+        switch (ch) {
+        case 'n':       return('\n');
+        case 'f':       return('\f');
+        case 'r':       return('\r');
+        case 'b':       return('\b');
+        default:        return(ch);
+        }
+    }
+
+    /*
+     * got a number.  might be decimal (no prefix), octal (prefix 0),
+     * or hexadecimal (prefix 0x).  Set the base appropriately.
+     */
+    if (ch!='0') {
+        base=10;                /* its a decimal number */
+    } else {
+        /*
+         * found a zero, its either hex or octal
+         */
+        ch = fGetChar(fp);
+        if ((ch!='x') && (ch!='X')) {
+            base=010;
+        } else {
+            ch = fGetChar(fp);
+            base=0x10;
+        }
+    }
+
+    switch (base) {
+
+    case 010:                   /* octal */
+        while (ISOCTAL(ch)) {
+            n = (n*base) + ch - '0';
+            ch = fGetChar(fp);
+        }
+        break;
+
+    case 10:                    /* decimal */
+        while (isdigit(ch)) {
+            n = (n*base) + ch - '0';
+            ch = fGetChar(fp);
+        }
+        break;
+    case 0x10:                  /* hexadecimal */
+        while (isxdigit(ch)) {
+            if (isdigit(ch)) {
+                n = (n*base) + ch - '0';
+            } else {
+                n = (n*base) + toupper(ch) - 'A' + 0xA ;
+            }
+            ch = fGetChar(fp);
+        }
+        break;
+    default:
+        fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
+        exit(1);
+        break;
+    }
+    fUngetChar(ch,fp);
+    return(n);
+}
+
+/*
+ * exactly the same as ungetc(3) except that the line number of the
+ * input file is maintained.
+ */
+int
+fUngetChar(ch, fp)
+       int ch;
+       FILE *fp;
+{
+    if (ch=='\n') LineNbr--;
+    return(ungetc(ch,fp));
+}
+
+/*
+ * exactly the same as fgetc(3) except that the line number of the
+ * input file is maintained.
+ */
+int
+fGetChar(fp)
+       FILE *fp;
+{
+    int ch = fgetc(fp);
+    if (ch=='\n') LineNbr++;
+    return(ch);
+}
+
+
+/*
+ * Routine Name: strsave
+ *
+ * Function: return a pointer to a saved copy of the
+ * input string. the copy will be allocated
+ * as large as necessary.
+ *
+ * Explicit Parameters: pointer to string to save
+ *
+ * Implicit Parameters: None
+ *
+ * External Procedures: malloc,strcpy,strlen
+ *
+ * Side Effects: None
+ *
+ * Return Value: pointer to copied string
+ *
+ */
+char *
+strsave(p)
+       char *p;
+{
+    return(strcpy(malloc(strlen(p)+1),p));
+}
+
+
+/*
+ * strutol changes all characters in a string to lower case, in place.
+ * the pointer to the beginning of the string is returned.
+ */
+
+char *
+strutol(start)
+       char *start;
+{
+    char *q;
+    for (q=start; *q; q++)
+        if (isupper(*q))
+           *q=tolower(*q);
+    return(start);
+}
+
+#ifdef GTOK_TEST            /* mainline test routine for fGetToken() */
+
+#define MAXTOKEN 100
+
+char *pgm = "gettoken";
+
+main(argc,argv)
+    int argc;
+    char **argv;
+{
+    char *p;
+    int type;
+    FILE *fp;
+
+    if (--argc) {
+        fp = fopen(*++argv,"ra");
+        if (fp == (FILE *)NULL) {
+            fprintf(stderr,"can\'t open \"%s\"\n",*argv);
+        }
+    } else
+        fp = stdin;
+
+    p = malloc(MAXTOKEN);
+    while (type = fGetToken(fp,p,MAXTOKEN)) {
+        switch(type) {
+        case GTOK_BAD_QSTRING:
+           printf("BAD QSTRING!\t");
+           break;
+        case GTOK_EOF:
+           printf("EOF!\t");
+           break;
+        case GTOK_QSTRING:
+           printf("QSTRING\t");
+           break;
+        case GTOK_STRING:
+           printf("STRING\t");
+           break;
+        case GTOK_NUMBER:
+           printf("NUMBER\t");
+           break;
+        case GTOK_PUNK:
+           printf("PUNK\t");
+           break;
+        case GTOK_WHITE:
+           printf("WHITE\t");
+           break;
+        default:
+           printf("HUH?\t");
+           break;
+        }
+        if (*p=='\n')
+            printf("\\n\n");
+       else
+            printf("%s\n",p);
+    }
+    exit(0);
+}
+#endif
+
+#ifdef KVTEST
+
+main(argc,argv)
+    int argc;
+    char **argv;
+{
+    int rc,ch;
+    FILE *fp;
+    char key[MAXKEY],valu[MAXVALUE];
+    char *filename;
+
+    if (argc != 2) {
+        fprintf(stderr,"usage: test <filename>\n");
+        exit(1);
+    }
+
+    if (!(fp=fopen(*++argv,"r"))) {
+        fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+        exit(1);
+    }
+    filename = *argv;
+
+    while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
+
+        switch (rc) {
+
+        case KV_EOL:
+            printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
+            break;
+
+        case KV_SYNTAX:
+            printf("%s, line %d: syntax error: %s\n",
+                   filename,LineNbr,ErrorMsg);
+            while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+            break;
+
+        case KV_OKAY:
+            printf("%s, line %d: okay, %s=\"%s\"\n",
+                   filename,LineNbr,key,valu);
+            break;
+
+        default:
+            printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
+            break;
+        }
+    }
+    printf("EOF");
+    fclose(fp);
+    exit(0);
+}
+#endif
+
+#ifdef PSTEST
+
+parmtable kparm[] = {
+    /*  keyword, default, found value */
+    { "user",       "",    (char *)NULL },
+    { "realm",   "Athena", (char *)NULL },
+    { "instance",   "",    (char *)NULL }
+};
+
+main(argc,argv)
+    int argc;
+    char **argv;
+{
+    int rc,i,ch;
+    FILE *fp;
+    char *filename;
+
+    if (argc != 2) {
+        fprintf(stderr,"usage: test <filename>\n");
+        exit(1);
+    }
+
+    if (!(fp=fopen(*++argv,"r"))) {
+        fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+        exit(1);
+    }
+    filename = *argv;
+
+    while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
+
+        switch (rc) {
+
+        case PS_BAD_KEYWORD:
+            printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
+            while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+            break;
+
+        case PS_SYNTAX:
+            printf("%s, line %d: syntax error: %s\n",
+                   filename,LineNbr,ErrorMsg);
+            while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+            break;
+
+        case PS_OKAY:
+            printf("%s, line %d: valid parameter set found:\n",
+                   filename,LineNbr-1);
+            for (i=0; i<PARMCOUNT(kparm); i++) {
+                printf("\t%s = \"%s\"\n",kparm[i].keyword,
+                       (kparm[i].value ? kparm[i].value
+                       : kparm[i].defvalue));
+            }
+            break;
+
+        default:
+            printf("panic: bad return (%d) from fGetParameterSet\n",rc);
+            break;
+        }
+        FreeParameterSet(kparm,PARMCOUNT(kparm));
+    }
+    printf("EOF");
+    fclose(fp);
+    exit(0);
+}
+#endif
diff --git a/kerberosIV/krb/krb_equiv.c b/kerberosIV/krb/krb_equiv.c
new file mode 100644 (file)
index 0000000..0cc13a6
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * int krb_equiv(u_int32_t ipaddr_a, u_int32_t ipaddr_b);
+ *
+ * Given two IP adresses return true if they match
+ * or are considered to belong to the same host.
+ *
+ * For example if /etc/krb.equiv looks like
+ *
+ *    130.237.223.3   192.16.126.3    # alv alv1
+ *    130.237.223.4   192.16.126.4    # byse byse1
+ *    130.237.228.152 192.16.126.9    # topsy topsy1
+ *
+ * krb_equiv(alv, alv1) would return true but
+ * krb_equiv(alv, byse1) would not.
+ *
+ * A comment starts with an '#' and ends with '\n'.
+ *
+ */
+#include "krb_locl.h"
+
+int
+krb_equiv(a, b)
+       u_int32_t a;
+       u_int32_t b;
+{
+#ifdef NO_IPADDR_CHECK
+  return 1;
+#else
+
+  FILE *fil;
+  int result = 0;
+  char line[256];
+  
+  if (a == b)                  /* trivial match */
+    return 1;
+  
+  fil = fopen(KRB_EQUIV, "r");
+  if (fil == NULL)             /* open failed */
+    return 0;
+  
+  while (fgets(line, sizeof(line)-1, fil) != NULL) /* for each line */
+    {
+      int hit_a = 0, hit_b = 0;
+      char *t = line;
+      
+      /* for each item on this line */
+      while (*t != 0)          /* more addresses on this line? */
+       if (*t == '#')          /* rest is comment */
+         *t = 0;
+       else if (isspace(*t))   /* skip space */
+         t++;
+       else if (isdigit(*t))   /* an address? */
+         {
+           u_int32_t tmp = inet_addr(t);
+           if (tmp == -1)
+             ;                 /* not an address (or broadcast) */
+           else if (tmp == a)
+             hit_a = 1;
+           else if (tmp == b)
+             hit_b = 1;
+           
+           while (*t == '.' || isdigit(*t)) /* done with this address */
+             t++;
+         }
+       else
+         *t = 0;               /* garbage on this line, skip it */
+
+      /* line is now parsed, if we found 2 matches were done */
+      if (hit_a && hit_b)
+       {
+         result = 1;
+         goto done;
+       }
+    }
+
+ done:
+  fclose(fil);
+  return result;
+#endif /* !NO_IPADDR_CHECK */
+}
diff --git a/kerberosIV/krb/krb_err.et b/kerberosIV/krb/krb_err.et
new file mode 100644 (file)
index 0000000..46e58f5
--- /dev/null
@@ -0,0 +1,259 @@
+#      Copyright 1987,1988 Massachusetts Institute of Technology
+#
+#      For copying and distribution information, see the file
+#      "mit-copyright.h".
+# 
+#      $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_err.et,v $
+#      $Author: tholo $
+#      $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_err.et,v 1.1.1.1 1995/12/14 06:52:37 tholo Exp $
+#
+       error_table     krb
+
+       ec              KRBET_KSUCCESS,
+                       "Kerberos successful"
+
+       ec              KRBET_KDC_NAME_EXP,
+                       "Kerberos principal expired"
+
+       ec              KRBET_KDC_SERVICE_EXP,
+                       "Kerberos service expired"
+
+       ec              KRBET_KDC_AUTH_EXP,
+                       "Kerberos auth expired"
+
+       ec              KRBET_KDC_PKT_VER,
+                       "Incorrect kerberos master key version"
+
+       ec              KRBET_KDC_P_MKEY_VER,
+                       "Incorrect kerberos master key version"
+
+       ec              KRBET_KDC_S_MKEY_VER,
+                       "Incorrect kerberos master key version"
+
+       ec              KRBET_KDC_BYTE_ORDER,
+                       "Kerberos error: byte order unknown"
+
+       ec              KRBET_KDC_PR_UNKNOWN,
+                       "Kerberos principal unknown"
+
+       ec              KRBET_KDC_PR_N_UNIQUE,
+                       "Kerberos principal not unique"
+
+       ec              KRBET_KDC_NULL_KEY,
+                       "Kerberos principal has null key"
+
+       ec              KRBET_KRB_RES11,
+                       "Reserved 11"
+
+       ec              KRBET_KRB_RES12,
+                       "Reserved 12"
+  
+       ec              KRBET_KRB_RES13,
+                       "Reserved 13"
+
+       ec              KRBET_KRB_RES14,
+                       "Reserved 14"
+
+       ec              KRBET_KRB_RES15,
+                       "Reserved 15"
+
+       ec              KRBET_KRB_RES16,
+                       "Reserved 16"
+
+       ec              KRBET_KRB_RES17,
+                       "Reserved 17"
+
+       ec              KRBET_KRB_RES18,
+                       "Reserved 18"
+
+       ec              KRBET_KRB_RES19,
+                       "Reserved 19"
+
+       ec              KRBET_KDC_GEN_ERR,
+                       "Generic error from Kerberos KDC"
+
+       ec              KRBET_GC_TKFIL,
+                       "Can't read Kerberos ticket file"
+
+       ec              KRBET_GC_NOTKT,
+                       "Can't find Kerberos ticket or TGT"
+
+       ec              KRBET_KRB_RES23,
+                       "Reserved 23"
+
+       ec              KRBET_KRB_RES24,
+                       "Reserved 24"
+
+       ec              KRBET_KRB_RES25,
+                       "Reserved 25"
+
+       ec              KRBET_MK_AP_TGTEXP,
+                       "Kerberos TGT Expired"
+
+       ec              KRBET_KRB_RES27,
+                       "Reserved 27"
+
+       ec              KRBET_KRB_RES28,
+                       "Reserved 28"
+
+       ec              KRBET_KRB_RES29,
+                       "Reserved 29"
+
+       ec              KRBET_KRB_RES30,
+                       "Reserved 30"
+
+       ec              KRBET_RD_AP_UNDEC,
+                       "Kerberos error: Can't decode authenticator"
+
+       ec              KRBET_RD_AP_EXP,
+                       "Kerberos ticket expired"
+
+       ec              KRBET_RD_AP_NYV,
+                       "Kerberos ticket not yet valid"
+
+       ec              KRBET_RD_AP_REPEAT,
+                       "Kerberos error: Repeated request"
+
+       ec              KRBET_RD_AP_NOT_US,
+                       "The kerberos ticket isn't for us"
+
+       ec              KRBET_RD_AP_INCON,
+                       "Kerberos request inconsistent"
+
+       ec              KRBET_RD_AP_TIME,
+                       "Kerberos error: delta_t too big"
+
+       ec              KRBET_RD_AP_BADD,
+                       "Kerberos error: incorrect net address"
+
+       ec              KRBET_RD_AP_VERSION,
+                       "Kerberos protocol version mismatch"
+
+       ec              KRBET_RD_AP_MSG_TYPE,
+                       "Kerberos error: invalid msg type"
+
+       ec              KRBET_RD_AP_MODIFIED,
+                       "Kerberos error: message stream modified"
+
+       ec              KRBET_RD_AP_ORDER,
+                       "Kerberos error: message out of order"
+
+       ec              KRBET_RD_AP_UNAUTHOR,
+                       "Kerberos error: unauthorized request"
+
+       ec              KRBET_KRB_RES44,
+                       "Reserved 44"
+
+       ec              KRBET_KRB_RES45,
+                       "Reserved 45"
+
+       ec              KRBET_KRB_RES46,
+                       "Reserved 46"
+
+       ec              KRBET_KRB_RES47,
+                       "Reserved 47"
+
+       ec              KRBET_KRB_RES48,
+                       "Reserved 48"
+
+       ec              KRBET_KRB_RES49,
+                       "Reserved 49"
+
+       ec              KRBET_KRB_RES50,
+                       "Reserved 50"
+
+       ec              KRBET_GT_PW_NULL,
+                       "Kerberos error: current PW is null"
+
+       ec              KRBET_GT_PW_BADPW,
+                       "Kerberos error: Incorrect current password"
+
+       ec              KRBET_GT_PW_PROT,
+                       "Kerberos protocol error"
+
+       ec              KRBET_GT_PW_KDCERR,
+                       "Error returned by Kerberos KDC"
+
+       ec              KRBET_GT_PW_NULLTKT,
+                       "Null Kerberos ticket returned by KDC"
+
+       ec              KRBET_SKDC_RETRY,
+                       "Kerberos error: Retry count exceeded"
+
+       ec              KRBET_SKDC_CANT,
+                       "Kerberos error: Can't send request"
+
+       ec              KRBET_KRB_RES58,
+                       "Reserved 58"
+
+       ec              KRBET_KRB_RES59,
+                       "Reserved 59"
+
+       ec              KRBET_KRB_RES60,
+                       "Reserved 60"
+
+       ec              KRBET_INTK_W_NOTALL,
+                       "Kerberos error: not all tickets returned"
+
+       ec              KRBET_INTK_BADPW,
+                       "Kerberos error: incorrect password"
+
+       ec              KRBET_INTK_PROT,
+                       "Kerberos error: Protocol Error"
+
+       ec              KRBET_KRB_RES64,
+                       "Reserved 64"
+
+       ec              KRBET_KRB_RES65,
+                       "Reserved 65"
+
+       ec              KRBET_KRB_RES66,
+                       "Reserved 66"
+
+       ec              KRBET_KRB_RES67,
+                       "Reserved 67"
+
+       ec              KRBET_KRB_RES68,
+                       "Reserved 68"
+
+       ec              KRBET_KRB_RES69,
+                       "Reserved 69"
+
+       ec              KRBET_INTK_ERR,
+                       "Other error"
+
+       ec              KRBET_AD_NOTGT,
+                       "Don't have Kerberos ticket-granting ticket"
+
+       ec              KRBET_KRB_RES72,
+                       "Reserved 72"
+
+       ec              KRBET_KRB_RES73,
+                       "Reserved 73"
+
+       ec              KRBET_KRB_RES74,
+                       "Reserved 74"
+
+       ec              KRBET_KRB_RES75,
+                       "Reserved 75"
+
+       ec              KRBET_NO_TKT_FIL,
+                       "No ticket file found"
+
+       ec              KRBET_TKT_FIL_ACC,
+                       "Couldn't access ticket file"
+
+       ec              KRBET_TKT_FIL_LCK,
+                       "Couldn't lock ticket file"
+
+       ec              KRBET_TKT_FIL_FMT,
+                       "Bad ticket file format"
+
+       ec              KRBET_TKT_FIL_INI,
+                       "tf_init not called first"
+
+       ec              KRBET_KNAME_FMT,
+                       "Bad Kerberos name format"
+
+       end
+
diff --git a/kerberosIV/krb/krb_err_txt.c b/kerberosIV/krb/krb_err_txt.c
new file mode 100644 (file)
index 0000000..0adfb86
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_err_txt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This file contains an array of error text strings.
+ * The associated error codes (which are defined in "krb.h")
+ * follow the string in the comments at the end of each line.
+ */
+
+const char *krb_err_txt[256] = {
+  "OK",                                                        /* 000 */
+  "Principal expired (kerberos)",                      /* 001 */
+  "Service expired (kerberos)",                                /* 002 */
+  "Authentication expired (kerberos)",                 /* 003 */
+  "Unknown protocol version number (kerberos)",        /* 004 */
+  "Principal: Incorrect master key version (kerberos)", /* 005 */
+  "Service: Incorrect master key version (kerberos)",   /* 006 */
+  "Bad byte order (kerberos)",                         /* 007 */
+  "Principal unknown (kerberos)",                      /* 008 */
+  "Principal not unique (kerberos)",                   /* 009 */
+  "Principal has null key (kerberos)",                 /* 010 */
+  "Reserved error message 11 (kerberos)",              /* 011 */
+  "Reserved error message 12 (kerberos)",              /* 012 */
+  "Reserved error message 13 (kerberos)",              /* 013 */
+  "Reserved error message 14 (kerberos)",              /* 014 */
+  "Reserved error message 15 (kerberos)",              /* 015 */
+  "Reserved error message 16 (kerberos)",              /* 016 */
+  "Reserved error message 17 (kerberos)",              /* 017 */
+  "Reserved error message 18 (kerberos)",              /* 018 */
+  "Reserved error message 19 (kerberos)",              /* 019 */
+  "Permission Denied (kerberos)",                      /* 020 */
+  "Can't read ticket file (krb_get_cred)",             /* 021 */
+  "Can't find ticket (krb_get_cred)",                  /* 022 */
+  "Reserved error message 23 (krb_get_cred)",          /* 023 */
+  "Reserved error message 24 (krb_get_cred)",          /* 024 */
+  "Reserved error message 25 (krb_get_cred)",          /* 025 */
+  "Ticket granting ticket expired (krb_mk_req)",       /* 026 */
+  "Reserved error message 27 (krb_mk_req)",            /* 027 */
+  "Reserved error message 28 (krb_mk_req)",            /* 028 */
+  "Reserved error message 29 (krb_mk_req)",            /* 029 */
+  "Reserved error message 30 (krb_mk_req)",            /* 030 */
+  "Can't decode authenticator (krb_rd_req)",           /* 031 */
+  "Ticket expired (krb_rd_req)",                       /* 032 */
+  "Ticket issue date too far in the future (krb_rd_req)",/* 033 */
+  "Repeat request (krb_rd_req)",                       /* 034 */
+  "Ticket for wrong server (krb_rd_req)",              /* 035 */
+  "Request inconsistent (krb_rd_req)",                 /* 036 */
+  "Time is out of bounds (krb_rd_req)",                        /* 037 */
+  "Incorrect network address (krb_rd_req)",            /* 038 */
+  "Protocol version mismatch (krb_rd_req)",            /* 039 */
+  "Illegal message type (krb_rd_req)",                 /* 040 */
+  "Message integrity error (krb_rd_req)",              /* 041 */
+  "Message duplicate or out of order (krb_rd_req)",    /* 042 */
+  "Unauthorized request (krb_rd_req)",                 /* 043 */
+  "Reserved error message 44 (krb_rd_req)",            /* 044 */
+  "Reserved error message 45 (krb_rd_req)",            /* 045 */
+  "Reserved error message 46 (krb_rd_req)",            /* 046 */
+  "Reserved error message 47 (krb_rd_req)",            /* 047 */
+  "Reserved error message 48 (krb_rd_req)",            /* 048 */
+  "Reserved error message 49 (krb_rd_req)",            /* 049 */
+  "Reserved error message 50 (krb_rd_req)",            /* 050 */
+  "Current password is NULL (get_pw_tkt)",             /* 051 */
+  "Current password incorrect (get_pw_tkt)",           /* 052 */
+  "Protocol error (gt_pw_tkt)",                                /* 053 */
+  "Error returned by KDC (gt_pw_tkt)",                 /* 054 */
+  "Null ticket returned by KDC (gt_pw_tkt)",           /* 055 */
+  "Retry count exceeded (send_to_kdc)",                        /* 056 */
+  "Can't send request (send_to_kdc)",                  /* 057 */
+  "Reserved error message 58 (send_to_kdc)",           /* 058 */
+  "Reserved error message 59 (send_to_kdc)",           /* 059 */
+  "Reserved error message 60 (send_to_kdc)",           /* 060 */
+  "Warning: Not ALL tickets returned",                 /* 061 */
+  "Password incorrect",                                        /* 062 */
+  "Protocol error (get_intkt)",                                /* 063 */
+  "Reserved error message 64 (get_in_tkt)",            /* 064 */
+  "Reserved error message 65 (get_in_tkt)",            /* 065 */
+  "Reserved error message 66 (get_in_tkt)",            /* 066 */
+  "Reserved error message 67 (get_in_tkt)",            /* 067 */
+  "Reserved error message 68 (get_in_tkt)",            /* 068 */
+  "Reserved error message 69 (get_in_tkt)",            /* 069 */
+  "Generic error (get_intkt)",                         /* 070 */
+  "Don't have ticket granting ticket (get_ad_tkt)",    /* 071 */
+  "Reserved error message 72 (get_ad_tkt)",            /* 072 */
+  "Reserved error message 73 (get_ad_tkt)",            /* 073 */
+  "Reserved error message 74 (get_ad_tkt)",            /* 074 */
+  "Reserved error message 75 (get_ad_tkt)",            /* 075 */
+  "No ticket file (tf_util)",                          /* 076 */
+  "Can't access ticket file (tf_util)",                        /* 077 */
+  "Can't lock ticket file; try later (tf_util)",       /* 078 */
+  "Bad ticket file format (tf_util)",                  /* 079 */
+  "Read ticket file before tf_init (tf_util)",         /* 080 */
+  "Bad Kerberos name format (kname_parse)",            /* 081 */
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "(reserved)",
+  "Generic kerberos error (kfailure)",                 /* 255 */
+};
diff --git a/kerberosIV/krb/krb_get_in_tkt.c b/kerberosIV/krb/krb_get_in_tkt.c
new file mode 100644 (file)
index 0000000..3a42d4d
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_get_in_tkt.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+
+int     swap_bytes;
+
+static int
+pkt_clen(pkt)
+       KTEXT pkt;
+{
+    static unsigned short temp,temp2;
+    int clen = 0;
+
+    /* Start of ticket list */
+    unsigned char *ptr = pkt_a_realm(pkt) + 10
+       + strlen((char *)pkt_a_realm(pkt));
+
+    /* Finally the length */
+    bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+    if (swap_bytes) {
+        /* assume a short is 2 bytes?? */
+        swab((char *)&temp,(char *)&temp2,2);
+        temp = temp2;
+    }
+
+    clen = (int) temp;
+
+    if (krb_debug)
+       printf("Clen is %d\n",clen);
+    return(clen);
+}
+
+/*
+ * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
+ * and the cipher text sent from the KDC, decrypt the cipher text
+ * using the key returned by key_proc.
+ */
+
+static int
+decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+  char *user;
+  char *instance;
+  char *realm;
+  char *arg;
+  int (*key_proc)();
+  KTEXT *cipp;
+{
+    KTEXT cip = *cipp;
+    des_cblock key;            /* Key for decrypting cipher */
+    des_key_schedule key_s;
+
+#ifndef NOENCRYPTION
+    /* Attempt to decrypt it */
+#endif
+    
+    /* generate a key */
+    
+    {
+       register int rc;
+       rc = (*key_proc)(user,instance,realm,arg,key);
+       if (rc)
+           return(rc);
+    }
+    
+#ifndef NOENCRYPTION
+    des_key_sched(&key,key_s);
+    des_pcbc_encrypt((des_cblock *)cip->dat,(des_cblock *)cip->dat,
+                (long) cip->length,key_s,&key,DES_DECRYPT);
+#endif /* !NOENCRYPTION */
+    /* Get rid of all traces of key */
+    bzero((char *)key,sizeof(key));
+    bzero((char *)key_s,sizeof(key_s));
+
+    return(0);
+}
+
+/*
+ * krb_get_in_tkt() gets a ticket for a given principal to use a given
+ * service and stores the returned ticket and session key for future
+ * use.
+ *
+ * The "user", "instance", and "realm" arguments give the identity of
+ * the client who will use the ticket.  The "service" and "sinstance"
+ * arguments give the identity of the server that the client wishes
+ * to use.  (The realm of the server is the same as the Kerberos server
+ * to whom the request is sent.)  The "life" argument indicates the
+ * desired lifetime of the ticket; the "key_proc" argument is a pointer
+ * to the routine used for getting the client's private key to decrypt
+ * the reply from Kerberos.  The "decrypt_proc" argument is a pointer
+ * to the routine used to decrypt the reply from Kerberos; and "arg"
+ * is an argument to be passed on to the "key_proc" routine.
+ *
+ * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
+ * returns an error code:  If an AUTH_MSG_ERR_REPLY packet is returned
+ * by Kerberos, then the error code it contains is returned.  Other
+ * error codes returned by this routine include INTK_PROT to indicate
+ * wrong protocol version, INTK_BADPW to indicate bad password (if
+ * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
+ * the wrong server or the ticket store couldn't be initialized.
+ *
+ * The format of the message sent to Kerberos is as follows:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 1 byte              KRB_PROT_VERSION        protocol version number
+ * 1 byte              AUTH_MSG_KDC_REQUEST |  message type
+ *                     HOST_BYTE_ORDER         local byte order in lsb
+ * string              user                    client's name
+ * string              instance                client's instance
+ * string              realm                   client's realm
+ * 4 bytes             tlocal.tv_sec           timestamp in seconds
+ * 1 byte              life                    desired lifetime
+ * string              service                 service's name
+ * string              sinstance               service's instance
+ */
+
+int
+krb_get_in_tkt(user, instance, realm, service, sinstance, life,
+              key_proc, decrypt_proc, arg)
+    char *user;
+    char *instance;
+    char *realm;
+    char *service;
+    char *sinstance;
+    int life;
+    int (*key_proc)();
+    int (*decrypt_proc)();
+    char *arg;
+{
+    KTEXT_ST pkt_st;
+    KTEXT pkt = &pkt_st;       /* Packet to KDC */
+    KTEXT_ST rpkt_st;
+    KTEXT rpkt = &rpkt_st;     /* Returned packet */
+    KTEXT_ST cip_st;
+    KTEXT cip = &cip_st;       /* Returned Ciphertext */
+    KTEXT_ST tkt_st;
+    KTEXT tkt = &tkt_st;       /* Current ticket */
+    des_cblock ses;                /* Session key for tkt */
+    int kvno;                  /* Kvno for session key */
+    unsigned char *v = pkt->dat; /* Prot vers no */
+    unsigned char *t = (pkt->dat+1); /* Prot msg type */
+
+    char s_name[SNAME_SZ];
+    char s_instance[INST_SZ];
+    char rlm[REALM_SZ];
+    int lifetime;
+    int msg_byte_order;
+    int kerror;
+    unsigned long exp_date;
+    char *ptr;
+
+    struct timeval t_local;
+
+    unsigned long rep_err_code;
+
+    unsigned long kdc_time;   /* KDC time */
+
+    /* BUILD REQUEST PACKET */
+
+    /* Set up the fixed part of the packet */
+    *v = (unsigned char) KRB_PROT_VERSION;
+    *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
+    *t |= HOST_BYTE_ORDER;
+
+    /* Now for the variable info */
+    (void) strcpy((char *)(pkt->dat+2),user); /* aname */
+    pkt->length = 3 + strlen(user);
+    (void) strcpy((char *)(pkt->dat+pkt->length),
+                 instance);    /* instance */
+    pkt->length += 1 + strlen(instance);
+    (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
+    pkt->length += 1 + strlen(realm);
+
+    (void) gettimeofday(&t_local,(struct timezone *) 0);
+    /* timestamp */
+    bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
+    pkt->length += 4;
+
+    *(pkt->dat+(pkt->length)++) = (char) life;
+    (void) strcpy((char *)(pkt->dat+pkt->length),service);
+    pkt->length += 1 + strlen(service);
+    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+    pkt->length += 1 + strlen(sinstance);
+
+    rpkt->length = 0;
+
+    /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+
+    if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror);
+
+    /* check packet version of the returned packet */
+    if (pkt_version(rpkt) != KRB_PROT_VERSION)
+        return(INTK_PROT);
+
+    /* Check byte order */
+    msg_byte_order = pkt_msg_type(rpkt) & 1;
+    swap_bytes = 0;
+    if (msg_byte_order != HOST_BYTE_ORDER) {
+        swap_bytes++;
+    }
+
+    switch (pkt_msg_type(rpkt) & ~1) {
+    case AUTH_MSG_KDC_REPLY:
+        break;
+    case AUTH_MSG_ERR_REPLY:
+        bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
+        if (swap_bytes) swap_u_long(rep_err_code);
+        return((int)rep_err_code);
+    default:
+        return(INTK_PROT);
+    }
+
+    /* EXTRACT INFORMATION FROM RETURN PACKET */
+
+    /* get the principal's expiration date */
+    bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
+    if (swap_bytes) swap_u_long(exp_date);
+
+    /* Extract the ciphertext */
+    cip->length = pkt_clen(rpkt);       /* let clen do the swap */
+
+    if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
+       return(INTK_ERR);               /* no appropriate error code
+                                        currently defined for INTK_ */
+    /* copy information from return packet into "cip" */
+    bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
+
+    /* Attempt to decrypt the reply. */
+    if (decrypt_proc == NULL)
+       decrypt_proc = decrypt_tkt;
+    (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
+
+    ptr = (char *) cip->dat;
+
+    /* extract session key */
+    bcopy(ptr,(char *)ses,8);
+    ptr += 8;
+
+    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+       return(INTK_BADPW);
+
+    /* extract server's name */
+    (void) strcpy(s_name,ptr);
+    ptr += strlen(s_name) + 1;
+
+    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+       return(INTK_BADPW);
+
+    /* extract server's instance */
+    (void) strcpy(s_instance,ptr);
+    ptr += strlen(s_instance) + 1;
+
+    if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+       return(INTK_BADPW);
+
+    /* extract server's realm */
+    (void) strcpy(rlm,ptr);
+    ptr += strlen(rlm) + 1;
+
+    /* extract ticket lifetime, server key version, ticket length */
+    /* be sure to avoid sign extension on lifetime! */
+    lifetime = (unsigned char) ptr[0];
+    kvno = (unsigned char) ptr[1];
+    tkt->length = (unsigned char) ptr[2];
+    ptr += 3;
+    
+    if ((tkt->length < 0) ||
+       ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
+       return(INTK_BADPW);
+
+    /* extract ticket itself */
+    bcopy(ptr,(char *)(tkt->dat),tkt->length);
+    ptr += tkt->length;
+
+    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+        strcmp(rlm, realm))    /* not what we asked for */
+       return(INTK_ERR);       /* we need a better code here XXX */
+
+    /* check KDC time stamp */
+    bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+    if (swap_bytes) swap_u_long(kdc_time);
+
+    ptr += 4;
+
+    (void) gettimeofday(&t_local,(struct timezone *) 0);
+    if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+        return(RD_AP_TIME);            /* XXX should probably be better
+                                          code */
+    }
+
+    /* initialize ticket cache */
+    if (in_tkt(user,instance) != KSUCCESS)
+       return(INTK_ERR);
+
+    /* stash ticket, session key, etc. for future use */
+    if ((kerror = save_credentials(s_name, s_instance, rlm, ses,
+                                 lifetime, kvno, tkt, t_local.tv_sec)))
+       return(kerror);
+
+    return(INTK_OK);
+}
diff --git a/kerberosIV/krb/krb_locl.h b/kerberosIV/krb/krb_locl.h
new file mode 100644 (file)
index 0000000..5b5d50b
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id: krb_locl.h,v 1.1.1.1 1995/12/14 06:52:38 tholo Exp $ */
+
+#ifndef __krb_locl_h
+#define __krb_locl_h
+
+#include <sys/cdefs.h>
+#include "kerberosIV/site.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <errno.h>
+
+#include <kerberosIV/krb.h>
+#include <prot.h>
+
+/* --- */
+
+/* Globals! */
+extern int krb_debug;
+extern int krb_ap_req_debug;
+
+/* Utils */
+char *pkt_cipher __P((KTEXT));
+
+int new_log __P((time_t, char *));
+char *klog ();
+
+char *month_sname __P((int));
+int fgetst __P((FILE *, char *, int));
+
+#endif /*  __krb_locl_h */
diff --git a/kerberosIV/krb/krb_realmofhost.3 b/kerberosIV/krb/krb_realmofhost.3
new file mode 100644 (file)
index 0000000..d60e1c2
--- /dev/null
@@ -0,0 +1,162 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_realmofhost.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_realmofhost.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question.  In order to prevent certain security attacks, this routine
+must either have 
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by 
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If 
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by 
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+The configuration file is described by 
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned.  If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports 
+.I n
+= 1.  It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/kerberosIV/krb/krb_sendauth.3 b/kerberosIV/krb/krb_sendauth.3
new file mode 100644 (file)
index 0000000..512fa42
--- /dev/null
@@ -0,0 +1,349 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_sendauth.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_sendauth.3,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;                 
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see 
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by 
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using 
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated.  They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see 
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters.  It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <mit-copyright.h>.
diff --git a/kerberosIV/krb/krb_set_tkt_string.3 b/kerberosIV/krb/krb_set_tkt_string.3
new file mode 100644 (file)
index 0000000..129169f
--- /dev/null
@@ -0,0 +1,44 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/krb_set_tkt_string.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_set_tkt_string \- set Kerberos ticket cache file name
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+void krb_set_tkt_string(filename)
+char *filename;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_set_tkt_string
+sets the name of the file that holds the user's
+cache of Kerberos server tickets and associated session keys.
+.PP
+The string 
+.I filename
+passed in is copied into local storage.
+Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
+copied in for use as the cache file name.
+.PP
+This routine should be called during initialization, before other
+Kerberos routines are called; otherwise the routines which fetch the
+ticket cache file name may be called and return an undesired ticket file
+name until this routine is called.
+.SH FILES
+.TP 20n
+/tmp/tkt[uid]
+default ticket file name, unless the environment variable KRBTKFILE is set.
+[uid] denotes the user's uid, in decimal.
+.SH SEE ALSO
+kerberos(3), setenv(3)
diff --git a/kerberosIV/krb/kuserok.3 b/kerberosIV/krb/kuserok.3
new file mode 100644 (file)
index 0000000..4aa7d5b
--- /dev/null
@@ -0,0 +1,64 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/kuserok.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/kuserok.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kuserok \- Kerberos version of ruserok
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+kuserok(kdata, localuser)
+AUTH_DAT *auth_data;
+char   *localuser;
+.fi
+.ft R
+.SH DESCRIPTION
+.I kuserok
+determines whether a Kerberos principal described by the structure
+.I auth_data
+is authorized to login as user
+.I localuser
+according to the authorization file
+("~\fIlocaluser\fR/.klogin" by default).  It returns 0 (zero) if authorized,
+1 (one) if not authorized.
+.PP
+If there is no account for 
+.I localuser
+on the local machine, authorization is not granted.
+If there is no authorization file, and the Kerberos principal described
+by 
+.I auth_data
+translates to 
+.I localuser
+(using 
+.IR krb_kntoln (3)),
+authorization is granted.
+If the authorization file
+can't be accessed, or the file is not owned by
+.IR localuser,
+authorization is denied.  Otherwise, the file is searched for
+a matching principal name, instance, and realm.  If a match is found,
+authorization is granted, else authorization is denied.
+.PP
+The file entries are in the format:
+.nf
+.in +5n
+       name.instance@realm
+.in -5n
+.fi
+with one entry per line.
+.SH SEE ALSO
+kerberos(3), ruserok(3), krb_kntoln(3)
+.SH FILES
+.TP 20n
+~\fIlocaluser\fR/.klogin
+authorization list
diff --git a/kerberosIV/krb/kuserok.c b/kerberosIV/krb/kuserok.c
new file mode 100644 (file)
index 0000000..fd888fc
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/kuserok.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * kuserok: check if a kerberos principal has
+ * access to a local account
+ */
+
+#include "krb_locl.h"
+
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "kdata", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default).  Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK.  If there is no authorization file, and the given Kerberos
+ * name "kdata" translates to the same name as "luser" (using
+ * krb_kntoln()), returns OK.  Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK.  Otherwise, the file is read for
+ * a matching principal name, instance, and realm.  If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format:
+ *
+ *     name.instance@realm
+ *
+ * one entry per line.
+ *
+ * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
+ * file entries.  See the file "kparse.c".
+ */
+
+#ifdef ATHENA_COMPAT
+
+#include <kparse.h>
+
+/*
+ * The parmtable defines the keywords we will recognize with their
+ * default values, and keeps a pointer to the found value.  The found
+ * value should be filled in with strsave(), since FreeParameterSet()
+ * will release memory for all non-NULL found strings. 
+ *
+*** NOTE WELL! *** 
+ *
+ * The table below is very nice, but we cannot hard-code a default for the
+ * realm: we have to get the realm via krb_get_lrealm().  Even though the
+ * default shows as "from krb_get_lrealm, below", it gets changed in
+ * kuserok to whatever krb_get_lrealm() tells us.  That code assumes that
+ * the realm will be the entry number in the table below, so if you
+ * change the order of the entries below, you have to change the
+ * #definition of REALM_SCRIPT to reflect it. 
+ */
+#define REALM_SUBSCRIPT 1
+parmtable kparm[] = {
+
+/* keyword     default                         found value     */
+{"user",       "",                             (char *) NULL},
+{"realm",      "see krb_get_lrealm, below",    (char *) NULL},
+{"instance",    "",                            (char *) NULL},
+};
+#define KPARMS kparm,PARMCOUNT(kparm)
+#endif /* ATHENA_COMPAT */
+
+int
+kuserok(kdata, luser)
+       AUTH_DAT *kdata;
+       char *luser;
+{
+    struct stat sbuf;
+    struct passwd *pwd;
+    char pbuf[MAXPATHLEN];
+    int isok = NOTOK, rc;
+    FILE *fp;
+    char kuser[MAX_USERNAME];
+    char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+    char linebuf[BUFSIZ];
+    char *newline;
+    int gobble;
+#ifdef ATHENA_COMPAT
+    char local_realm[REALM_SZ];
+#endif /* ATHENA_COMPAT */
+
+    /* no account => no access */
+    if ((pwd = getpwnam(luser)) == NULL) {
+       return(NOTOK);
+    }
+    (void) strcpy(pbuf, pwd->pw_dir);
+    (void) strcat(pbuf, "/.klogin");
+
+    if (access(pbuf, F_OK)) {   /* not accessible */
+       /*
+        * if he's trying to log in as himself, and there is no .klogin file,
+        * let him.  To find out, call
+        * krb_kntoln to convert the triple in kdata to a name which we can
+        * string compare. 
+        */
+       if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
+           return(OK);
+       }
+    }
+    /* open ~/.klogin */
+    if ((fp = fopen(pbuf, "r")) == NULL) {
+       return(NOTOK);
+    }
+    /*
+     * security:  if the user does not own his own .klogin file,
+     * do not grant access
+     */
+    if (fstat(fileno(fp), &sbuf)) {
+       fclose(fp);
+       return(NOTOK);
+    }
+    if (sbuf.st_uid != pwd->pw_uid) {
+       fclose(fp);
+       return(NOTOK);
+    }
+
+#ifdef ATHENA_COMPAT
+    /* Accept old-style .klogin files */
+
+    /*
+     * change the default realm from the hard-coded value to the
+     * accepted realm that Kerberos specifies. 
+     */
+    rc = krb_get_lrealm(local_realm, 1);
+    if (rc == KSUCCESS)
+       kparm[REALM_SUBSCRIPT].defvalue = local_realm;
+    else
+       return (rc);
+
+    /* check each line */
+    while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
+       switch (rc) {
+       case PS_BAD_KEYWORD:
+       case PS_SYNTAX:
+           while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
+           break;
+
+       case PS_OKAY:
+           isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
+                   ParmCompare(KPARMS, "instance", kdata->pinst) ||
+                   ParmCompare(KPARMS, "realm", kdata->prealm));
+           break;
+
+       default:
+           break;
+       }
+       FreeParameterSet(kparm, PARMCOUNT(kparm));
+    }
+    /* reset the stream for parsing new-style names, if necessary */
+    rewind(fp);
+#endif /* ATHENA_COMPAT */
+
+    /* check each line */
+    while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+       /* null-terminate the input string */
+       linebuf[BUFSIZ-1] = '\0';
+       newline = NULL;
+       /* nuke the newline if it exists */
+       if ((newline = strchr(linebuf, '\n')))
+           *newline = '\0';
+       rc = kname_parse(principal, inst, realm, linebuf);
+       if (rc == KSUCCESS) {
+           isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
+                   strncmp(kdata->pinst, inst, INST_SZ) ||
+                   strncmp(kdata->prealm, realm, REALM_SZ));
+       }
+       /* clean up the rest of the line if necessary */
+       if (!newline)
+           while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+    }
+    fclose(fp);
+    return(isok);
+}
diff --git a/kerberosIV/krb/lifetime.c b/kerberosIV/krb/lifetime.c
new file mode 100644 (file)
index 0000000..e91d5b0
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/lifetime.c,v $
+ *
+ * $Locker:  $
+ */
+
+/***************************************************************************
+ * PRE-HISTORY
+ *
+ * Revision 2.1.2.2  91/11/08  00:35:25  mja
+ *     Lower NEVERDATE to a positive value since time values are not
+ *     handled properly by most of the rest of the system when
+ *     negative;  add krb_life_to_atime() and krb_atime_to_life().
+ *     [91/11/07  22:52:50  mja]
+ * 
+ * Revision 2.1.2.1  91/07/09  22:50:42  mja
+ *     Created.
+ *     [91/01/30            jm36@ANDREW.CMU.EDU]
+ * 
+ ***************************************************************************/
+
+/*
+ * Ticket lifetime.  This defines the table used to lookup lifetime
+ * for the fixed part of rande of the one byte lifetime field.  Values
+ * less than 0x80 are intrpreted as the number of 5 minute intervals.
+ * Values from 0x80 to 0xBF should be looked up in this table.  The
+ * value of 0x80 is the same using both methods: 10 and two-thirds
+ * hours .  The lifetime of 0xBF is 30 days.  The intervening values
+ * of have a fixed ratio of roughly 1.06914.  The value 0xFF is
+ * defined to mean a ticket has no expiration time.  This should be
+ * used advisedly since individual servers may impose defacto
+ * upperbounds on ticket lifetimes.
+ */
+
+#include "krb_locl.h"
+
+#define TKTLIFENUMFIXED 64
+#define TKTLIFEMINFIXED 0x80
+#define TKTLIFEMAXFIXED 0xBF
+#define TKTLIFENOEXPIRE 0xFF
+#define MAXTKTLIFETIME (30*24*3600)    /* 30 days */
+#ifndef NEVERDATE
+#define NEVERDATE ((unsigned long)0x7fffffffL)
+#endif
+
+static const int tkt_lifetimes[TKTLIFENUMFIXED] = {
+    38400,                             /* 10.67 hours, 0.44 days */ 
+    41055,                             /* 11.40 hours, 0.48 days */ 
+    43894,                             /* 12.19 hours, 0.51 days */ 
+    46929,                             /* 13.04 hours, 0.54 days */ 
+    50174,                             /* 13.94 hours, 0.58 days */ 
+    53643,                             /* 14.90 hours, 0.62 days */ 
+    57352,                             /* 15.93 hours, 0.66 days */ 
+    61318,                             /* 17.03 hours, 0.71 days */ 
+    65558,                             /* 18.21 hours, 0.76 days */ 
+    70091,                             /* 19.47 hours, 0.81 days */ 
+    74937,                             /* 20.82 hours, 0.87 days */ 
+    80119,                             /* 22.26 hours, 0.93 days */ 
+    85658,                             /* 23.79 hours, 0.99 days */ 
+    91581,                             /* 25.44 hours, 1.06 days */ 
+    97914,                             /* 27.20 hours, 1.13 days */ 
+    104684,                            /* 29.08 hours, 1.21 days */ 
+    111922,                            /* 31.09 hours, 1.30 days */ 
+    119661,                            /* 33.24 hours, 1.38 days */ 
+    127935,                            /* 35.54 hours, 1.48 days */ 
+    136781,                            /* 37.99 hours, 1.58 days */ 
+    146239,                            /* 40.62 hours, 1.69 days */ 
+    156350,                            /* 43.43 hours, 1.81 days */ 
+    167161,                            /* 46.43 hours, 1.93 days */ 
+    178720,                            /* 49.64 hours, 2.07 days */ 
+    191077,                            /* 53.08 hours, 2.21 days */ 
+    204289,                            /* 56.75 hours, 2.36 days */ 
+    218415,                            /* 60.67 hours, 2.53 days */ 
+    233517,                            /* 64.87 hours, 2.70 days */ 
+    249664,                            /* 69.35 hours, 2.89 days */ 
+    266926,                            /* 74.15 hours, 3.09 days */ 
+    285383,                            /* 79.27 hours, 3.30 days */ 
+    305116,                            /* 84.75 hours, 3.53 days */ 
+    326213,                            /* 90.61 hours, 3.78 days */ 
+    348769,                            /* 96.88 hours, 4.04 days */ 
+    372885,                            /* 103.58 hours, 4.32 days */ 
+    398668,                            /* 110.74 hours, 4.61 days */ 
+    426234,                            /* 118.40 hours, 4.93 days */ 
+    455705,                            /* 126.58 hours, 5.27 days */ 
+    487215,                            /* 135.34 hours, 5.64 days */ 
+    520904,                            /* 144.70 hours, 6.03 days */ 
+    556921,                            /* 154.70 hours, 6.45 days */ 
+    595430,                            /* 165.40 hours, 6.89 days */ 
+    636601,                            /* 176.83 hours, 7.37 days */ 
+    680618,                            /* 189.06 hours, 7.88 days */ 
+    727680,                            /* 202.13 hours, 8.42 days */ 
+    777995,                            /* 216.11 hours, 9.00 days */ 
+    831789,                            /* 231.05 hours, 9.63 days */ 
+    889303,                            /* 247.03 hours, 10.29 days */ 
+    950794,                            /* 264.11 hours, 11.00 days */ 
+    1016537,                           /* 282.37 hours, 11.77 days */ 
+    1086825,                           /* 301.90 hours, 12.58 days */ 
+    1161973,                           /* 322.77 hours, 13.45 days */ 
+    1242318,                           /* 345.09 hours, 14.38 days */ 
+    1328218,                           /* 368.95 hours, 15.37 days */ 
+    1420057,                           /* 394.46 hours, 16.44 days */ 
+    1518247,                           /* 421.74 hours, 17.57 days */ 
+    1623226,                           /* 450.90 hours, 18.79 days */ 
+    1735464,                           /* 482.07 hours, 20.09 days */ 
+    1855462,                           /* 515.41 hours, 21.48 days */ 
+    1983758,                           /* 551.04 hours, 22.96 days */ 
+    2120925,                           /* 589.15 hours, 24.55 days */ 
+    2267576,                           /* 629.88 hours, 26.25 days */ 
+    2424367,                           /* 673.44 hours, 28.06 days */ 
+    2592000};                          /* 720.00 hours, 30.00 days */ 
+
+/*
+ * krb_life_to_time - takes a start time and a Kerberos standard
+ * lifetime char and returns the corresponding end time.  There are
+ * four simple cases to be handled.  The first is a life of 0xff,
+ * meaning no expiration, and results in an end time of 0xffffffff.
+ * The second is when life is less than the values covered by the
+ * table.  In this case, the end time is the start time plus the
+ * number of 5 minute intervals specified by life.  The third case
+ * returns start plus the MAXTKTLIFETIME if life is greater than
+ * TKTLIFEMAXFIXED.  The last case, uses the life value (minus
+ * TKTLIFEMINFIXED) as an index into the table to extract the lifetime
+ * in seconds, which is added to start to produce the end time.
+ */
+u_int32_t
+krb_life_to_time(start, life)
+       u_int32_t start;
+       int life;
+{
+    life = (unsigned char) life;
+    if (life == TKTLIFENOEXPIRE) return NEVERDATE;
+    if (life < TKTLIFEMINFIXED) return start + life*5*60;
+    if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME;
+    return start + tkt_lifetimes[life - TKTLIFEMINFIXED];
+}
+
+/*
+ * krb_time_to_life - takes start and end times for the ticket and
+ * returns a Kerberos standard lifetime char, possibily using the
+ * tkt_lifetimes table for lifetimes above 127*5 minutes.  First, the
+ * special case of (end == NEVERDATE) is handled to mean no
+ * expiration.  Then negative lifetimes and those greater than the
+ * maximum ticket lifetime are rejected.  Then lifetimes less than the
+ * first table entry are handled by rounding the requested lifetime
+ * *up* to the next 5 minute interval.  The final step is to search
+ * the table for the smallest entry *greater than or equal* to the
+ * requested entry.
+ */
+int
+krb_time_to_life(start, end)
+       u_int32_t start;
+       u_int32_t end;
+{
+    long lifetime;
+    int i;
+
+    if (end >= NEVERDATE) return TKTLIFENOEXPIRE;
+    lifetime = end - start;
+    if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0;
+    if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60);
+    for (i=0; i<TKTLIFENUMFIXED; i++) {
+       if (lifetime <= tkt_lifetimes[i]) {
+           return i+TKTLIFEMINFIXED;
+       }
+    }
+    return 0;
+}
+
+char *
+krb_life_to_atime(life)
+       int life;
+{
+    static char atime[11+1+2+1+2+1+2+1];
+    unsigned long when;
+    int secs, mins, hours;
+
+    if (life == TKTLIFENOEXPIRE)
+       return("Forever");
+    when = krb_life_to_time(0, life);
+    secs = when%60;
+    when /= 60;
+    mins = when%60;
+    when /= 60;
+    hours = when%24;
+    when /= 24;
+    sprintf(atime, "%d+%02d:%02d:%02d", (int)when, hours, mins, secs);
+    return(atime);
+}
+
+int
+krb_atime_to_life(atime)
+       char *atime;
+{
+    unsigned long when = 0;
+    register char *cp;
+    int colon = 0, plus = 0;
+    int n = 0;
+
+    if (strcasecmp(atime, "forever") == 0)
+       return(TKTLIFENOEXPIRE);
+    
+    for (cp=atime; *cp; cp++) {
+       switch(*cp) {
+           case '0': case '1': case '2': case '3': case '4':
+           case '5': case '6': case '7': case '8': case '9':
+               n = n*10 + *cp-'0';
+               break;
+           case '+':
+               plus++;
+               when += n;
+               when *= 24;
+               n = 0;
+               break;
+           case ':':
+               colon++;
+               when += n;
+               when *= 60;
+               n = 0;
+               break;
+           default:
+               break;
+       }
+    }
+    when += n;
+    if (plus == 0 && colon == 0)
+       return((unsigned char)when);
+    while (colon < 2) {
+       when *= 60;
+       colon++;
+    }
+    return(krb_time_to_life(0,when));
+}
diff --git a/kerberosIV/krb/log.c b/kerberosIV/krb/log.c
new file mode 100644 (file)
index 0000000..995319c
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/log.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static is_open;
+
+/*
+ * This file contains three logging routines: set_logfile()
+ * to determine the file that log entries should be written to;
+ * and log() and new_log() to write log entries to the file.
+ */
+
+/*
+ * log() is used to add entries to the logfile (see set_logfile()
+ * below).  Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format".
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * The return value is undefined.
+ */
+
+/*VARARGS1 */
+void
+log(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0)
+     char *format;
+     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a0;
+{
+    FILE *logfile;
+    time_t now;
+    struct tm *tm;
+
+    if ((logfile = fopen(log_name,"a")) == NULL)
+        return;
+
+    (void) time(&now);
+    tm = localtime(&now);
+
+    fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+            month_sname(tm->tm_mon + 1),tm->tm_year,
+            tm->tm_hour, tm->tm_min, tm->tm_sec);
+    fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+    fprintf(logfile,"\n");
+    (void) fclose(logfile);
+    return;
+}
+
+/*
+ * set_logfile() changes the name of the file to which
+ * messages are logged.  If set_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+void
+set_logfile(filename)
+       char *filename;
+{
+    log_name = filename;
+    is_open = 0;
+}
+
+/*
+ * new_log() appends a log entry containing the give time "t" and the
+ * string "string" to the logfile (see set_logfile() above).  The file
+ * is opened once and left open.  The routine returns 1 on failure, 0
+ * on success.
+ */
+
+int
+new_log(t, string)
+       time_t t;
+       char *string;
+{
+    static FILE *logfile;
+
+    struct tm *tm;
+
+    if (!is_open) {
+        if ((logfile = fopen(log_name,"a")) == NULL) return(1);
+        is_open = 1;
+    }
+
+    if (t) {
+        tm = localtime(&t);
+
+        fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d  %s",tm->tm_mday,
+                month_sname(tm->tm_mon + 1),tm->tm_year,
+                tm->tm_hour, tm->tm_min, tm->tm_sec, string);
+    }
+    else {
+        fprintf(logfile,"\n%20s%s","",string);
+    }
+
+    (void) fflush(logfile);
+    return(0);
+}
diff --git a/kerberosIV/krb/lsb_addr_comp.h b/kerberosIV/krb/lsb_addr_comp.h
new file mode 100644 (file)
index 0000000..2462be6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/lsb_addr_comp.h,v $
+ */
+
+/*
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Comparison macros to emulate LSBFIRST comparison results of network
+ * byte-order quantities
+ */
+
+#ifndef LSB_ADDR_COMP_DEFS
+#define LSB_ADDR_COMP_DEFS
+
+#if BYTE_ORDER == BIG_ENDIAN
+
+#define u_char_comp(x,y) \
+        (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
+/* This is gross, but... */
+#define lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y)
+#define lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y)
+
+#define long_less_than(x,y) \
+        (u_char_comp((x)[3],(y)[3])?u_char_comp((x)[3],(y)[3]): \
+        (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \
+         (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+          (u_char_comp((x)[0],(y)[0])))))
+#define short_less_than(x,y) \
+         (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+          (u_char_comp((x)[0],(y)[0])))
+
+#else /* !WORDS_BIGENDIAN */
+
+#define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+
+#endif /* !WORDS_BIGENDIAN */
+
+#endif /*  LSB_ADDR_COMP_DEFS */
diff --git a/kerberosIV/krb/mk_err.c b/kerberosIV/krb/mk_err.c
new file mode 100644 (file)
index 0000000..cc168c9
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_err.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/types.h>
+
+/*
+ * This routine creates a general purpose error reply message.  It
+ * doesn't use KTEXT because application protocol may have long
+ * messages, and may want this part of buffer contiguous to other
+ * stuff.
+ *
+ * The error reply is built in "p", using the error code "e" and
+ * error text "e_string" given.  The length of the error reply is
+ * returned.
+ *
+ * The error reply is in the following format:
+ *
+ * unsigned char       KRB_PROT_VERSION        protocol version no.
+ * unsigned char       AUTH_MSG_APPL_ERR       message type
+ * (least significant
+ * bit of above)       HOST_BYTE_ORDER         local byte order
+ * 4 bytes             e                       given error code
+ * string              e_string                given error text
+ */
+
+int32_t
+krb_mk_err(p, e, e_string)
+       u_char *p;              /* Where to build error packet */
+       int32_t e;              /* Error code */
+       char *e_string;         /* Text of error */
+{
+    u_char      *start;
+
+    start = p;
+
+    /* Create fixed part of packet */
+    *p++ = (unsigned char) KRB_PROT_VERSION;
+    *p = (unsigned char) AUTH_MSG_APPL_ERR;
+    *p++ |= HOST_BYTE_ORDER;
+
+    /* Add the basic info */
+    bcopy((char *)&e,(char *)p,4); /* err code */
+    p += sizeof(e);
+    (void) strcpy((char *)p,e_string); /* err text */
+    p += strlen(e_string);
+
+    /* And return the length */
+    return p-start;
+}
diff --git a/kerberosIV/krb/mk_priv.c b/kerberosIV/krb/mk_priv.c
new file mode 100644 (file)
index 0000000..e527a18
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_priv.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * This routine constructs a Kerberos 'private msg', i.e.
+ * cryptographically sealed with a private session key.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT.
+ *
+ * Note-- It's too bad that it did a long int compare on the RT before.
+ *
+ * Returns either < 0 ===> error, or resulting size of message
+ *
+ * Steve Miller    Project Athena  MIT/DEC
+ */
+
+#include "krb_locl.h"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include "lsb_addr_comp.h"
+
+/* static storage */
+static u_int32_t c_length;
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message.  It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+#ifndef NOENCRYTION
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+#endif
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum.  Also, the protocol version
+ * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 1 byte              private_msg_ver         protocol version number
+ * 1 byte              AUTH_MSG_PRIVATE |      message type plus local
+ *                     HOST_BYTE_ORDER         byte order in low bit
+ *
+ * 4 bytes             c_length                length of data
+#ifndef NOENCRYPT
+ * we encrypt from here with pcbc_encrypt
+#endif
+ * 
+ * 4 bytes             length                  length of user data
+ * length              in                      user data
+ * 1 byte              msg_time_5ms            timestamp milliseconds
+ * 4 bytes             sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes             msg_time_sec or         timestamp seconds with
+ *                     -msg_time_sec           direction in sign bit
+ *
+ * 0<=n<=7  bytes      pad to 8 byte multiple  zeroes
+ */
+
+int32_t
+krb_mk_priv(in, out, length, schedule, key, sender, receiver)
+       u_char *in;             /* application data */
+       u_char *out;            /* put msg here, leave room for
+                                 * header! breaks if in and out
+                                 * (header stuff) overlap */
+       u_int32_t length;       /* of in data */
+       struct des_ks_struct *schedule; /* precomputed key schedule */
+       des_cblock *key;        /* encryption key for seed and ivec */
+       struct sockaddr_in *sender; /* sender address */
+       struct sockaddr_in *receiver; /* receiver address */
+{
+    register u_char     *p,*q;
+    static       u_char *c_length_ptr;
+
+    /*
+     * get the current time to use instead of a sequence #, since
+     * process lifetime may be shorter than the lifetime of a session
+     * key.
+     */
+    if (gettimeofday(&msg_time,(struct timezone *)0)) {
+        return -1;
+    }
+    msg_time_sec = (long) msg_time.tv_sec;
+    msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+    p = out;
+
+    *p++ = private_msg_ver;
+    *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+
+    /* calculate cipher length */
+    c_length_ptr = p;
+    p += sizeof(c_length);
+
+    q = p;
+
+    /* stuff input length */
+    bcopy((char *)&length,(char *)p,sizeof(length));
+    p += sizeof(length);
+
+#ifdef NOENCRYPTION
+    /* make all the stuff contiguous for checksum */
+#else
+    /* make all the stuff contiguous for checksum and encryption */
+#endif
+    bcopy((char *)in,(char *)p,(int) length);
+    p += length;
+
+    /* stuff time 5ms */
+    bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+    p += sizeof(msg_time_5ms);
+
+    /* stuff source address */
+    bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
+          sizeof(sender->sin_addr.s_addr));
+    p += sizeof(sender->sin_addr.s_addr);
+
+    /*
+     * direction bit is the sign bit of the timestamp.  Ok
+     * until 2038??
+     */
+    /* For compatibility with broken old code, compares are done in VAX 
+       byte order (LSBFIRST) */ 
+    if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ 
+                         receiver->sin_addr.s_addr)==-1) 
+        msg_time_sec =  -msg_time_sec; 
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
+                               receiver->sin_addr.s_addr)==0) 
+        if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) 
+            msg_time_sec = -msg_time_sec; 
+    /* stuff time sec */
+    bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+    p += sizeof(msg_time_sec);
+
+    /*
+     * All that for one tiny bit!  Heaven help those that talk to
+     * themselves.
+     */
+
+#ifdef notdef
+    /*
+     * calculate the checksum of the length, address, sequence, and
+     * inp data
+     */
+    cksum =  des_quad_cksum(q,NULL,p-q,0,key);
+    if (krb_debug)
+        printf("\ncksum = %u",cksum);
+    /* stuff checksum */
+    bcopy((char *) &cksum,(char *) p,sizeof(cksum));
+    p += sizeof(cksum);
+#endif
+
+    /*
+     * All the data have been assembled, compute length
+     */
+
+    c_length = p - q;
+    c_length = ((c_length + sizeof(des_cblock) -1)/sizeof(des_cblock)) *
+        sizeof(des_cblock);
+    /* stuff the length */
+    bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
+
+#ifndef NOENCRYPTION
+    des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)(p-q),schedule,key, DES_ENCRYPT);
+#endif /* NOENCRYPTION */
+
+    return (q - out + c_length);        /* resulting size */
+}
diff --git a/kerberosIV/krb/mk_req.c b/kerberosIV/krb/mk_req.c
new file mode 100644 (file)
index 0000000..cabe872
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_req.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+
+static struct   timeval tv_local = { 0, 0 };
+static int lifetime = 255;     /* But no longer than TGT says. */
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum.  It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument.  krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req.  When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char       KRB_PROT_VERSION        protocol version no.
+ * unsigned char       AUTH_MSG_APPL_REQUEST   message type
+ * (least significant
+ * bit of above)       HOST_BYTE_ORDER         local byte ordering
+ * unsigned char       kvno from ticket        server's key version
+ * string              realm                   server's realm
+ * unsigned char       tl                      ticket length
+ * unsigned char       idl                     request id length
+ * text                        ticket->dat             ticket for server
+ * text                        req_id->dat             request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos.  The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string              cr.pname                {name, instance, and
+ * string              cr.pinst                realm of principal
+ * string              myrealm                 making this request}
+ * 4 bytes             checksum                checksum argument given
+ * unsigned char       tv_local.tf_usec        time (milliseconds)
+ * 4 bytes             tv_local.tv_sec         time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ *                  all rounded up to multiple of 8.
+ */
+
+int
+krb_mk_req(authent, service, instance, realm, checksum)
+       register KTEXT authent; /* Place to build the authenticator */
+       char *service;          /* Name of the service */
+       char *instance;         /* Service instance */
+       char *realm;            /* Authentication domain of service */
+       int32_t checksum;       /* Checksum of data (optional) */
+{
+    static KTEXT_ST req_st; /* Temp storage for req id */
+    register KTEXT req_id = &req_st;
+    unsigned char *v = authent->dat; /* Prot version number */
+    unsigned char *t = (authent->dat+1); /* Message type */
+    unsigned char *kv = (authent->dat+2); /* Key version no */
+    unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
+    unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
+    CREDENTIALS cr;             /* Credentials used by retr */
+    register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+    int retval;                 /* Returned by krb_get_cred */
+    static des_key_schedule key_s;
+    char myrealm[REALM_SZ];
+
+    /* The fixed parts of the authenticator */
+    *v = (unsigned char) KRB_PROT_VERSION;
+    *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
+    *t |= HOST_BYTE_ORDER;
+
+    /* Get the ticket and move it into the authenticator */
+    if (krb_ap_req_debug)
+        printf("Realm: %s\n",realm);
+    /* 
+     * Determine realm of these tickets.  We will send this to the
+     * KDC from which we are requesting tickets so it knows what to
+     * with our session key.
+     */
+    if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
+       return(retval);
+    
+    retval = krb_get_cred(service,instance,realm,&cr);
+
+    if (retval == RET_NOTKT) {
+        if ((retval = get_ad_tkt(service,instance,realm,lifetime)))
+            return(retval);
+        if ((retval = krb_get_cred(service,instance,realm,&cr)))
+            return(retval);
+    }
+
+    if (retval != KSUCCESS) return (retval);
+
+    if (krb_ap_req_debug)
+        printf("%s %s %s %s %s\n", service, instance, realm,
+               cr.pname, cr.pinst);
+    *kv = (unsigned char) cr.kvno;
+    (void) strcpy((char *)(authent->dat+3),realm);
+    *tl = (unsigned char) ticket->length;
+    bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
+          ticket->length);
+    authent->length = 6 + strlen(realm) + ticket->length;
+    if (krb_ap_req_debug)
+        printf("Ticket->length = %d\n",ticket->length);
+    if (krb_ap_req_debug)
+        printf("Issue date: %d\n",cr.issue_date);
+
+    /* Build request id */
+    (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
+    req_id->length = strlen(cr.pname)+1;
+    /* Principal's instance */
+    (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
+    req_id->length += strlen(cr.pinst)+1;
+    /* Authentication domain */
+    (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
+    req_id->length += strlen(myrealm)+1;
+    /* Checksum */
+    bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
+    req_id->length += 4;
+
+    /* Fill in the times on the request id */
+    (void) gettimeofday(&tv_local,(struct timezone *) 0);
+    *(req_id->dat+(req_id->length)++) =
+        (unsigned char) tv_local.tv_usec;
+    /* Time (coarse) */
+    bcopy((char *)&(tv_local.tv_sec),
+          (char *)(req_id->dat+req_id->length), 4);
+    req_id->length += 4;
+
+    /* Fill to a multiple of 8 bytes for DES */
+    req_id->length = ((req_id->length+7)/8)*8;
+
+#ifndef NOENCRYPTION
+    des_key_sched(&cr.session,key_s);
+    des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat,
+       (long)req_id->length,key_s,&cr.session, DES_ENCRYPT);
+    bzero((char *) key_s, sizeof(key_s));
+#endif /* NOENCRYPTION */
+
+    /* Copy it into the authenticator */
+    bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
+          req_id->length);
+    authent->length += req_id->length;
+    /* And set the id length */
+    *idl = (unsigned char) req_id->length;
+    /* clean up */
+    bzero((char *)req_id, sizeof(*req_id));
+
+    if (krb_ap_req_debug)
+        printf("Authent->length = %d\n",authent->length);
+    if (krb_ap_req_debug)
+        printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
+
+    return(KSUCCESS);
+}
+
+/* 
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ * 
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(newval)
+       int newval;
+{
+    int olife = lifetime;
+
+    lifetime = newval;
+    return(olife);
+}
diff --git a/kerberosIV/krb/mk_safe.c b/kerberosIV/krb/mk_safe.c
new file mode 100644 (file)
index 0000000..6d49fd8
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/mk_safe.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * This routine constructs a Kerberos 'safe msg', i.e. authenticated
+ * using a private session key to seed a checksum. Msg is NOT
+ * encrypted.
+ *
+ *      Note-- bcopy is used to avoid alignment problems on IBM RT
+ *
+ *      Returns either <0 ===> error, or resulting size of message
+ *
+ * Steve Miller    Project Athena  MIT/DEC
+ */
+
+#include "krb_locl.h"
+
+/* system include files */
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include "lsb_addr_comp.h"
+
+/* static storage */
+static u_int32_t cksum;
+static des_cblock big_cksum[2];
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message.  It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key".  The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 1 byte              KRB_PROT_VERSION        protocol version number
+ * 1 byte              AUTH_MSG_SAFE |         message type plus local
+ *                     HOST_BYTE_ORDER         byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ * 
+ * 4 bytes             length                  length of user data
+ * length              in                      user data
+ * 1 byte              msg_time_5ms            timestamp milliseconds
+ * 4 bytes             sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes             msg_time_sec or         timestamp seconds with
+ *                     -msg_time_sec           direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes            big_cksum               quadratic checksum of
+ *                                             above using "key"
+ */
+
+int32_t
+krb_mk_safe(in, out, length, key, sender, receiver)
+       u_char *in;             /* application data */
+       u_char *out;            /*
+                                * put msg here, leave room for header!
+                                * breaks if in and out (header stuff)
+                                * overlap
+                                */
+       u_int32_t length;       /* of in data */
+       des_cblock *key;        /* encryption key for seed and ivec */
+       struct sockaddr_in *sender; /* sender address */
+       struct sockaddr_in *receiver; /* receiver address */
+{
+    register u_char     *p,*q;
+
+    /*
+     * get the current time to use instead of a sequence #, since
+     * process lifetime may be shorter than the lifetime of a session
+     * key.
+     */
+    if (gettimeofday(&msg_time,(struct timezone *)0)) {
+        return  -1;
+    }
+    msg_time_sec = (long) msg_time.tv_sec;
+    msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+    p = out;
+
+    *p++ = KRB_PROT_VERSION;
+    *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+
+    q = p;                     /* start for checksum stuff */
+    /* stuff input length */
+    bcopy((char *)&length,(char *)p,sizeof(length));
+    p += sizeof(length);
+
+    /* make all the stuff contiguous for checksum */
+    bcopy((char *)in,(char *)p,(int) length);
+    p += length;
+
+    /* stuff time 5ms */
+    bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+    p += sizeof(msg_time_5ms);
+
+    /* stuff source address */
+    bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
+          sizeof(sender->sin_addr.s_addr));
+    p += sizeof(sender->sin_addr.s_addr);
+
+    /*
+     * direction bit is the sign bit of the timestamp.  Ok until
+     * 2038??
+     */
+    /* For compatibility with broken old code, compares are done in VAX 
+       byte order (LSBFIRST) */ 
+    if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */ 
+                         receiver->sin_addr.s_addr)==-1) 
+        msg_time_sec =  -msg_time_sec; 
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
+                               receiver->sin_addr.s_addr)==0) 
+        if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1) 
+            msg_time_sec = -msg_time_sec; 
+    /*
+     * all that for one tiny bit!  Heaven help those that talk to
+     * themselves.
+     */
+
+    /* stuff time sec */
+    bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+    p += sizeof(msg_time_sec);
+
+#ifdef NOENCRYPTION
+    cksum = 0;
+    bzero(big_cksum, sizeof(big_cksum));
+#else
+    cksum = des_quad_cksum((des_cblock *)q,big_cksum,p-q,2,key);
+#endif
+    if (krb_debug)
+        printf("\ncksum = %u",(u_int) cksum);
+
+    /* stuff checksum */
+    bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
+    p += sizeof(big_cksum);
+
+    return ((long)(p - out));  /* resulting size */
+
+}
diff --git a/kerberosIV/krb/month_sname.c b/kerberosIV/krb/month_sname.c
new file mode 100644 (file)
index 0000000..55f5ea4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/month_sname.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * Given an integer 1-12, month_sname() returns a string
+ * containing the first three letters of the corresponding
+ * month.  Returns 0 if the argument is out of range.
+ */
+
+char *
+month_sname(n)
+       int n;
+{
+    static char *name[] = {
+        "Jan","Feb","Mar","Apr","May","Jun",
+        "Jul","Aug","Sep","Oct","Nov","Dec"
+    };
+    return((n < 1 || n > 12) ? 0 : name [n-1]);
+}
diff --git a/kerberosIV/krb/netread.c b/kerberosIV/krb/netread.c
new file mode 100644 (file)
index 0000000..e362017
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/netread.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * krb_net_read() reads from the file descriptor "fd" to the buffer
+ * "buf", until either 1) "len" bytes have been read or 2) cannot
+ * read anymore from "fd".  It returns the number of bytes read
+ * or a read() error.  (The calling interface is identical to
+ * read(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_read(fd, buf, len)
+       int fd;
+       register char *buf;
+       register int len;
+{
+    int cc, len2 = 0;
+
+    do {
+       cc = read(fd, buf, len);
+       if (cc < 0)
+           return(cc);          /* errno is already set */
+       else if (cc == 0) {
+           return(len2);
+       } else {
+           buf += cc;
+           len2 += cc;
+           len -= cc;
+       }
+    } while (len > 0);
+    return(len2);
+}
diff --git a/kerberosIV/krb/netwrite.c b/kerberosIV/krb/netwrite.c
new file mode 100644 (file)
index 0000000..4c7146d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/netwrite.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * krb_net_write() writes "len" bytes from "buf" to the file
+ * descriptor "fd".  It returns the number of bytes written or
+ * a write() error.  (The calling interface is identical to
+ * write(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_write(fd, buf, len)
+       int fd;
+       register char *buf;
+       int len;
+{
+    int cc;
+    register int wrlen = len;
+    do {
+       cc = write(fd, buf, wrlen);
+       if (cc < 0)
+           return(cc);
+       else {
+           buf += cc;
+           wrlen -= cc;
+       }
+    } while (wrlen > 0);
+    return(len);
+}
diff --git a/kerberosIV/krb/one.c b/kerberosIV/krb/one.c
new file mode 100644 (file)
index 0000000..beff561
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/one.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+  Export of this software from the United States of America is assumed
+  to require a specific license from the United States Government.
+  It is the responsibility of any person or organization contemplating
+  export to obtain such a license before exporting.
+  
+  WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+  distribute this software and its documentation for any purpose and
+  without fee is hereby granted, provided that the above copyright
+  notice appear in all copies and that both that copyright notice and
+  this permission notice appear in supporting documentation, and that
+  the name of M.I.T. not be used in advertising or publicity pertaining
+  to distribution of the software without specific, written prior
+  permission.  M.I.T. makes no representations about the suitability of
+  this software for any purpose.  It is provided "as is" without express
+  or implied warranty.
+  
+  */
+
+/*
+ * definition of variable set to 1.
+ * used in krb_conf.h to determine host byte order.
+ */
+
+int krbONE = 1;
diff --git a/kerberosIV/krb/pkt_cipher.c b/kerberosIV/krb/pkt_cipher.c
new file mode 100644 (file)
index 0000000..ecf90bd
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/pkt_cipher.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine takes a reply packet from the Kerberos ticket-granting
+ * service and returns a pointer to the beginning of the ciphertext in it.
+ *
+ * See "prot.h" for packet format.
+ */
+
+char *
+pkt_cipher(packet)
+       KTEXT packet;
+{
+    unsigned char *ptr = pkt_a_realm(packet) + 6
+       + strlen((char *)pkt_a_realm(packet));
+    /* Skip a few more fields */
+    ptr += 3 + 4;              /* add 4 for exp_date */
+
+    /* And return the pointer */
+    return((char*)ptr);
+}
diff --git a/kerberosIV/krb/pkt_clen.c b/kerberosIV/krb/pkt_clen.c
new file mode 100644 (file)
index 0000000..00ecc73
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/pkt_clen.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#if defined(horrible_function_using_global_variable_had_to_be_inlined)
+
+#include "krb_locl.h"
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion.  The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order.  pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+int
+pkt_clen(pkt)
+       KTEXT pkt;
+{
+    static unsigned short temp,temp2;
+    int clen = 0;
+
+    /* Start of ticket list */
+    unsigned char *ptr = pkt_a_realm(pkt) + 10
+       + strlen((char *)pkt_a_realm(pkt));
+
+    /* Finally the length */
+    bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+    if (swap_bytes) {
+        /* assume a short is 2 bytes?? */
+        swab((char *)&temp,(char *)&temp2,2);
+        temp = temp2;
+    }
+
+    clen = (int) temp;
+
+    if (krb_debug)
+       printf("Clen is %d\n",clen);
+    return(clen);
+}
+
+#endif /* defined(horrible_function_using_global_variable_had_to_be_inlined) */
diff --git a/kerberosIV/krb/rd_err.c b/kerberosIV/krb/rd_err.c
new file mode 100644 (file)
index 0000000..33c3cf0
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_err.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * This routine dissects a a Kerberos 'safe msg',
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller    Project Athena  MIT/DEC
+ */
+
+#include "krb_locl.h"
+
+/* system include files */
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/*
+ * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
+ * return the error code from the message in "code" and the text in
+ * "m_data" as follows:
+ *
+ *     m_data->app_data        points to the error text
+ *     m_data->app_length      points to the length of the error text
+ *
+ * If all goes well, return RD_AP_OK.  If the version number
+ * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
+ * type message, return RD_AP_MSG_TYPE.
+ *
+ * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
+ */
+
+int
+krb_rd_err(in, in_length, code, m_data)
+       u_char *in;             /* pointer to the msg received */
+       u_int32_t in_length;    /* of in msg */
+       int32_t *code;          /* received error code */
+       MSG_DAT *m_data;
+{
+    register u_char *p;
+    int swap_bytes = 0;
+    p = in;                     /* beginning of message */
+
+    if (*p++ != KRB_PROT_VERSION)
+        return(RD_AP_VERSION);
+    if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
+        return(RD_AP_MSG_TYPE);
+    if ((*p++ & 1) != HOST_BYTE_ORDER)
+        swap_bytes++;
+
+    /* safely get code */
+    bcopy((char *)p,(char *)code,sizeof(*code));
+    if (swap_bytes)
+        swap_u_long(*code);
+    p += sizeof(*code);         /* skip over */
+
+    m_data->app_data = p;       /* we're now at the error text
+                                 * message */
+    m_data->app_length = in_length;
+
+    return(RD_AP_OK);           /* OK == 0 */
+}
diff --git a/kerberosIV/krb/rd_priv.c b/kerberosIV/krb/rd_priv.c
new file mode 100644 (file)
index 0000000..21c959e
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_priv.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * This routine dissects a a Kerberos 'private msg', decrypting it,
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...).  If
+ * the return value is RD_AP_TIME, then either the times are too far
+ * out of synch, OR the packet was modified.
+ *
+ * Steve Miller    Project Athena  MIT/DEC
+ */
+
+#include "krb_locl.h"
+
+/* system include files */
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include "lsb_addr_comp.h"
+
+/* static storage */
+static u_int32_t c_length;
+static int swap_bytes;
+static struct timeval local_time;
+static long delta_t;
+
+/* Global! */
+int private_msg_ver = KRB_PROT_VERSION;
+
+/*
+#ifdef NOENCRPYTION
+ * krb_rd_priv() checks the integrity of an
+#else
+ * krb_rd_priv() decrypts and checks the integrity of an
+#endif
+ * AUTH_MSG_PRIVATE message.  Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data".  The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message.  The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+int32_t
+krb_rd_priv(in, in_length, schedule, key, sender, receiver, m_data)
+       u_char *in;             /* pointer to the msg received */
+       u_int32_t in_length;    /* length of "in" msg */
+       struct des_ks_struct *schedule; /* precomputed key schedule */
+       des_cblock *key;        /* encryption key for seed and ivec */
+       struct sockaddr_in *sender;
+       struct sockaddr_in *receiver;
+       MSG_DAT *m_data;        /*various input/output data from msg */
+{
+    register u_char *p,*q;
+    static u_int32_t src_addr; /* Can't send structs since no
+                                * guarantees on size */
+
+    if (gettimeofday(&local_time,(struct timezone *)0))
+        return  -1;
+
+    p = in;                    /* beginning of message */
+    swap_bytes = 0;
+
+    if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+        return RD_AP_VERSION;
+    private_msg_ver = *(p-1);
+    if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+        return RD_AP_MSG_TYPE;
+    if ((*p++ & 1) != HOST_BYTE_ORDER)
+        swap_bytes++;
+
+    /* get cipher length */
+    bcopy((char *)p,(char *)&c_length,sizeof(c_length));
+    if (swap_bytes)
+        swap_u_long(c_length);
+    p += sizeof(c_length);
+    /* check for rational length so we don't go comatose */
+    if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+        return RD_AP_MODIFIED;
+
+
+    q = p;                     /* mark start of encrypted stuff */
+
+#ifndef NOENCRYPTION
+    des_pcbc_encrypt((des_cblock *)q,(des_cblock *)q,(long)c_length,schedule,key,DES_DECRYPT);
+#endif
+
+    /* safely get application data length */
+    bcopy((char *) p,(char *)&(m_data->app_length),
+          sizeof(m_data->app_length));
+    if (swap_bytes)
+        swap_u_long(m_data->app_length);
+    p += sizeof(m_data->app_length);    /* skip over */
+
+    if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
+        sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
+        sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
+        > in_length)
+        return RD_AP_MODIFIED;
+
+#ifndef NOENCRYPTION
+    /* we're now at the decrypted application data */
+#endif
+    m_data->app_data = p;
+
+    p += m_data->app_length;
+
+    /* safely get time_5ms */
+    bcopy((char *) p, (char *)&(m_data->time_5ms),
+         sizeof(m_data->time_5ms));
+    /*  don't need to swap-- one byte for now */
+    p += sizeof(m_data->time_5ms);
+
+    /* safely get src address */
+    bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
+    /* don't swap, net order always */
+    p += sizeof(src_addr);
+
+    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
+       return RD_AP_MODIFIED;
+
+    /* safely get time_sec */
+    bcopy((char *) p, (char *)&(m_data->time_sec),
+         sizeof(m_data->time_sec));
+    if (swap_bytes) swap_u_long(m_data->time_sec);
+
+    p += sizeof(m_data->time_sec);
+
+    /* check direction bit is the sign bit */
+    /* For compatibility with broken old code, compares are done in VAX 
+       byte order (LSBFIRST) */ 
+    if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+                          receiver->sin_addr.s_addr)==-1) 
+       /* src < recv */ 
+       m_data->time_sec =  - m_data->time_sec; 
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
+                               receiver->sin_addr.s_addr)==0) 
+       if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+           /* src < recv */
+           m_data->time_sec =  - m_data->time_sec; 
+    /*
+     * all that for one tiny bit!
+     * Heaven help those that talk to themselves.
+     */
+
+    /* check the time integrity of the msg */
+    delta_t = abs((int)((long) local_time.tv_sec
+                       - m_data->time_sec));
+    if (delta_t > CLOCK_SKEW)
+       return RD_AP_TIME;
+    if (krb_debug)
+       printf("\ndelta_t = %d", (int) delta_t);
+
+    /*
+     * caller must check timestamps for proper order and
+     * replays, since server might have multiple clients
+     * each with its own timestamps and we don't assume
+     * tightly synchronized clocks.
+     */
+
+#ifdef notdef
+    bcopy((char *) p,(char *)&cksum,sizeof(cksum));
+    if (swap_bytes) swap_u_long(cksum)
+    /*
+     * calculate the checksum of the length, sequence,
+     * and input data, on the sending byte order!!
+     */
+    calc_cksum = des_quad_cksum(q,NULL,p-q,0,key);
+
+    if (krb_debug)
+       printf("\ncalc_cksum = %u, received cksum = %u",
+              calc_cksum, cksum);
+    if (cksum != calc_cksum)
+       return RD_AP_MODIFIED;
+#endif
+    return RD_AP_OK;        /* OK == 0 */
+}
diff --git a/kerberosIV/krb/rd_req.c b/kerberosIV/krb/rd_req.c
new file mode 100644 (file)
index 0000000..4d28146
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_req.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+
+static struct timeval t_local = { 0, 0 };
+
+/*
+ * Keep the following information around for subsequent calls
+ * to this routine by the same server using the same key.
+ */
+
+static des_key_schedule serv_key;      /* Key sched to decrypt ticket */
+static des_cblock ky;              /* Initialization vector */
+static int st_kvno;            /* version number for this key */
+static char st_rlm[REALM_SZ];  /* server's realm */
+static char st_nam[ANAME_SZ];  /* service name */
+static char st_inst[INST_SZ];  /* server's instance */
+
+/*
+ * This file contains two functions.  krb_set_key() takes a DES
+ * key or password string and returns a DES key (either the original
+ * key, or the password converted into a DES key) and a key schedule
+ * for it.
+ *
+ * krb_rd_req() reads an authentication request and returns information
+ * about the identity of the requestor, or an indication that the
+ * identity information was not authentic.
+ */
+
+/*
+ * krb_set_key() takes as its first argument either a DES key or a
+ * password string.  The "cvt" argument indicates how the first
+ * argument "key" is to be interpreted: if "cvt" is null, "key" is
+ * taken to be a DES key; if "cvt" is non-null, "key" is taken to
+ * be a password string, and is converted into a DES key using
+ * string_to_key().  In either case, the resulting key is returned
+ * in the external static variable "ky".  A key schedule is
+ * generated for "ky" and returned in the external static variable
+ * "serv_key".
+ *
+ * This routine returns the return value of des_key_sched.
+ *
+ * krb_set_key() needs to be in the same .o file as krb_rd_req() so that
+ * the key set by krb_set_key() is available in private storage for
+ * krb_rd_req().
+ */
+
+int
+krb_set_key(key, cvt)
+       char *key;
+       int cvt;
+{
+#ifdef NOENCRYPTION
+    bzero(ky, sizeof(ky));
+    return KSUCCESS;
+#else /* Encrypt */
+    if (cvt)
+        des_string_to_key(key,&ky);
+    else
+        bcopy(key,(char *)ky,8);
+    return(des_key_sched(&ky,serv_key));
+#endif /* NOENCRYPTION */
+}
+
+
+/*
+ * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
+ * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
+ * checks its integrity and returns a judgement as to the requestor's
+ * identity.
+ *
+ * The "authent" argument is a pointer to the received message.
+ * The "service" and "instance" arguments name the receiving server,
+ * and are used to get the service's ticket to decrypt the ticket
+ * in the message, and to compare against the server name inside the
+ * ticket.  "from_addr" is the network address of the host from which
+ * the message was received; this is checked against the network
+ * address in the ticket.  If "from_addr" is zero, the check is not
+ * performed.  "ad" is an AUTH_DAT structure which is
+ * filled in with information about the sender's identity according
+ * to the authenticator and ticket sent in the message.  Finally,
+ * "fn" contains the name of the file containing the server's key.
+ * (If "fn" is NULL, the server's key is assumed to have been set
+ * by krb_set_key().  If "fn" is the null string ("") the default
+ * file KEYFILE, defined in "krb.h", is used.)
+ *
+ * krb_rd_req() returns RD_AP_OK if the authentication information
+ * was genuine, or one of the following error codes (defined in
+ * "krb.h"):
+ *
+ *     RD_AP_VERSION           - wrong protocol version number
+ *     RD_AP_MSG_TYPE          - wrong message type
+ *     RD_AP_UNDEC             - couldn't decipher the message
+ *     RD_AP_INCON             - inconsistencies found
+ *     RD_AP_BADD              - wrong network address
+ *     RD_AP_TIME              - client time (in authenticator)
+ *                               too far off server time
+ *     RD_AP_NYV               - Kerberos time (in ticket) too
+ *                               far off server time
+ *     RD_AP_EXP               - ticket expired
+ *
+ * For the message format, see krb_mk_req().
+ *
+ * Mutual authentication is not implemented.
+ */
+
+int
+krb_rd_req(authent, service, instance, from_addr, ad, fn)
+       register KTEXT authent; /* The received message */
+       char *service;          /* Service name */
+       char *instance;         /* Service instance */
+       int32_t from_addr;      /* Net address of originating host */
+       AUTH_DAT *ad;           /* Structure to be filled in */
+       char *fn;               /* Filename to get keys from */
+{
+    static KTEXT_ST ticket;     /* Temp storage for ticket */
+    static KTEXT tkt = &ticket;
+    static KTEXT_ST req_id_st;  /* Temp storage for authenticator */
+    register KTEXT req_id = &req_id_st;
+
+    char realm[REALM_SZ];      /* Realm of issuing kerberos */
+    static des_key_schedule seskey_sched; /* Key sched for session key */
+    unsigned char skey[KKEY_SZ]; /* Session key from ticket */
+    char sname[SNAME_SZ];      /* Service name from ticket */
+    char iname[INST_SZ];       /* Instance name from ticket */
+    char r_aname[ANAME_SZ];    /* Client name from authenticator */
+    char r_inst[INST_SZ];      /* Client instance from authenticator */
+    char r_realm[REALM_SZ];    /* Client realm from authenticator */
+    unsigned int r_time_ms;     /* Fine time from authenticator */
+    unsigned long r_time_sec;   /* Coarse time from authenticator */
+    register char *ptr;                /* For stepping through */
+    unsigned long delta_t;      /* Time in authenticator - local time */
+    long tkt_age;              /* Age of ticket */
+    static int swap_bytes;     /* Need to swap bytes? */
+    static int mutual;         /* Mutual authentication requested? */
+    static unsigned char s_kvno;/* Version number of the server's key
+                                * Kerberos used to encrypt ticket */
+    int status;
+
+    if (authent->length <= 0)
+       return(RD_AP_MODIFIED);
+
+    ptr = (char *) authent->dat;
+
+    /* get msg version, type and byte order, and server key version */
+
+    /* check version */
+    if (KRB_PROT_VERSION != (unsigned int) *ptr++)
+        return(RD_AP_VERSION);
+
+    /* byte order */
+    swap_bytes = 0;
+    if ((*ptr & 1) != HOST_BYTE_ORDER)
+        swap_bytes++;
+
+    /* check msg type */
+    mutual = 0;
+    switch (*ptr++ & ~1) {
+    case AUTH_MSG_APPL_REQUEST:
+        break;
+    case AUTH_MSG_APPL_REQUEST_MUTUAL:
+        mutual++;
+        break;
+    default:
+        return(RD_AP_MSG_TYPE);
+    }
+
+#ifdef lint
+    /* XXX mutual is set but not used; why??? */
+    /* this is a crock to get lint to shut up */
+    if (mutual)
+        mutual = 0;
+#endif /* lint */
+    s_kvno = *ptr++;           /* get server key version */
+    (void) strcpy(realm,ptr);   /* And the realm of the issuing KDC */
+    ptr += strlen(ptr) + 1;     /* skip the realm "hint" */
+
+    /*
+     * If "fn" is NULL, key info should already be set; don't
+     * bother with ticket file.  Otherwise, check to see if we
+     * already have key info for the given server and key version
+     * (saved in the static st_* variables).  If not, go get it
+     * from the ticket file.  If "fn" is the null string, use the
+     * default ticket file.
+     */
+    if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
+               strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+        if (*fn == 0) fn = KEYFILE;
+        st_kvno = s_kvno;
+#ifndef NOENCRYPTION
+        if (read_service_key(service,instance,realm,(int) s_kvno,
+                            fn,(char *)skey))
+            return(RD_AP_UNDEC);
+        if ((status = krb_set_key((char *)skey,0)))
+           return(status);
+#endif /* !NOENCRYPTION */
+        (void) strcpy(st_rlm,realm);
+        (void) strcpy(st_nam,service);
+        (void) strcpy(st_inst,instance);
+    }
+
+    /* Get ticket from authenticator */
+    tkt->length = (int) *ptr++;
+    if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
+       return(RD_AP_MODIFIED);
+    bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
+
+    if (krb_ap_req_debug)
+        log("ticket->length: %d",tkt->length);
+
+#ifndef NOENCRYPTION
+    /* Decrypt and take apart ticket */
+#endif
+
+    if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm,
+                      &(ad->address),ad->session, &(ad->life),
+                      &(ad->time_sec),sname,iname,&ky,serv_key))
+        return(RD_AP_UNDEC);
+
+    if (krb_ap_req_debug) {
+        log("Ticket Contents.");
+        log(" Aname:   %s.%s",ad->pname,
+            ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+        log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname);
+    }
+
+    /* Extract the authenticator */
+    req_id->length = (int) *(ptr++);
+    if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
+       authent->length)
+       return(RD_AP_MODIFIED);
+    bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
+
+#ifndef NOENCRYPTION
+    /* And decrypt it with the session key from the ticket */
+    if (krb_ap_req_debug) log("About to decrypt authenticator");
+    des_key_sched(&ad->session,seskey_sched);
+    des_pcbc_encrypt((des_cblock *)req_id->dat,(des_cblock *)req_id->dat,
+                 (long) req_id->length, seskey_sched,&ad->session,DES_DECRYPT);
+    if (krb_ap_req_debug) log("Done.");
+#endif /* NOENCRYPTION */
+
+#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
+
+    ptr = (char *) req_id->dat;
+    (void) strcpy(r_aname,ptr);        /* Authentication name */
+    ptr += strlen(r_aname)+1;
+    check_ptr();
+    (void) strcpy(r_inst,ptr); /* Authentication instance */
+    ptr += strlen(r_inst)+1;
+    check_ptr();
+    (void) strcpy(r_realm,ptr);        /* Authentication name */
+    ptr += strlen(r_realm)+1;
+    check_ptr();
+    bcopy(ptr,(char *)&ad->checksum,4);        /* Checksum */
+    ptr += 4;
+    check_ptr();
+    if (swap_bytes) swap_u_long(ad->checksum);
+    r_time_ms = *(ptr++);      /* Time (fine) */
+#ifdef lint
+    /* XXX r_time_ms is set but not used.  why??? */
+    /* this is a crock to get lint to shut up */
+    if (r_time_ms)
+        r_time_ms = 0;
+#endif /* lint */
+    check_ptr();
+    /* assume sizeof(r_time_sec) == 4 ?? */
+    bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
+    if (swap_bytes) swap_u_long(r_time_sec);
+
+    /* Check for authenticity of the request */
+    if (krb_ap_req_debug)
+        log("Pname:   %s %s",ad->pname,r_aname);
+    if (strcmp(ad->pname,r_aname) != 0)
+        return(RD_AP_INCON);
+    if (strcmp(ad->pinst,r_inst) != 0)
+        return(RD_AP_INCON);
+    if (krb_ap_req_debug)
+        log("Realm:   %s %s",ad->prealm,r_realm);
+    if ((strcmp(ad->prealm,r_realm) != 0))
+        return(RD_AP_INCON);
+
+    if (krb_ap_req_debug)
+        log("Address: %d %d",ad->address,from_addr);
+    if (from_addr && (!krb_equiv(ad->address, from_addr)))
+        return(RD_AP_BADD);
+
+    (void) gettimeofday(&t_local,(struct timezone *) 0);
+    delta_t = abs((int)(t_local.tv_sec - r_time_sec));
+    if (delta_t > CLOCK_SKEW) {
+        if (krb_ap_req_debug)
+            log("Time out of range: %d - %d = %d",
+                t_local.tv_sec,r_time_sec,delta_t);
+        return(RD_AP_TIME);
+    }
+
+    /* Now check for expiration of ticket */
+
+    tkt_age = t_local.tv_sec - ad->time_sec;
+    if (krb_ap_req_debug)
+        log("Time: %d Issue Date: %d Diff: %d Life %x",
+            t_local.tv_sec,ad->time_sec,tkt_age,ad->life);
+
+    if (t_local.tv_sec < ad->time_sec) {
+        if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW)
+            return(RD_AP_NYV);
+    }
+    else if (t_local.tv_sec > krb_life_to_time(ad->time_sec, ad->life))
+        return(RD_AP_EXP);
+
+    /* All seems OK */
+    ad->reply.length = 0;
+
+    return(RD_AP_OK);
+}
diff --git a/kerberosIV/krb/rd_safe.c b/kerberosIV/krb/rd_safe.c
new file mode 100644 (file)
index 0000000..aeb829a
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/rd_safe.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+/*
+ * This routine dissects a a Kerberos 'safe msg', checking its
+ * integrity, and returning a pointer to the application data
+ * contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller    Project Athena  MIT/DEC
+ */
+
+#include "krb_locl.h"
+
+/* system include files */
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include "lsb_addr_comp.h"
+
+/* static storage */
+static des_cblock calc_cksum[2];
+static des_cblock big_cksum[2];
+static int swap_bytes;
+static struct timeval local_time;
+static u_int32_t delta_t;
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data".  The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message.  The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+int32_t
+krb_rd_safe(in, in_length, key, sender, receiver, m_data)
+       u_char *in;             /* pointer to the msg received */
+       u_int32_t in_length;    /* length of "in" msg */
+       des_cblock *key;        /* encryption key for seed and ivec */
+       struct sockaddr_in *sender; /* sender's address */
+       struct sockaddr_in *receiver; /* receiver's address -- me */
+       MSG_DAT *m_data;        /* where to put message information */
+{
+    register u_char     *p,*q;
+    static      u_int32_t  src_addr; /* Can't send structs since no
+                                   * guarantees on size */
+    /* Be very conservative */
+    if (sizeof(src_addr) != sizeof(struct in_addr)) {
+        fprintf(stderr,"\n\
+krb_rd_safe protocol err sizeof(src_addr) != sizeof(struct in_addr)");
+        exit(-1);
+    }
+
+    if (gettimeofday(&local_time,(struct timezone *)0))
+        return  -1;
+
+    p = in;                     /* beginning of message */
+    swap_bytes = 0;
+
+    if (*p++ != KRB_PROT_VERSION)       return RD_AP_VERSION;
+    if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
+    if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+
+    q = p;                      /* mark start of cksum stuff */
+
+    /* safely get length */
+    bcopy((char *)p,(char *)&(m_data->app_length),
+          sizeof(m_data->app_length));
+    if (swap_bytes) swap_u_long(m_data->app_length);
+    p += sizeof(m_data->app_length); /* skip over */
+
+    if (m_data->app_length + sizeof(in_length)
+        + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
+        + sizeof(big_cksum) + sizeof(src_addr)
+        + VERSION_SZ + MSG_TYPE_SZ > in_length)
+        return(RD_AP_MODIFIED);
+
+    m_data->app_data = p;       /* we're now at the application data */
+
+    /* skip app data */
+    p += m_data->app_length;
+
+    /* safely get time_5ms */
+    bcopy((char *)p, (char *)&(m_data->time_5ms),
+          sizeof(m_data->time_5ms));
+
+    /* don't need to swap-- one byte for now */
+    p += sizeof(m_data->time_5ms);
+
+    /* safely get src address */
+    bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
+
+    /* don't swap, net order always */
+    p += sizeof(src_addr);
+
+    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
+        return RD_AP_MODIFIED;
+
+    /* safely get time_sec */
+    bcopy((char *)p, (char *)&(m_data->time_sec),
+          sizeof(m_data->time_sec));
+    if (swap_bytes)
+        swap_u_long(m_data->time_sec);
+    p += sizeof(m_data->time_sec);
+
+    /* check direction bit is the sign bit */
+    /* For compatibility with broken old code, compares are done in VAX 
+       byte order (LSBFIRST) */ 
+    if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+                          receiver->sin_addr.s_addr)==-1) 
+       /* src < recv */ 
+       m_data->time_sec =  - m_data->time_sec; 
+    else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
+                               receiver->sin_addr.s_addr)==0) 
+       if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+           /* src < recv */
+           m_data->time_sec =  - m_data->time_sec; 
+
+    /*
+     * All that for one tiny bit!  Heaven help those that talk to
+     * themselves.
+     */
+
+    /* check the time integrity of the msg */
+    delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
+    if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+    /*
+     * caller must check timestamps for proper order and replays, since
+     * server might have multiple clients each with its own timestamps
+     * and we don't assume tightly synchronized clocks.
+     */
+
+    bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
+    if (swap_bytes) swap_u_16(big_cksum);
+
+#ifdef NOENCRYPTION
+    bzero(calc_cksum, sizeof(calc_cksum));
+#else
+    des_quad_cksum((des_cblock *)q,calc_cksum,p-q,2,key);
+#endif
+
+    if (krb_debug)
+        printf("\ncalc_cksum = %u, received cksum = %u",
+               (u_int) calc_cksum[0], (u_int) big_cksum[0]);
+    if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
+        return(RD_AP_MODIFIED);
+
+    return(RD_AP_OK);           /* OK == 0 */
+}
diff --git a/kerberosIV/krb/read_service_key.c b/kerberosIV/krb/read_service_key.c
new file mode 100644 (file)
index 0000000..8c2a8f2
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/read_service_key.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * The private keys for servers on a given host are stored in a
+ * "srvtab" file (typically "/etc/srvtab").  This routine extracts
+ * a given server's key from the file.
+ *
+ * read_service_key() takes the server's name ("service"), "instance",
+ * and "realm" and a key version number "kvno", and looks in the given
+ * "file" for the corresponding entry, and if found, returns the entry's
+ * key field in "key".
+ * 
+ * If "instance" contains the string "*", then it will match
+ * any instance, and the chosen instance will be copied to that
+ * string.  For this reason it is important that the there is enough
+ * space beyond the "*" to receive the entry.
+ *
+ * If "kvno" is 0, it is treated as a wild card and the first
+ * matching entry regardless of the "vno" field is returned.
+ *
+ * This routine returns KSUCCESS on success, otherwise KFAILURE.
+ *
+ * The format of each "srvtab" entry is as follows:
+ *
+ * Size                        Variable                Field in file
+ * ----                        --------                -------------
+ * string              serv                    server name
+ * string              inst                    server instance
+ * string              realm                   server realm
+ * 1 byte              vno                     server key version #
+ * 8 bytes             key                     server's key
+ * ...                 ...                     ...
+ */
+
+
+/*ARGSUSED */
+int
+read_service_key(service, instance, realm, kvno, file, key)
+       char *service;          /* Service Name */
+       char *instance;         /* Instance name or "*" */
+       char *realm;            /* Realm */
+       int kvno;               /* Key version number */
+       char *file;             /* Filename */
+       char *key;              /* Pointer to key to be filled in */
+{
+    char serv[SNAME_SZ];
+    char inst[INST_SZ];
+    char rlm[REALM_SZ];
+    unsigned char vno;          /* Key version number */
+    int wcard;
+
+    int stab, open(const char *, int, ...);
+
+    if ((stab = open(file, 0, 0)) < 0)
+        return(KFAILURE);
+
+    wcard = (instance[0] == '*') && (instance[1] == '\0');
+
+    while (getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
+        (void) getst(stab,inst,INST_SZ); /* Instance */
+        (void) getst(stab,rlm,REALM_SZ); /* Realm */
+        /* Vers number */
+        if (read(stab,(char *)&vno,1) != 1) {
+           close(stab);
+            return(KFAILURE);
+       }
+        /* Key */
+        if (read(stab,key,8) != 8) {
+           close(stab);
+            return(KFAILURE);
+       }
+        /* Is this the right service */
+        if (strcmp(serv,service))
+            continue;
+        /* How about instance */
+        if (!wcard && strcmp(inst,instance))
+            continue;
+        if (wcard)
+            (void) strncpy(instance,inst,INST_SZ);
+        /* Is this the right realm */
+#ifdef ATHENA_COMPAT
+       /* XXX For backward compatibility:  if keyfile says "Athena"
+          and caller wants "ATHENA.MIT.EDU", call it a match */
+        if (strcmp(rlm,realm) &&
+           (strcmp(rlm,"Athena") ||
+            strcmp(realm,"ATHENA.MIT.EDU")))
+           continue;
+#else /* ! ATHENA_COMPAT */
+        if (strcmp(rlm,realm)) 
+           continue;
+#endif /* ATHENA_COMPAT */
+
+        /* How about the key version number */
+        if (kvno && kvno != (int) vno)
+            continue;
+
+        (void) close(stab);
+        return(KSUCCESS);
+    }
+
+    /* Can't find the requested service */
+    (void) close(stab);
+    return(KFAILURE);
+}
diff --git a/kerberosIV/krb/recvauth.c b/kerberosIV/krb/recvauth.c
new file mode 100644 (file)
index 0000000..3a5949e
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/recvauth.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_sendauth.c
+ * be sure to support old versions of krb_sendauth!
+ */
+#define        KRB_SENDAUTH_VERS       "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
+                                             chars */
+
+/*
+ * krb_recvauth() reads (and optionally responds to) a message sent
+ * using krb_sendauth().  The "options" argument is a bit-field of
+ * selected options (see "sendauth.c" for options description).
+ * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
+ * (mutual authentication requested).  The "fd" argument supplies
+ * a file descriptor to read from (and write to, if mutual authenti-
+ * cation is requested).
+ *
+ * Part of the received message will be a Kerberos ticket sent by the
+ * client; this is read into the "ticket" argument.  The "service" and
+ * "instance" arguments supply the server's Kerberos name.  If the
+ * "instance" argument is the string "*", it is treated as a wild card
+ * and filled in during the krb_rd_req() call (see read_service_key()).
+ *
+ * The "faddr" and "laddr" give the sending (client) and receiving
+ * (local server) network addresses.  ("laddr" may be left NULL unless
+ * mutual authentication is requested, in which case it must be set.)
+ *
+ * The authentication information extracted from the message is returned
+ * in "kdata".  The "filename" argument indicates the file where the
+ * server's key can be found.  (It is passed on to krb_rd_req().)  If
+ * left null, the default "/etc/srvtab" will be used.
+ *
+ * If mutual authentication is requested, the session key schedule must
+ * be computed in order to reply; this schedule is returned in the
+ * "schedule" argument.  A string containing the application version
+ * number from the received message is returned in "version", which
+ * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
+ *
+ * See krb_sendauth() for the format of the received client message.
+ *
+ * This routine supports another client format, for backward
+ * compatibility, consisting of:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * string              tmp_buf, tkt_len        length of ticket, in
+ *                                             ascii
+ *
+ * char                        ' ' (space char)        separator
+ *
+ * tkt_len             ticket->dat             the ticket
+ *
+ * This old-style version does not support mutual authentication.
+ *
+ * krb_recvauth() first reads the protocol version string from the
+ * given file descriptor.  If it doesn't match the current protocol
+ * version (KRB_SENDAUTH_VERS), the old-style format is assumed.  In
+ * that case, the string of characters up to the first space is read
+ * and interpreted as the ticket length, then the ticket is read.
+ *
+ * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
+ * next reads the application protocol version string.  Then the
+ * ticket length and ticket itself are read.
+ *
+ * The ticket is decrypted and checked by the call to krb_rd_req().
+ * If no mutual authentication is required, the result of the
+ * krb_rd_req() call is retured by this routine.  If mutual authenti-
+ * cation is required, a message in the following format is returned
+ * on "fd":
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 4 bytes             tkt_len                 length of ticket or -1
+ *                                             if error occurred
+ *
+ * priv_len            tmp_buf                 "private" message created
+ *                                             by krb_mk_priv() which
+ *                                             contains the incremented
+ *                                             checksum sent by the client
+ *                                             encrypted in the session
+ *                                             key.  (This field is not
+ *                                             present in case of error.)
+ *
+ * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
+ * other error code is returned.
+ */
+
+#ifndef max
+#define        max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+int
+krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+            filename, schedule, version)
+       int32_t options;        /* bit-pattern of options */
+       int fd;                 /* file descr. to read from */
+       KTEXT ticket;           /* storage for client's ticket */
+       char *service;          /* service expected */
+       char *instance;         /* inst expected (may be filled in) */
+       struct sockaddr_in *faddr; /* address of foreign host on fd */
+       struct sockaddr_in *laddr; /* local address */
+       AUTH_DAT *kdata;        /* kerberos data (returned) */
+       char *filename;         /* name of file with service keys */
+       struct des_ks_struct *schedule; /* key schedule (return) */
+       char *version;          /* version string (filled in) */
+{
+
+    int i, cc, old_vers = 0;
+    char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
+    char *cp;
+    int rem;
+    long tkt_len, priv_len;
+    u_int32_t cksum;
+    u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+    /* read the protocol version number */
+    if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
+       KRB_SENDAUTH_VLEN)
+           return(errno);
+    krb_vers[KRB_SENDAUTH_VLEN] = '\0';
+
+    /* check version string */
+    if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
+       /* Assume the old version of sendkerberosdata: send ascii
+          length, ' ', and ticket. */
+       if (options & KOPT_DO_MUTUAL)
+           return(KFAILURE);    /* XXX can't do old style with mutual auth */
+       old_vers = 1;
+
+       /* copy what we have read into tmp_buf */
+       (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
+
+       /* search for space, and make it a null */
+       for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
+           if (tmp_buf[i]== ' ') {
+               tmp_buf[i] = '\0';
+               /* point cp to the beginning of the real ticket */
+               cp = (char *) &tmp_buf[i+1];
+               break;
+           }
+
+       if (i == KRB_SENDAUTH_VLEN)
+           /* didn't find the space, keep reading to find it */
+           for (; i<20; i++) {
+               if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
+                   return(KFAILURE);
+               }
+               if (tmp_buf[i] == ' ') {
+                   tmp_buf[i] = '\0';
+                   /* point cp to the beginning of the real ticket */
+                   cp = (char *) &tmp_buf[i+1];
+                   break;
+               }
+           }
+
+       tkt_len = (long) atoi((char *) tmp_buf);
+
+       /* sanity check the length */
+       if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
+           return(KFAILURE);
+
+       if (i < KRB_SENDAUTH_VLEN) {
+           /* since we already got the space, and part of the ticket,
+              we read fewer bytes to get the rest of the ticket */
+           if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
+                            (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+               != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+               return(errno);
+       } else {
+           if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
+               (int) tkt_len)
+               return(errno);
+       }
+       ticket->length = tkt_len;
+       /* copy the ticket into the struct */
+       (void) bcopy(cp, (char *) ticket->dat, ticket->length);
+
+    } else {
+       /* read the application version string */
+       if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+           KRB_SENDAUTH_VLEN)
+           return(errno);
+       version[KRB_SENDAUTH_VLEN] = '\0';
+
+       /* get the length of the ticket */
+       if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+           sizeof(tkt_len))
+           return(errno);
+    
+       /* sanity check */
+       ticket->length = ntohl((unsigned long)tkt_len);
+       if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+           if (options & KOPT_DO_MUTUAL) {
+               rem = KFAILURE;
+               goto mutual_fail;
+           } else
+               return(KFAILURE); /* XXX there may still be junk on the fd? */
+       }
+
+       /* read the ticket */
+       if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+           != ticket->length)
+           return(errno);
+    }
+    /*
+     * now have the ticket.  decrypt it to get the authenticated
+     * data.
+     */
+    rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+                    kdata,filename);
+
+    if (old_vers) return(rem);  /* XXX can't do mutual with old client */
+
+    /* if we are doing mutual auth, compose a response */
+    if (options & KOPT_DO_MUTUAL) {
+       if (rem != KSUCCESS)
+           /* the krb_rd_req failed */
+           goto mutual_fail;
+
+       /* add one to the (formerly) sealed checksum, and re-seal it
+          for return to the client */
+       cksum = kdata->checksum + 1;
+       cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+       des_key_sched(&kdata->session,schedule);
+#endif
+       priv_len = krb_mk_priv((unsigned char *)&cksum,
+                              tmp_buf,
+                              (unsigned long) sizeof(cksum),
+                              schedule,
+                              &kdata->session,
+                              laddr,
+                              faddr);
+       if (priv_len < 0) {
+           /* re-sealing failed; notify the client */
+           rem = KFAILURE;      /* XXX */
+mutual_fail:
+           priv_len = -1;
+           tkt_len = htonl((unsigned long) priv_len);
+           /* a length of -1 is interpreted as an authentication
+              failure by the client */
+           if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+               != sizeof(tkt_len))
+               return(cc);
+           return(rem);
+       } else {
+           /* re-sealing succeeded, send the private message */
+           tkt_len = htonl((unsigned long)priv_len);
+           if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+                != sizeof(tkt_len))
+               return(cc);
+           if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+               != (int) priv_len)
+               return(cc);
+       }
+    }
+    return(rem);
+}
diff --git a/kerberosIV/krb/save_credentials.c b/kerberosIV/krb/save_credentials.c
new file mode 100644 (file)
index 0000000..780f4fc
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/save_credentials.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+/*
+ * This routine takes a ticket and associated info and calls
+ * tf_save_cred() to store them in the ticket cache.  The peer
+ * routine for extracting a ticket and associated info from the
+ * ticket cache is krb_get_cred().  When changes are made to
+ * this routine, the corresponding changes should be made
+ * in krb_get_cred() as well.
+ *
+ * Returns KSUCCESS if all goes well, otherwise an error returned
+ * by the tf_init() or tf_save_cred() routines.
+ */
+
+int
+save_credentials(service, instance, realm, session, lifetime, kvno,
+                ticket, issue_date)
+       char *service;          /* Service name */
+       char *instance;         /* Instance */
+       char *realm;            /* Auth domain */
+       unsigned char *session; /* Session key */
+       int lifetime;           /* Lifetime */
+       int kvno;               /* Key version number */
+       KTEXT ticket;           /* The ticket itself */
+       int32_t issue_date;     /* The issue time */
+{
+    int tf_status;   /* return values of the tf_util calls */
+
+    /* Open and lock the ticket file for writing */
+    if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
+       return(tf_status);
+
+    /* Save credentials by appending to the ticket file */
+    tf_status = tf_save_cred(service, instance, realm, session,
+                            lifetime, kvno, ticket, issue_date);
+    (void) tf_close();
+    return (tf_status);
+}
diff --git a/kerberosIV/krb/send_to_kdc.c b/kerberosIV/krb/send_to_kdc.c
new file mode 100644 (file)
index 0000000..a680819
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/send_to_kdc.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+static int krb_udp_port = 0;
+
+/* CLIENT_KRB_TIMEOUT indicates the time to wait before
+ * retrying a server.  It's defined in "krb.h".
+ */
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};
+static char *prog = "send_to_kdc";
+static send_recv(KTEXT pkt, KTEXT rpkt, int f, struct sockaddr_in *_to, struct hostent *addrs);
+
+/*
+ * This file contains two routines, send_to_kdc() and send_recv().
+ * send_recv() is a static routine used by send_to_kdc().
+ */
+
+/*
+ * send_to_kdc() sends a message to the Kerberos authentication
+ * server(s) in the given realm and returns the reply message.
+ * The "pkt" argument points to the message to be sent to Kerberos;
+ * the "rpkt" argument will be filled in with Kerberos' reply.
+ * The "realm" argument indicates the realm of the Kerberos server(s)
+ * to transact with.  If the realm is null, the local realm is used.
+ *
+ * If more than one Kerberos server is known for a given realm,
+ * different servers will be queried until one of them replies.
+ * Several attempts (retries) are made for each server before
+ * giving up entirely.
+ *
+ * If an answer was received from a Kerberos host, KSUCCESS is
+ * returned.  The following errors can be returned:
+ *
+ * SKDC_CANT    - can't get local realm
+ *              - can't find "kerberos" in /etc/services database
+ *              - can't open socket
+ *              - can't bind socket
+ *              - all ports in use
+ *              - couldn't find any Kerberos host
+ *
+ * SKDC_RETRY   - couldn't get an answer from any Kerberos server,
+ *               after several retries
+ */
+
+int
+send_to_kdc(pkt, rpkt, realm)
+       KTEXT pkt;
+       KTEXT rpkt;
+       char *realm;
+{
+    int i, f;
+    int no_host; /* was a kerberos host found? */
+    int retry;
+    int n_hosts;
+    int retval;
+    struct sockaddr_in to;
+    struct hostent *host, *hostlist;
+    char *cp;
+    char krbhst[MAX_HSTNM];
+    char lrealm[REALM_SZ];
+
+    /*
+     * If "realm" is non-null, use that, otherwise get the
+     * local realm.
+     */
+    if (realm)
+       (void) strcpy(lrealm, realm);
+    else
+       if (krb_get_lrealm(lrealm,1)) {
+           if (krb_debug)
+               fprintf(stderr, "%s: can't get local realm\n", prog);
+           return(SKDC_CANT);
+       }
+    if (krb_debug)
+        printf("lrealm is %s\n", lrealm);
+    if (krb_udp_port == 0) {
+        register struct servent *sp;
+        if ((sp = getservbyname("kerberos","udp")) == 0) {
+            if (krb_debug)
+                fprintf(stderr, "%s: Can't get kerberos/udp service\n",
+                        prog);
+            krb_udp_port = 750; /* Was return(SKDC_CANT); */
+        }
+        else
+           krb_udp_port = sp->s_port;
+        if (krb_debug)
+            printf("krb_udp_port is %d\n", krb_udp_port);
+    }
+    bzero((char *)&to, S_AD_SZ);
+    hostlist = (struct hostent *) malloc(sizeof(struct hostent));
+    if (!hostlist)
+        return (/*errno */SKDC_CANT);
+    if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        if (krb_debug)
+            fprintf(stderr,"%s: Can't open socket\n", prog);
+        return(SKDC_CANT);
+    }
+    /* from now on, exit through rtn label for cleanup */
+
+    no_host = 1;
+    /* get an initial allocation */
+    n_hosts = 0;
+    bzero((char *)&hostlist[n_hosts], sizeof(struct hostent));
+    for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
+        if (krb_debug) {
+            printf("Getting host entry for %s...",krbhst);
+            (void) fflush(stdout);
+        }
+        host = gethostbyname(krbhst);
+        if (krb_debug) {
+            printf("%s.\n",
+                   host ? "Got it" : "Didn't get it");
+            (void) fflush(stdout);
+        }
+        if (!host)
+            continue;
+        no_host = 0;    /* found at least one */
+        n_hosts++;
+        /* preserve host network address to check later
+         * (would be better to preserve *all* addresses,
+         * take care of that later)
+         */
+        hostlist = (struct hostent *)
+            realloc((char *)hostlist,
+                    (unsigned)
+                    sizeof(struct hostent)*(n_hosts+1));
+        if (!hostlist)
+            return /*errno */SKDC_CANT;
+        bcopy((char *)host, (char *)&hostlist[n_hosts-1],
+              sizeof(struct hostent));
+        host = &hostlist[n_hosts-1];
+        cp = malloc((unsigned)host->h_length);
+        if (!cp) {
+            retval = /*errno */SKDC_CANT;
+            goto rtn;
+        }
+        bcopy((char *)host->h_addr, cp, host->h_length);
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+   (or worse) only return one name ... */
+#if defined(h_addr)
+        host->h_addr_list = (char **)malloc(2*sizeof(char *));
+        if (!host->h_addr_list) {
+            retval = /*errno */SKDC_CANT;
+            goto rtn;
+        }
+        host->h_addr_list[1] = NULL;
+#endif /* defined(h_addr) */
+        host->h_addr = cp;
+        bzero((char *)&hostlist[n_hosts],
+              sizeof(struct hostent));
+        to.sin_family = host->h_addrtype;
+        bcopy(host->h_addr, (char *)&to.sin_addr,
+              host->h_length);
+        to.sin_port = krb_udp_port;
+        if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+            retval = KSUCCESS;
+            goto rtn;
+        }
+        if (krb_debug) {
+            printf("Timeout, error, or wrong descriptor\n");
+            (void) fflush(stdout);
+        }
+    }
+    if (no_host) {
+       if (krb_debug)
+           fprintf(stderr, "%s: can't find any Kerberos host.\n",
+                   prog);
+        retval = SKDC_CANT;
+        goto rtn;
+    }
+    /* retry each host in sequence */
+    for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
+        for (host = hostlist; host->h_name != (char *)NULL; host++) {
+            to.sin_family = host->h_addrtype;
+            bcopy(host->h_addr, (char *)&to.sin_addr,
+                  host->h_length);
+            if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+                retval = KSUCCESS;
+                goto rtn;
+            }
+        }
+    }
+    retval = SKDC_RETRY;
+rtn:
+    (void) close(f);
+    if (hostlist) {
+        register struct hostent *hp;
+        for (hp = hostlist; hp->h_name; hp++)
+#if defined(h_addr)
+            if (hp->h_addr_list) {
+#endif /* defined(h_addr) */
+                if (hp->h_addr)
+                    free(hp->h_addr);
+#if defined(h_addr)
+                free((char *)hp->h_addr_list);
+            }
+#endif /* defined(h_addr) */
+        free((char *)hostlist);
+    }
+    return(retval);
+}
+
+/*
+ * try to send out and receive message.
+ * return 1 on success, 0 on failure
+ */
+
+static int
+send_recv(pkt, rpkt, f, _to, addrs)
+       KTEXT pkt;
+       KTEXT rpkt;
+       int f;
+       struct sockaddr_in *_to;
+       struct hostent *addrs;
+{
+    fd_set readfds;
+    register struct hostent *hp;
+    struct sockaddr_in from;
+    int sin_size;
+    int numsent;
+
+    if (krb_debug) {
+        if (_to->sin_family == AF_INET)
+            printf("Sending message to %s...",
+                   inet_ntoa(_to->sin_addr));
+        else
+            printf("Sending message...");
+        (void) fflush(stdout);
+    }
+    if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0, 
+                         (struct sockaddr *)_to,
+                          S_AD_SZ)) != pkt->length) {
+        if (krb_debug)
+            printf("sent only %d/%d\n",numsent, pkt->length);
+        return 0;
+    }
+    if (krb_debug) {
+        printf("Sent\nWaiting for reply...");
+        (void) fflush(stdout);
+    }
+    FD_ZERO(&readfds);
+    FD_SET(f, &readfds);
+    errno = 0;
+    /* select - either recv is ready, or timeout */
+    /* see if timeout or error or wrong descriptor */
+    if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1
+        || !FD_ISSET(f, &readfds)) {
+        if (krb_debug) {
+           long rfds;
+           bcopy(&readfds, &rfds, sizeof(rfds));
+            fprintf(stderr, "select failed: readfds=%lx",
+                    rfds);
+            perror("");
+        }
+        return 0;
+    }
+    sin_size = sizeof(from);
+    if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0,
+                (struct sockaddr *)&from, &sin_size)
+        < 0) {
+        if (krb_debug)
+            perror("recvfrom");
+        return 0;
+    }
+    if (krb_debug) {
+        printf("received packet from %s\n", inet_ntoa(from.sin_addr));
+        fflush(stdout);
+    }
+    for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+        if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr,
+                  hp->h_length)) {
+            if (krb_debug) {
+                printf("Received it\n");
+                (void) fflush(stdout);
+            }
+            return 1;
+        }
+        if (krb_debug)
+            fprintf(stderr,
+                    "packet not from %lx\n",
+                    (long)hp->h_addr);
+    }
+    if (krb_debug)
+        fprintf(stderr, "%s: received packet from wrong host! (%x)\n",
+                "send_to_kdc(send_rcv)", (int)from.sin_addr.s_addr);
+    return 0;
+}
diff --git a/kerberosIV/krb/sendauth.c b/kerberosIV/krb/sendauth.c
new file mode 100644 (file)
index 0000000..3aa157d
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/sendauth.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_recvauth.c
+ */
+#define        KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
+
+
+/*
+ * This file contains two routines: krb_sendauth() and krb_sendsrv().
+ *
+ * krb_sendauth() transmits a ticket over a file descriptor for a
+ * desired service, instance, and realm, doing mutual authentication
+ * with the server if desired.
+ *
+ * krb_sendsvc() sends a service name to a remote knetd server.
+ */
+
+/*
+ * The first argument to krb_sendauth() contains a bitfield of
+ * options (the options are defined in "krb.h"):
+ *
+ * KOPT_DONT_CANON     Don't canonicalize instance as a hostname.
+ *                     (If this option is not chosen, krb_get_phost()
+ *                     is called to canonicalize it.)
+ *
+ * KOPT_DONT_MK_REQ    Don't request server ticket from Kerberos.
+ *                     A ticket must be supplied in the "ticket"
+ *                     argument.
+ *                     (If this option is not chosen, and there
+ *                     is no ticket for the given server in the
+ *                     ticket cache, one will be fetched using
+ *                     krb_mk_req() and returned in "ticket".)
+ *
+ * KOPT_DO_MUTUAL      Do mutual authentication, requiring that the
+ *                     receiving server return the checksum+1 encrypted
+ *                     in the session key.  The mutual authentication
+ *                     is done using krb_mk_priv() on the other side
+ *                     (see "recvauth.c") and krb_rd_priv() on this
+ *                     side.
+ *
+ * The "fd" argument is a file descriptor to write to the remote
+ * server on.  The "ticket" argument is used to store the new ticket
+ * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
+ * chosen, the ticket must be supplied in the "ticket" argument.
+ * The "service", "inst", and "realm" arguments identify the ticket.
+ * If "realm" is null, the local realm is used.
+ *
+ * The following arguments are only needed if the KOPT_DO_MUTUAL option
+ * is chosen:
+ *
+ *   The "checksum" argument is a number that the server will add 1 to
+ *   to authenticate itself back to the client; the "msg_data" argument
+ *   holds the returned mutual-authentication message from the server
+ *   (i.e., the checksum+1); the "cred" structure is used to hold the
+ *   session key of the server, extracted from the ticket file, for use
+ *   in decrypting the mutual authentication message from the server;
+ *   and "schedule" holds the key schedule for that decryption.  The
+ *   the local and server addresses are given in "laddr" and "faddr".
+ *
+ * The application protocol version number (of up to KRB_SENDAUTH_VLEN
+ * characters) is passed in "version".
+ *
+ * If all goes well, KSUCCESS is returned, otherwise some error code.
+ *
+ * The format of the message sent to the server is:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * KRB_SENDAUTH_VLEN   KRB_SENDAUTH_VER        sendauth protocol
+ * bytes                                       version number
+ *
+ * KRB_SENDAUTH_VLEN   version                 application protocol
+ * bytes                                       version number
+ *
+ * 4 bytes             ticket->length          length of ticket
+ *
+ * ticket->length      ticket->dat             ticket itself
+ */
+
+/*
+ * XXX: Note that krb_rd_priv() is coded in such a way that
+ * "msg_data->app_data" will be pointing into "priv_buf", which
+ * will disappear when krb_sendauth() returns.
+ */
+
+int
+krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
+            msg_data, cred, schedule, laddr, faddr, version)
+       int32_t options;        /* bit-pattern of options */
+       int fd;                 /* file descriptor to write onto */
+       KTEXT ticket;           /* where to put ticket (return); or
+                                * supplied in case of KOPT_DONT_MK_REQ */
+       char *service;          /* service name, instance, realm */
+       char *inst;             /* checksum to include in request */
+       char *realm;            /* mutual auth MSG_DAT (return) */
+       u_int32_t checksum;     /* credentials (return) */
+       MSG_DAT *msg_data;      /* key schedule (return) */
+       CREDENTIALS *cred;      /* local address */
+       struct des_ks_struct *schedule;
+       struct sockaddr_in *faddr; /* address of foreign host on fd */
+       struct sockaddr_in *laddr;
+       char *version;          /* version string */
+{
+    int rem, i, cc;
+    char srv_inst[INST_SZ];
+    char krb_realm[REALM_SZ];
+    char buf[BUFSIZ];
+    u_int32_t tkt_len;
+    u_char priv_buf[1024];
+    u_int32_t cksum;
+
+    rem=KSUCCESS;
+
+    /* get current realm if not passed in */
+    if (!realm) {
+       rem = krb_get_lrealm(krb_realm,1);
+       if (rem != KSUCCESS)
+           return(rem);
+       realm = krb_realm;
+    }
+
+    /* copy instance into local storage, canonicalizing if desired */
+    if (options & KOPT_DONT_CANON)
+       (void) strncpy(srv_inst, inst, INST_SZ);
+    else
+       (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
+
+    /* get the ticket if desired */
+    if (!(options & KOPT_DONT_MK_REQ)) {
+       rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
+       if (rem != KSUCCESS)
+           return(rem);
+    }
+
+#ifdef ATHENA_COMPAT
+    /* this is only for compatibility with old servers */
+    if (options & KOPT_DO_OLDSTYLE) {
+       (void) sprintf(buf,"%d ",ticket->length);
+       (void) write(fd, buf, strlen(buf));
+       (void) write(fd, (char *) ticket->dat, ticket->length);
+       return(rem);
+    }
+#endif /* ATHENA_COMPAT */
+    /* if mutual auth, get credentials so we have service session
+       keys for decryption below */
+    if (options & KOPT_DO_MUTUAL)
+       if ((cc = krb_get_cred(service, srv_inst, realm, cred)))
+           return(cc);
+
+    /* zero the buffer */
+    (void) bzero(buf, BUFSIZ);
+
+    /* insert version strings */
+    (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+    (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
+
+    /* increment past vers strings */
+    i = 2*KRB_SENDAUTH_VLEN;
+
+    /* put ticket length into buffer */
+    tkt_len = htonl(ticket->length);
+    (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
+    i += sizeof(tkt_len);
+
+    /* put ticket into buffer */
+    (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
+    i += ticket->length;
+
+    /* write the request to the server */
+    if ((cc = krb_net_write(fd, buf, i)) != i)
+       return(cc);
+
+    /* mutual authentication, if desired */
+    if (options & KOPT_DO_MUTUAL) {
+       /* get the length of the reply */
+       if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
+           sizeof(tkt_len))
+           return(errno);
+       tkt_len = ntohl(tkt_len);
+
+       /* if the length is negative, the server failed to recognize us. */
+       if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf)))
+           return(KFAILURE);    /* XXX */
+       /* read the reply... */
+       if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
+           return(errno);
+
+       /* ...and decrypt it */
+#ifndef NOENCRYPTION
+       des_key_sched(&cred->session,schedule);
+#endif
+       if ((cc = krb_rd_priv(priv_buf, tkt_len, schedule,
+                            &cred->session, faddr, laddr, msg_data)))
+           return(cc);
+
+       /* fetch the (modified) checksum */
+       (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
+                    sizeof(cksum));
+       cksum = ntohl(cksum);
+
+       /* if it doesn't match, fail */
+       if (cksum != checksum + 1)
+           return(KFAILURE);    /* XXX */
+    }
+    return(KSUCCESS);
+}
+
+#ifdef ATHENA_COMPAT
+/*
+ * krb_sendsvc
+ */
+
+int
+krb_sendsvc(fd, service)
+       int fd;
+       char *service;
+{
+    /* write the service name length and then the service name to
+       the fd */
+    u_int32_t serv_length;
+    int cc;
+
+    serv_length = htonl(strlen(service));
+    if ((cc = krb_net_write(fd, (char *) &serv_length,
+       sizeof(serv_length)))
+       != sizeof(serv_length))
+       return(cc);
+    if ((cc = krb_net_write(fd, service, strlen(service)))
+       != strlen(service))
+       return(cc);
+    return(KSUCCESS);
+}
+#endif /* ATHENA_COMPAT */
diff --git a/kerberosIV/krb/shlib_version b/kerberosIV/krb/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/krb/str2key.c b/kerberosIV/krb/str2key.c
new file mode 100644 (file)
index 0000000..471bc5e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/str2key.c,v $
+ *
+ * $Locker:  $
+ */
+
+/*
+ * This defines the Andrew string_to_key function.  It accepts a password
+ * string as input and converts its via a one-way encryption algorithm to a DES
+ * encryption key.  It is compatible with the original Andrew authentication
+ * service password database.
+ */
+
+#include "krb_locl.h"
+
+/*
+EXPORT void afs_string_to_key(char *passwd, char *cell, des_cblock *key);
+*/
+
+static void
+mklower(s)
+       char *s;
+{
+    for (; *s; s++)
+        if ('A' <= *s && *s <= 'Z')
+            *s = *s - 'A' + 'a';
+}
+
+/*
+ * Short passwords, i.e 8 characters or less.
+ */
+static void
+afs_cmu_StringToKey (str, cell, key)
+       char *str;
+       char *cell;
+       des_cblock *key;
+{
+    char  password[8+1];       /* crypt is limited to 8 chars anyway */
+    int   i;
+    int   passlen;
+
+    bzero (key, sizeof(key));
+    bzero(password, sizeof(password));
+
+    strncpy (password, cell, 8);
+    passlen = strlen (str);
+    if (passlen > 8) passlen = 8;
+
+    for (i=0; i<passlen; i++)
+        password[i] = str[i] ^ cell[i];        /* make sure cell is zero padded */
+
+    for (i=0; i<8; i++)
+        if (password[i] == '\0') password[i] = 'X';
+
+    /* crypt only considers the first 8 characters of password but for some
+       reason returns eleven characters of result (plus the two salt chars). */
+    strncpy((void *)key, (char *)crypt(password, "#~") + 2, sizeof(des_cblock));
+
+    /* parity is inserted into the LSB so leftshift each byte up one bit.  This
+       allows ascii characters with a zero MSB to retain as much significance
+       as possible. */
+    {   char *keybytes = (char *)key;
+        unsigned int temp;
+
+        for (i = 0; i < 8; i++) {
+            temp = (unsigned int) keybytes[i];
+            keybytes[i] = (unsigned char) (temp << 1);
+        }
+    }
+    des_fixup_key_parity (key);
+}
+
+#undef  BUFSIZ
+#define        BUFSIZ          512
+
+/*
+ * Long passwords, i.e 9 characters or more.
+*/
+static void
+afs_transarc_StringToKey (str, cell, key)
+       char *str;
+       char *cell;
+       des_cblock *key;
+{
+    des_key_schedule schedule;
+    des_cblock temp_key;
+    des_cblock ivec;
+    char password[BUFSIZ];
+    int  passlen;
+
+    strncpy (password, str, sizeof(password));
+    if ((passlen = strlen (password)) < sizeof(password)-1)
+        strncat (password, cell, sizeof(password)-passlen);
+    if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password);
+
+    bcopy ("kerberos", &ivec, 8);
+    bcopy ("kerberos", &temp_key, 8);
+    des_fixup_key_parity (&temp_key);
+    des_key_sched (&temp_key, schedule);
+    des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
+
+    bcopy (&ivec, &temp_key, 8);
+    des_fixup_key_parity (&temp_key);
+    des_key_sched (&temp_key, schedule);
+    des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
+
+    des_fixup_key_parity (key);
+}
+
+#undef  REALM_SZ
+#define        REALM_SZ        41
+
+void
+afs_string_to_key(str, cell, key)
+       char *str;
+       char *cell;
+       des_cblock *key;
+{
+    char  realm[REALM_SZ];
+    (void)strcpy(realm, cell);
+    (void)mklower(realm);
+
+    if (strlen(str) > 8)
+        afs_transarc_StringToKey (str, realm, key);
+    else
+        afs_cmu_StringToKey (str, realm, key);
+}
diff --git a/kerberosIV/krb/tf_util.3 b/kerberosIV/krb/tf_util.3
new file mode 100644 (file)
index 0000000..0f19e53
--- /dev/null
@@ -0,0 +1,152 @@
+.\" $Source: /home/cvs/src/kerberosIV/krb/Attic/tf_util.3,v $
+.\" $Author: tholo $
+.\" $Header: /home/cvs/src/kerberosIV/krb/Attic/tf_util.3,v 1.1.1.1 1995/12/14 06:52:40 tholo Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \
+\- Routines for manipulating a Kerberos ticket file
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+tf_init(tf_name, rw)
+char *tf_name;
+int rw;
+.PP
+.ft B
+tf_get_pname(pname)
+char *pname;
+.PP
+.ft B
+tf_get_pinst(pinst)
+char *pinst;
+.PP
+.ft B
+tf_get_cred(c)
+CREDENTIALS *c;
+.PP
+.ft B
+tf_close()
+.PP
+.fi
+.SH DESCRIPTION
+This group of routines are provided to manipulate the Kerberos tickets
+file.  A ticket file has the following format:
+.nf
+.in +4
+.sp
+principal's name          (null-terminated string)
+principal's instance      (null-terminated string)
+CREDENTIAL_1
+CREDENTIAL_2
+  ...
+CREDENTIAL_n
+EOF
+.sp
+.in -4
+.LP
+Where "CREDENTIAL_x" consists of the following fixed-length
+fields from the CREDENTIALS structure (defined in <krb.h>):
+.nf
+.sp
+.in +4
+       char            service[ANAME_SZ]
+       char            instance[INST_SZ]
+       char            realm[REALM_SZ]
+       des_cblock      session
+       int             lifetime
+       int             kvno
+       KTEXT_ST        ticket_st
+       long            issue_date
+.in -4
+.sp
+.fi
+.PP
+.I tf_init
+must be called before the other ticket file
+routines.
+It takes the name of the ticket file to use,
+and a read/write flag as arguments.
+It tries to open the ticket file, checks the mode and if
+everything is okay, locks the file.  If it's opened for
+reading, the lock is shared.  If it's opened for writing,
+the lock is exclusive.
+KSUCCESS is returned if all went well, otherwise one of the
+following:
+.nf
+.sp
+NO_TKT_FIL     - file wasn't there
+TKT_FIL_ACC    - file was in wrong mode, etc.
+TKT_FIL_LCK    - couldn't lock the file, even after a retry
+.sp
+.fi
+.PP
+The
+.I tf_get_pname
+reads the principal's name from a ticket file.
+It should only be called after tf_init has been called.  The
+principal's name is filled into the 
+.I pname
+parameter.  If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If the principal's name was null, or EOF was encountered, or the
+name was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+.PP
+The
+.I tf_get_pinst
+reads the principal's instance from a ticket file.
+It should only be called after tf_init and tf_get_pname
+have been called.
+The principal's instance is filled into the 
+.I pinst
+parameter.
+If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If EOF was encountered, or the
+name was longer than INST_SZ, TKT_FIL_FMT is returned.
+Note that, unlike the principal name, the instance name may be null.
+.PP
+The
+.I tf_get_cred
+routine reads a CREDENTIALS record from a ticket file and
+fills in the given structure.
+It should only be called after
+tf_init, tf_get_pname, and tf_get_pinst have been called.
+If all goes well, KSUCCESS is returned.  Possible error codes
+are:
+.nf
+.sp
+TKT_FIL_INI    - tf_init wasn't called first
+TKT_FIL_FMT    - bad format
+EOF            - end of file encountered
+.sp
+.fi
+.PP
+.I tf_close
+closes the ticket file and releases the lock on it.
+.SH "SEE ALSO"
+krb(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The ticket file routines have to be called in a certain order.
+.SH AUTHORS
+Jennifer Steiner, MIT Project Athena
+.br
+Bill Bryant, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1987 Massachusetts Institute of Technology
diff --git a/kerberosIV/krb/tf_util.c b/kerberosIV/krb/tf_util.c
new file mode 100644 (file)
index 0000000..d144242
--- /dev/null
@@ -0,0 +1,590 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/tf_util.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* TKT_SHMEM */
+
+#define TOO_BIG -1
+#define TF_LCK_RETRY ((unsigned)2)     /* seconds to sleep before
+                                        * retry if ticket file is
+                                        * locked */
+
+#ifdef TKT_SHMEM
+static char *krb_shm_addr = 0;
+static char *tmp_shm_addr = 0;
+static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};
+#endif /* TKT_SHMEM */
+
+/*
+ * fd must be initialized to something that won't ever occur as a real
+ * file descriptor. Since open(2) returns only non-negative numbers as
+ * valid file descriptors, and tf_init always stuffs the return value
+ * from open in here even if it is an error flag, we must
+ *     a. Initialize fd to a negative number, to indicate that it is
+ *        not initially valid.
+ *     b. When checking for a valid fd, assume that negative values
+ *        are invalid (ie. when deciding whether tf_init has been
+ *        called.)
+ *     c. In tf_close, be sure it gets reinitialized to a negative
+ *        number. 
+ */
+static  fd = -1;
+static curpos;                         /* Position in tfbfr */
+static lastpos;                        /* End of tfbfr */
+static char tfbfr[BUFSIZ];             /* Buffer for ticket data */
+
+static tf_gets(register char *s, int n), tf_read(register char *s, register int n);
+
+/*
+ * This file contains routines for manipulating the ticket cache file.
+ *
+ * The ticket file is in the following format:
+ *
+ *      principal's name        (null-terminated string)
+ *      principal's instance    (null-terminated string)
+ *      CREDENTIAL_1
+ *      CREDENTIAL_2
+ *      ...
+ *      CREDENTIAL_n
+ *      EOF
+ *
+ *      Where "CREDENTIAL_x" consists of the following fixed-length
+ *      fields from the CREDENTIALS structure (see "krb.h"):
+ *
+ *              char            service[ANAME_SZ]
+ *              char            instance[INST_SZ]
+ *              char            realm[REALM_SZ]
+ *              C_Block         session
+ *              int             lifetime
+ *              int             kvno
+ *              KTEXT_ST        ticket_st
+ *              u_int32_t            issue_date
+ *
+ * Short description of routines:
+ *
+ * tf_init() opens the ticket file and locks it.
+ *
+ * tf_get_pname() returns the principal's name.
+ *
+ * tf_get_pinst() returns the principal's instance (may be null).
+ *
+ * tf_get_cred() returns the next CREDENTIALS record.
+ *
+ * tf_save_cred() appends a new CREDENTIAL record to the ticket file.
+ *
+ * tf_close() closes the ticket file and releases the lock.
+ *
+ * tf_gets() returns the next null-terminated string.  It's an internal
+ * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred().
+ *
+ * tf_read() reads a given number of bytes.  It's an internal routine
+ * used by tf_get_cred().
+ */
+
+/*
+ * tf_init() should be called before the other ticket file routines.
+ * It takes the name of the ticket file to use, "tf_name", and a
+ * read/write flag "rw" as arguments. 
+ *
+ * It tries to open the ticket file, checks the mode, and if everything
+ * is okay, locks the file.  If it's opened for reading, the lock is
+ * shared.  If it's opened for writing, the lock is exclusive. 
+ *
+ * Returns KSUCCESS if all went well, otherwise one of the following: 
+ *
+ * NO_TKT_FIL   - file wasn't there
+ * TKT_FIL_ACC  - file was in wrong mode, etc.
+ * TKT_FIL_LCK  - couldn't lock the file, even after a retry
+ */
+
+int
+tf_init(tf_name, rw)
+       char *tf_name;
+       int rw;
+{
+    int     wflag;
+    uid_t   me, getuid(void);
+    struct stat stat_buf;
+#ifdef TKT_SHMEM
+    char shmidname[MaxPathLen]; 
+    FILE *sfp;
+    int shmid;
+#endif
+
+    switch (rw) {
+    case R_TKT_FIL:
+       wflag = 0;
+       break;
+    case W_TKT_FIL:
+       wflag = 1;
+       break;
+    default:
+       if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");
+       return TKT_FIL_ACC;
+    }
+    if (lstat(tf_name, &stat_buf) < 0)
+       switch (errno) {
+       case ENOENT:
+           return NO_TKT_FIL;
+       default:
+           return TKT_FIL_ACC;
+       }
+    me = getuid();
+    if ((stat_buf.st_uid != me && me != 0) ||
+       ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+       return TKT_FIL_ACC;
+#ifdef TKT_SHMEM
+    (void) strcpy(shmidname, tf_name);
+    (void) strcat(shmidname, ".shm");
+    if (stat(shmidname,&stat_buf) < 0)
+       return(TKT_FIL_ACC);
+    if ((stat_buf.st_uid != me && me != 0) ||
+       ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+       return TKT_FIL_ACC;
+#endif /* TKT_SHMEM */
+
+    /*
+     * If "wflag" is set, open the ticket file in append-writeonly mode
+     * and lock the ticket file in exclusive mode.  If unable to lock
+     * the file, sleep and try again.  If we fail again, return with the
+     * proper error message. 
+     */
+
+    curpos = sizeof(tfbfr);
+
+#ifdef TKT_SHMEM
+    sfp = fopen(shmidname, "r");       /* only need read/write on the
+                                          actual tickets */
+    if (sfp == 0)
+       return TKT_FIL_ACC;
+    shmid = -1;
+    {
+       char buf[BUFSIZ];
+       int val;                        /* useful for debugging fscanf */
+       /* We provide our own buffer here since some STDIO libraries
+          barf on unbuffered input with fscanf() */
+
+       setbuf(sfp, buf);
+       if ((val = fscanf(sfp,"%d",&shmid)) != 1) {
+           (void) fclose(sfp);
+           return TKT_FIL_ACC;
+       }
+       if (shmid < 0) {
+           (void) fclose(sfp);
+           return TKT_FIL_ACC;
+       }
+       (void) fclose(sfp);
+    }
+    /*
+    * global krb_shm_addr is initialized to 0.  Ultrix bombs when you try and
+    * attach the same segment twice so we need this check.
+    */
+    if (!krb_shm_addr) {
+       if ((krb_shm_addr = shmat(shmid,0,0)) == -1){
+               if (krb_debug)
+                   fprintf(stderr,
+                           "cannot attach shared memory for segment %d\n",
+                           shmid);
+               krb_shm_addr = 0;       /* reset so we catch further errors */
+               return TKT_FIL_ACC;
+           }
+    }
+    tmp_shm_addr = krb_shm_addr;
+#endif /* TKT_SHMEM */
+    
+    if (wflag) {
+       fd = open(tf_name, O_RDWR, 0600);
+       if (fd < 0) {
+           return TKT_FIL_ACC;
+       }
+       if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+           sleep(TF_LCK_RETRY);
+           if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+               (void) close(fd);
+               fd = -1;
+               return TKT_FIL_LCK;
+           }
+       }
+       return KSUCCESS;
+    }
+    /*
+     * Otherwise "wflag" is not set and the ticket file should be opened
+     * for read-only operations and locked for shared access. 
+     */
+
+    fd = open(tf_name, O_RDONLY, 0600);
+    if (fd < 0) {
+       return TKT_FIL_ACC;
+    }
+    if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+       sleep(TF_LCK_RETRY);
+       if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+           (void) close(fd);
+           fd = -1;
+           return TKT_FIL_LCK;
+       }
+    }
+    return KSUCCESS;
+}
+
+/*
+ * tf_get_pname() reads the principal's name from the ticket file. It
+ * should only be called after tf_init() has been called.  The
+ * principal's name is filled into the "p" parameter.  If all goes well,
+ * KSUCCESS is returned.  If tf_init() wasn't called, TKT_FIL_INI is
+ * returned.  If the name was null, or EOF was encountered, or the name
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned. 
+ */
+
+int
+tf_get_pname(p)
+       char *p;
+{
+    if (fd < 0) {
+       if (krb_debug)
+           fprintf(stderr, "tf_get_pname called before tf_init.\n");
+       return TKT_FIL_INI;
+    }
+    if (tf_gets(p, ANAME_SZ) < 2)      /* can't be just a null */
+       return TKT_FIL_FMT;
+    return KSUCCESS;
+}
+
+/*
+ * tf_get_pinst() reads the principal's instance from a ticket file.
+ * It should only be called after tf_init() and tf_get_pname() have been
+ * called.  The instance is filled into the "inst" parameter.  If all
+ * goes well, KSUCCESS is returned.  If tf_init() wasn't called,
+ * TKT_FIL_INI is returned.  If EOF was encountered, or the instance
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned.  Note that the
+ * instance may be null. 
+ */
+
+int
+tf_get_pinst(inst)
+       char *inst;
+{
+    if (fd < 0) {
+       if (krb_debug)
+           fprintf(stderr, "tf_get_pinst called before tf_init.\n");
+       return TKT_FIL_INI;
+    }
+    if (tf_gets(inst, INST_SZ) < 1)
+       return TKT_FIL_FMT;
+    return KSUCCESS;
+}
+
+/*
+ * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills
+ * in the given structure "c".  It should only be called after tf_init(),
+ * tf_get_pname(), and tf_get_pinst() have been called. If all goes well,
+ * KSUCCESS is returned.  Possible error codes are: 
+ *
+ * TKT_FIL_INI  - tf_init wasn't called first
+ * TKT_FIL_FMT  - bad format
+ * EOF          - end of file encountered
+ */
+
+int
+tf_get_cred(c)
+       CREDENTIALS *c;
+{
+    KTEXT   ticket = &c->ticket_st;    /* pointer to ticket */
+    int     k_errno;
+
+    if (fd < 0) {
+       if (krb_debug)
+           fprintf(stderr, "tf_get_cred called before tf_init.\n");
+       return TKT_FIL_INI;
+    }
+    if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+       switch (k_errno) {
+       case TOO_BIG:
+       case 1:         /* can't be just a null */
+           tf_close();
+           return TKT_FIL_FMT;
+       case 0:
+           return EOF;
+       }
+    if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
+       switch (k_errno) {
+       case TOO_BIG:
+           return TKT_FIL_FMT;
+       case 0:
+           return EOF;
+       }
+    if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+       switch (k_errno) {
+       case TOO_BIG:
+       case 1:         /* can't be just a null */
+           tf_close();
+           return TKT_FIL_FMT;
+       case 0:
+           return EOF;
+       }
+    if (
+       tf_read((char *) (c->session), DES_KEY_SZ) < 1 ||
+       tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
+       tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 ||
+       tf_read((char *) &(ticket->length), sizeof(ticket->length))
+       < 1 ||
+    /* don't try to read a silly amount into ticket->dat */
+       ticket->length > MAX_KTXT_LEN ||
+       tf_read((char *) (ticket->dat), ticket->length) < 1 ||
+       tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
+       ) {
+       tf_close();
+       return TKT_FIL_FMT;
+    }
+#ifdef TKT_SHMEM
+    bcopy(tmp_shm_addr,c->session,KEY_SZ);
+    tmp_shm_addr += KEY_SZ;
+#endif /* TKT_SHMEM */
+    return KSUCCESS;
+}
+
+/*
+ * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is
+ * not a valid file descriptor, it just returns.  It also clears the
+ * buffer used to read tickets.
+ *
+ * The return value is not defined.
+ */
+
+void
+tf_close()
+{
+    if (!(fd < 0)) {
+#ifdef TKT_SHMEM
+       if (shmdt(krb_shm_addr)) {
+           /* what kind of error? */
+           if (krb_debug)
+               fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno);
+       } else {
+           krb_shm_addr = 0;
+       }
+#endif /* TKT_SHMEM */
+       (void) flock(fd, LOCK_UN);
+       (void) close(fd);
+       fd = -1;                /* see declaration of fd above */
+    }
+    bzero(tfbfr, sizeof(tfbfr));
+}
+
+/*
+ * tf_gets() is an internal routine.  It takes a string "s" and a count
+ * "n", and reads from the file until either it has read "n" characters,
+ * or until it reads a null byte. When finished, what has been read exists
+ * in "s". If it encounters EOF or an error, it closes the ticket file. 
+ *
+ * Possible return values are:
+ *
+ * n            the number of bytes read (including null terminator)
+ *              when all goes well
+ *
+ * 0            end of file or read error
+ *
+ * TOO_BIG      if "count" characters are read and no null is
+ *             encountered. This is an indication that the ticket
+ *             file is seriously ill.
+ */
+
+static int
+tf_gets(s, n)
+       register char *s;
+       int n;
+{
+    register count;
+
+    if (fd < 0) {
+       if (krb_debug)
+           fprintf(stderr, "tf_gets called before tf_init.\n");
+       return TKT_FIL_INI;
+    }
+    for (count = n - 1; count > 0; --count) {
+       if (curpos >= sizeof(tfbfr)) {
+           lastpos = read(fd, tfbfr, sizeof(tfbfr));
+           curpos = 0;
+       }
+       if (curpos == lastpos) {
+           tf_close();
+           return 0;
+       }
+       *s = tfbfr[curpos++];
+       if (*s++ == '\0')
+           return (n - count);
+    }
+    tf_close();
+    return TOO_BIG;
+}
+
+/*
+ * tf_read() is an internal routine.  It takes a string "s" and a count
+ * "n", and reads from the file until "n" bytes have been read.  When
+ * finished, what has been read exists in "s".  If it encounters EOF or
+ * an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n           the number of bytes read when all goes well
+ *
+ * 0           on end of file or read error
+ */
+
+static int
+tf_read(s, n)
+       register char *s;
+       register int n;
+{
+    register count;
+    
+    for (count = n; count > 0; --count) {
+       if (curpos >= sizeof(tfbfr)) {
+           lastpos = read(fd, tfbfr, sizeof(tfbfr));
+           curpos = 0;
+       }
+       if (curpos == lastpos) {
+           tf_close();
+           return 0;
+       }
+       *s++ = tfbfr[curpos++];
+    }
+    return n;
+}
+     
+char   *tkt_string(void);
+
+/*
+ * tf_save_cred() appends an incoming ticket to the end of the ticket
+ * file.  You must call tf_init() before calling tf_save_cred().
+ *
+ * The "service", "instance", and "realm" arguments specify the
+ * server's name; "session" contains the session key to be used with
+ * the ticket; "kvno" is the server key version number in which the
+ * ticket is encrypted, "ticket" contains the actual ticket, and
+ * "issue_date" is the time the ticket was requested (local host's time).
+ *
+ * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't
+ * called previously, and KFAILURE for anything else that went wrong.
+ */
+
+int
+tf_save_cred(service, instance, realm, session,
+            lifetime, kvno, ticket, issue_date)
+       char *service;          /* Service name */
+       char *instance;         /* Instance */
+       char *realm;            /* Auth domain */
+       unsigned char *session; /* Session key */
+       int lifetime;           /* Lifetime */
+       int kvno;               /* Key version number */
+       KTEXT ticket;           /* The ticket itself */
+       u_int32_t issue_date;   /* The issue time */
+{
+
+    off_t   lseek(int, off_t, int);
+    int     count;             /* count for write */
+#ifdef TKT_SHMEM
+    int            *skey_check;
+#endif /* TKT_SHMEM */
+
+    if (fd < 0) {              /* fd is ticket file as set by tf_init */
+         if (krb_debug)
+             fprintf(stderr, "tf_save_cred called before tf_init.\n");
+         return TKT_FIL_INI;
+    }
+    /* Find the end of the ticket file */
+    (void) lseek(fd, 0L, 2);
+#ifdef TKT_SHMEM
+    /* scan to end of existing keys: pick first 'empty' slot.
+       we assume that no real keys will be completely zero (it's a weak
+       key under DES) */
+
+    skey_check = (int *) krb_shm_addr;
+
+    while (*skey_check && *(skey_check+1))
+       skey_check += 2;
+    tmp_shm_addr = (char *)skey_check;
+#endif /* TKT_SHMEM */
+
+    /* Write the ticket and associated data */
+    /* Service */
+    count = strlen(service) + 1;
+    if (write(fd, service, count) != count)
+       goto bad;
+    /* Instance */
+    count = strlen(instance) + 1;
+    if (write(fd, instance, count) != count)
+       goto bad;
+    /* Realm */
+    count = strlen(realm) + 1;
+    if (write(fd, realm, count) != count)
+       goto bad;
+    /* Session key */
+#ifdef TKT_SHMEM
+    bcopy(session,tmp_shm_addr,8);
+    tmp_shm_addr+=8;
+    if (write(fd,krb_dummy_skey,8) != 8)
+       goto bad;
+#else /* ! TKT_SHMEM */
+    if (write(fd, (char *) session, 8) != 8)
+       goto bad;
+#endif /* TKT_SHMEM */
+    /* Lifetime */
+    if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int))
+       goto bad;
+    /* Key vno */
+    if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int))
+       goto bad;
+    /* Tkt length */
+    if (write(fd, (char *) &(ticket->length), sizeof(int)) !=
+       sizeof(int))
+       goto bad;
+    /* Ticket */
+    count = ticket->length;
+    if (write(fd, (char *) (ticket->dat), count) != count)
+       goto bad;
+    /* Issue date */
+    if (write(fd, (char *) &issue_date, sizeof(issue_date))
+       != sizeof(issue_date))
+       goto bad;
+
+    /* Actually, we should check each write for success */
+    return (KSUCCESS);
+bad:
+    return (KFAILURE);
+}
diff --git a/kerberosIV/krb/tkt_string.c b/kerberosIV/krb/tkt_string.c
new file mode 100644 (file)
index 0000000..74e50cf
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * This software may now be redistributed outside the US.
+ *
+ * $Source: /home/cvs/src/kerberosIV/krb/Attic/tkt_string.c,v $
+ *
+ * $Locker:  $
+ */
+
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
+
+#include "krb_locl.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+/*
+ * This routine is used to generate the name of the file that holds
+ * the user's cache of server tickets and associated session keys.
+ *
+ * If it is set, krb_ticket_string contains the ticket file name.
+ * Otherwise, the filename is constructed as follows:
+ *
+ * If it is set, the environment variable "KRBTKFILE" will be used as
+ * the ticket file name.  Otherwise TKT_ROOT (defined in "krb.h") and
+ * the user's uid are concatenated to produce the ticket file name
+ * (e.g., "/tmp/tkt123").  A pointer to the string containing the ticket
+ * file name is returned.
+ */
+
+static char krb_ticket_string[MAXPATHLEN] = "";
+
+char *
+tkt_string()
+{
+    char *env;
+    uid_t getuid(void);
+
+    if (!*krb_ticket_string) {
+        if ((env = getenv("KRBTKFILE"))) {
+           (void) strncpy(krb_ticket_string, env,
+                          sizeof(krb_ticket_string)-1);
+           krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+       } else {
+           /* 32 bits of signed integer will always fit in 11 characters
+            (including the sign), so no need to worry about overflow */
+           (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,(int)getuid());
+        }
+    }
+    return krb_ticket_string;
+}
+
+/*
+ * This routine is used to set the name of the file that holds the user's
+ * cache of server tickets and associated session keys.
+ *
+ * The value passed in is copied into local storage.
+ *
+ * NOTE:  This routine should be called during initialization, before other
+ * Kerberos routines are called; otherwise tkt_string() above may be called
+ * and return an undesired ticket file name until this routine is called.
+ */
+
+void
+krb_set_tkt_string(val)
+       char *val;
+{
+
+    (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1);
+    krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+
+    return;
+}
diff --git a/kerberosIV/ksrvtgt/Makefile b/kerberosIV/ksrvtgt/Makefile
new file mode 100644 (file)
index 0000000..8297993
--- /dev/null
@@ -0,0 +1,10 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $
+
+PROG=  ksrvtgt
+CFLAGS+=-DKERBEROS
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+BINDIR=        /usr/bin
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/ksrvtgt/ksrvtgt.1 b/kerberosIV/ksrvtgt/ksrvtgt.1
new file mode 100644 (file)
index 0000000..89c8cf0
--- /dev/null
@@ -0,0 +1,50 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: ksrvtgt.1,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $
+.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a
+service key
+.SH SYNOPSIS
+.B ksrvtgt
+name instance [[realm] srvtab]
+.SH DESCRIPTION
+.I ksrvtgt
+retrieves a ticket-granting ticket with a lifetime of five (5) minutes
+for the principal
+.I name.instance@realm
+(or 
+.I name.instance@localrealm
+if
+.I realm
+is not supplied on the command line), decrypts the response using
+the service key found in
+.I srvtab
+(or in 
+.B /etc/kerberosIV/srvtab
+if
+.I srvtab
+is not specified on the command line), and stores the ticket in the
+standard ticket cache.
+.PP
+This command is intended primarily for use in shell scripts and other
+batch-type facilities.
+.SH DIAGNOSTICS
+"Generic kerberos failure (kfailure)" can indicate a whole range of
+problems, the most common of which is the inability to read the service
+key file.
+.SH FILES
+.TP 2i
+/etc/kerberosIV/krb.conf
+to get the name of the local realm.
+.TP
+/tmp/tkt[uid]
+The default ticket file.
+.TP
+/etc/kerberosIV/srvtab
+The default service key file.
+.SH SEE ALSO
+kerberos(1), kinit(1), kdestroy(1)
diff --git a/kerberosIV/ksrvtgt/ksrvtgt.c b/kerberosIV/ksrvtgt/ksrvtgt.c
new file mode 100644 (file)
index 0000000..f552fd3
--- /dev/null
@@ -0,0 +1,59 @@
+/*     $Id: ksrvtgt.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $        */
+
+/*-
+ * Copyright 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Get a ticket-granting-ticket given a service key file (srvtab)
+ * The lifetime is the shortest allowed [1 five-minute interval]
+ */
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/param.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+const char rcsid[] =
+    "$Id: ksrvtgt.c,v 1.1.1.1 1995/12/14 06:52:51 tholo Exp $";
+
+main(argc,argv)
+    int argc;
+    char **argv;
+{
+    char realm[REALM_SZ + 1];
+    register int code;
+    char srvtab[MAXPATHLEN + 1];
+
+    bzero(realm, sizeof(realm));
+    bzero(srvtab, sizeof(srvtab));
+
+    if (argc < 3 || argc > 5) {
+       fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n",
+               argv[0]);
+       exit(1);
+    }
+    
+    if (argc == 4)
+       (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1);
+    
+    if (argc == 5) {
+       (void) strncpy(realm, argv[3], sizeof(realm) - 1);
+       (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1);
+    }
+
+    if (srvtab[0] == 0)
+       (void) strcpy(srvtab, KEYFILE);
+
+    if (realm[0] == 0)
+       if (krb_get_lrealm(realm, 1) != KSUCCESS)
+           exit(1);
+
+    code = krb_get_svc_in_tkt(argv[1], argv[2], realm,
+                             "krbtgt", realm, 1, srvtab);
+    if (code)
+       fprintf(stderr, "%s\n", krb_err_txt[code]);
+    exit(code);
+}
diff --git a/kerberosIV/ksrvutil/Makefile b/kerberosIV/ksrvutil/Makefile
new file mode 100644 (file)
index 0000000..4d35102
--- /dev/null
@@ -0,0 +1,23 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $
+
+PROG=  ksrvutil
+.if exists(${.CURDIR}/../kadm/obj)
+CFLAGS+=-I${.CURDIR}/../kadm/obj
+.else
+CFLAGS+=-I${.CURDIR}/../kadm
+.endif
+.if exists(${.CURDIR}/../krb/obj)
+CFLAGS+=-I${.CURDIR}/../krb/obj
+.else
+CFLAGS+=-I${.CURDIR}/../krb
+.endif
+.if exists(${.CURDIR}/../ss/obj)
+CFLAGS+=-I${.CURDIR}/../ss/obj
+.else
+CFLAGS+=-I${.CURDIR}/../ss
+.endif
+LDADD+= -lkadm -lkrb -ldes -lcom_err
+DPADD+=        ${LIBKADM} ${LIBKRB} ${LIBDES} ${LIBCOM_ERR}
+MAN=   ksrvutil.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/ksrvutil/ksrvutil.8 b/kerberosIV/ksrvutil/ksrvutil.8
new file mode 100644 (file)
index 0000000..5bc22df
--- /dev/null
@@ -0,0 +1,92 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: ksrvutil.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $
+.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvutil \- host kerberos keyfile (srvtab) manipulation utility
+.SH SYNOPSIS
+ksrvutil
+.B operation
+[
+.B \-k 
+] [ 
+.B \-i 
+] [ 
+.B \-f filename 
+]
+.SH DESCRIPTION
+.I ksrvutil
+allows a system manager to list or change keys currently in his
+keyfile or to add new keys to the keyfile.
+.PP
+
+Operation must be one of the following:
+.TP 10n
+.I list
+lists the keys in a keyfile showing version number and principal
+name.  If the \-k option is given, keys will also be shown.
+.TP 10n
+.I change
+changes all the keys in the keyfile by using the regular admin
+protocol.  If the \-i flag is given, 
+.I ksrvutil
+will prompt for yes or no before changing each key.  If the \-k
+option is used, the old and new keys will be displayed.
+.TP 10n
+.I add
+allows the user to add a key.
+.I add
+prompts for name, instance, realm, and key version number, asks
+for confirmation, and then asks for a password.  
+.I ksrvutil 
+then converts the password to a key and appends the keyfile with
+the new information.  If the \-k option is used, the key is
+displayed. 
+
+.PP
+In all cases, the default file used is KEY_FILE as defined in
+krb.h unless this is overridden by the \-f option.
+
+.PP
+A good use for
+.I ksrvutil
+would be for adding keys to a keyfile.  A system manager could
+ask a kerberos administrator to create a new service key with 
+.IR kadmin (8)
+and could supply an initial password.  Then, he could use 
+.I ksrvutil
+to add the key to the keyfile and then to change the key so that
+it will be random and unknown to either the system manager or
+the kerberos administrator.
+
+.I ksrvutil
+always makes a backup copy of the keyfile before making any
+changes.  
+
+.SH DIAGNOSTICS
+If 
+.I ksrvutil
+should exit on an error condition at any time during a change or
+add, a copy of the
+original keyfile can be found in 
+.IR filename .old
+where 
+.I filename
+is the name of the keyfile, and a copy of the file with all new
+keys changed or added so far can be found in 
+.IR filename .work.
+The original keyfile is left unmodified until the program exits
+at which point it is removed and replaced it with the workfile.
+Appending the workfile to the backup copy and replacing the
+keyfile with the result should always give a usable keyfile,
+although the resulting keyfile will have some out of date keys
+in it.
+
+.SH SEE ALSO
+kadmin(8), ksrvtgt(1)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/kerberosIV/ksrvutil/ksrvutil.c b/kerberosIV/ksrvutil/ksrvutil.c
new file mode 100644 (file)
index 0000000..96dfb41
--- /dev/null
@@ -0,0 +1,624 @@
+/*     $Id: ksrvutil.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $       */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * list and update contents of srvtab files
+ */
+
+/*
+ * ksrvutil
+ * list and update the contents of srvtab files
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#include <kadm_locl.h>
+#include <sys/param.h>
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else /* NOENCRYPTION */
+#define read_long_pw_string des_read_pw_string
+#endif /* NOENCRYPTION */
+
+#define SRVTAB_MODE 0600       /* rw------- */
+#define PAD "  "
+#define VNO_HEADER "Version"
+#define VNO_FORMAT "%4d   "
+#define KEY_HEADER "       Key       " /* 17 characters long */
+#define PRINC_HEADER "  Principal\n"
+#define PRINC_FORMAT "%s"
+
+static unsigned short
+get_mode(char *filename)
+{
+    struct stat statbuf;
+    unsigned short mode;
+
+    (void) bzero((char *)&statbuf, sizeof(statbuf));
+    
+    if (stat(filename, &statbuf) < 0) 
+       mode = SRVTAB_MODE;
+    else
+       mode = statbuf.st_mode;
+
+    return(mode);
+}
+
+static void
+copy_keyfile(char *progname, char *keyfile, char *backup_keyfile)
+{
+    int keyfile_fd;
+    int backup_keyfile_fd;
+    int keyfile_mode;
+    char buf[BUFSIZ];          /* for copying keyfiles */
+    int rcount;                        /* for copying keyfiles */
+    int try_again;
+    
+    (void) bzero((char *)buf, sizeof(buf));
+    
+    do {
+       try_again = FALSE;
+       if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) {
+           if (errno != ENOENT) {
+               (void)fprintf(stderr, "%s: Unable to read %s: %s\n", progname, 
+                             keyfile, strerror(errno));
+               exit(1);
+           }
+           else {
+               try_again = TRUE;
+               if ((keyfile_fd = 
+                    open(keyfile, 
+                         O_WRONLY | O_TRUNC | O_CREAT, SRVTAB_MODE)) < 0) {
+                   (void) fprintf(stderr, "%s: Unable to create %s: %s\n", 
+                                  progname, keyfile, strerror(errno));
+                   exit(1);
+               }
+               else
+                   if (close(keyfile_fd) < 0) {
+                       (void) fprintf(stderr, "%s: Failure closing %s: %s\n",
+                                      progname, keyfile, strerror(errno));
+                       exit(1);
+                   }
+           }
+       }
+    } while(try_again);
+
+    keyfile_mode = get_mode(keyfile);
+
+    if ((backup_keyfile_fd = 
+        open(backup_keyfile, O_WRONLY | O_TRUNC | O_CREAT, 
+             keyfile_mode)) < 0) {
+       (void) fprintf(stderr, "%s: Unable to write %s: %s\n", progname, 
+                      backup_keyfile, strerror(errno));
+       exit(1);
+    }
+    do {
+       if ((rcount = read(keyfile_fd, (char *)buf, sizeof(buf))) < 0) {
+           (void) fprintf(stderr, "%s: Error reading %s: %s\n", progname,
+                          keyfile, strerror(errno));
+           exit(1);
+       }
+       if (rcount && (write(backup_keyfile_fd, buf, rcount) != rcount)) {
+           (void) fprintf(stderr, "%s: Error writing %s: %s\n", progname,
+                          backup_keyfile, strerror(errno));
+           exit(1);
+       }
+    } while (rcount);
+    if (close(backup_keyfile_fd) < 0) {
+       (void) fprintf(stderr, "%s: Error closing %s: %s\n", progname,
+                      backup_keyfile, strerror(errno));
+       exit(1);
+    }
+    if (close(keyfile_fd) < 0) {
+       (void) fprintf(stderr, "%s: Error closing %s: %s\n", progname,
+                      keyfile, strerror(errno));
+       exit(1);
+    }
+}
+
+static void
+leave(char *str, int x)
+{
+    if (str)
+       (void) fprintf(stderr, "%s\n", str);
+    (void) dest_tkt();
+    exit(x);
+}
+
+static void
+safe_read_stdin(char *prompt, char *buf, int size)
+{
+    (void) printf(prompt);
+    (void) fflush(stdout);
+    (void) bzero(buf, size);
+    if (read(0, buf, size - 1) < 0) {
+       (void) fprintf(stderr, "Failure reading from stdin: %s\n", 
+                      strerror(errno));
+       leave((char *)NULL, 1);
+    }
+    fflush(stdin);
+    buf[strlen(buf)-1] = 0;
+}      
+  
+
+static void
+safe_write(char *progname, char *filename, int fd, char *buf, int len)
+{
+    if (write(fd, buf, len) != len) {
+       (void) fprintf(stderr, "%s: Failure writing to %s: %s\n", progname,
+                      filename, strerror(errno));
+       (void) close(fd);
+       leave("In progress srvtab in this file.", 1);
+    }
+}      
+
+static int
+yn(char *string)
+{
+    char ynbuf[5];
+
+    (void) printf("%s (y,n) [y] ", string);
+    for (;;) {
+       safe_read_stdin("", ynbuf, sizeof(ynbuf));
+       
+       if ((ynbuf[0] == 'n') || (ynbuf[0] == 'N'))
+           return(0);
+       else if ((ynbuf[0] == 'y') || (ynbuf[0] == 'Y') || (ynbuf[0] == 0))
+           return(1);
+       else {
+           (void) printf("Please enter 'y' or 'n': ");
+           fflush(stdout);
+       }
+    }
+}
+
+static void
+append_srvtab(char *progname, char *filename, int fd, char *sname, char *sinst, char *srealm, unsigned char key_vno, unsigned char *key)
+{
+    /* Add one to append null */
+    safe_write(progname, filename, fd, sname, strlen(sname) + 1);
+    safe_write(progname, filename, fd, sinst, strlen(sinst) + 1);
+    safe_write(progname, filename, fd, srealm, strlen(srealm) + 1);
+    safe_write(progname, filename, fd, (char *)&key_vno, 1);
+    safe_write(progname, filename, fd, (char *)key, sizeof(des_cblock));
+    (void) fsync(fd);
+}    
+
+static void
+print_key(unsigned char *key)
+{
+    int i;
+
+    for (i = 0; i < 4; i++)
+       (void) printf("%02x", key[i]);
+    (void) printf(" ");
+    for (i = 4; i < 8; i++)
+       (void) printf("%02x", key[i]);
+}
+
+static void
+print_name(char *name, char *inst, char *realm)
+{
+    (void) printf("%s%s%s%s%s", name, inst[0] ? "." : "", inst,
+                 realm[0] ? "@" : "", realm);
+}
+
+static int
+get_svc_new_key(unsigned char *new_key, char *sname, char *sinst, char *srealm, char *keyfile)
+{
+    int status = KADM_SUCCESS;
+
+    if (((status = krb_get_svc_in_tkt(sname, sinst, srealm, PWSERV_NAME,
+                                     KADM_SINST, 1, keyfile)) == KSUCCESS) &&
+       ((status = kadm_init_link("changepw", KRB_MASTER, srealm)) == 
+        KADM_SUCCESS)) {
+#ifdef NOENCRYPTION
+       (void) bzero((char *) new_key, sizeof(des_cblock));
+       new_key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+       (void) des_new_random_key((des_cblock*)&new_key);
+#endif /* NOENCRYPTION */
+       return(KADM_SUCCESS);
+    }
+    
+    return(status);
+}
+
+static void
+get_key_from_password(des_cblock (*key))
+{
+    char password[MAX_KPW_LEN];        /* storage for the password */
+
+    if (read_long_pw_string(password, sizeof(password)-1, "Password: ", 1))
+       leave("Error reading password.", 1);
+
+#ifdef NOENCRYPTION
+    (void) bzero((char *) key, sizeof(des_cblock));
+    key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+    (void) des_string_to_key(password, key);
+#endif /* NOENCRYPTION */
+    (void) bzero((char *)password, sizeof(password));
+}    
+
+static void
+usage(void)
+{
+    (void) fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] ");
+    (void) fprintf(stderr, "{list | change | add | get}\n");
+    (void) fprintf(stderr, "   -i causes the program to ask for ");
+    (void) fprintf(stderr, "confirmation before changing keys.\n");
+    (void) fprintf(stderr, "   -k causes the key to printed for list or ");
+    (void) fprintf(stderr, "change.\n");
+    exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+    char sname[ANAME_SZ];      /* name of service */
+    char sinst[INST_SZ];       /* instance of service */
+    char srealm[REALM_SZ];     /* realm of service */
+    unsigned char key_vno;     /* key version number */
+    int status;                        /* general purpose error status */
+    des_cblock new_key;
+    des_cblock old_key;
+    char change_tkt[MAXPATHLEN]; /* Ticket to use for key change */
+    char keyfile[MAXPATHLEN];  /* Original keyfile */
+    char work_keyfile[MAXPATHLEN]; /* Working copy of keyfile */
+    char backup_keyfile[MAXPATHLEN]; /* Backup copy of keyfile */
+    unsigned short keyfile_mode; /* Protections on keyfile */
+    int work_keyfile_fd = -1;  /* Initialize so that */
+    int backup_keyfile_fd = -1;        /* compiler doesn't complain */
+    char local_realm[REALM_SZ];        /* local kerberos realm */
+    int i;
+    int interactive = FALSE;
+    int list = FALSE;
+    int change = FALSE;
+    int add = FALSE;
+    int get = FALSE;
+    int key = FALSE;           /* do we show keys? */
+    int arg_entered = FALSE;
+    int change_this_key = FALSE;
+    char databuf[BUFSIZ];
+    int first_printed = FALSE; /* have we printed the first item? */
+    
+    (void) bzero((char *)sname, sizeof(sname));
+    (void) bzero((char *)sinst, sizeof(sinst));
+    (void) bzero((char *)srealm, sizeof(srealm));
+    
+    (void) bzero((char *)change_tkt, sizeof(change_tkt));
+    (void) bzero((char *)keyfile, sizeof(keyfile));
+    (void) bzero((char *)work_keyfile, sizeof(work_keyfile));
+    (void) bzero((char *)backup_keyfile, sizeof(backup_keyfile));
+    (void) bzero((char *)local_realm, sizeof(local_realm));
+    
+    (void) sprintf(change_tkt, "/tmp/tkt_ksrvutil.%d", (int)getpid());
+    krb_set_tkt_string(change_tkt);
+
+    /* This is used only as a default for adding keys */
+    if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
+       (void) strcpy(local_realm, KRB_REALM);
+    
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-i") == 0) 
+           interactive++;
+       else if (strcmp(argv[i], "-k") == 0) 
+           key++;
+       else if (strcmp(argv[i], "list") == 0) {
+           if (arg_entered)
+               usage();
+           else {
+               arg_entered++;
+               list++;
+           }
+       }
+       else if (strcmp(argv[i], "change") == 0) {
+           if (arg_entered)
+               usage();
+           else {
+               arg_entered++;
+               change++;
+           }
+       }
+       else if (strcmp(argv[i], "add") == 0) {
+           if (arg_entered)
+               usage();
+           else {
+               arg_entered++;
+               add++;
+           }
+       }
+       else if (strcmp(argv[i], "get") == 0) {
+           if (arg_entered)
+               usage();
+           else {
+               arg_entered++;
+               get++;
+           }
+       }
+       else if (strcmp(argv[i], "-f") == 0) {
+           if (++i == argc)
+               usage();
+           else
+               (void) strcpy(keyfile, argv[i]);
+       }
+       else
+           usage();
+    }
+    
+    if (!arg_entered)
+       usage();
+
+    if (!keyfile[0])
+       (void) strcpy(keyfile, KEYFILE);
+    
+    (void) strcpy(work_keyfile, keyfile);
+    (void) strcpy(backup_keyfile, keyfile);
+    
+    if (change || add || get) {
+       (void) strcat(work_keyfile, ".work");
+       (void) strcat(backup_keyfile, ".old");
+       
+       copy_keyfile(argv[0], keyfile, backup_keyfile);
+    }
+    
+    if (add || get)
+       copy_keyfile(argv[0], backup_keyfile, work_keyfile);
+
+    keyfile_mode = get_mode(keyfile);
+
+    if (change || list) {
+       if ((backup_keyfile_fd = open(backup_keyfile, O_RDONLY, 0)) < 0) {
+           (void) fprintf(stderr, "%s: Unable to read %s: %s\n", argv[0],
+                          backup_keyfile, strerror(errno));
+           exit(1);
+       }
+    }
+
+    if (change) {
+       if ((work_keyfile_fd = 
+            open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC, 
+                 SRVTAB_MODE)) < 0) {
+           (void) fprintf(stderr, "%s: Unable to write %s: %s\n", argv[0],
+                          work_keyfile, strerror(errno));
+           exit(1);
+       }
+    }
+    else if (add || get) {
+       if ((work_keyfile_fd =
+            open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0) {
+           (void) fprintf(stderr, "%s: Unable to open %s for append: %s\n",
+                          argv[0], work_keyfile, strerror(errno));
+           exit(1);
+       }
+    }
+    
+    if (change || list) {
+       while ((getst(backup_keyfile_fd, sname, SNAME_SZ) > 0) &&
+              (getst(backup_keyfile_fd, sinst, INST_SZ) > 0) &&
+              (getst(backup_keyfile_fd, srealm, REALM_SZ) > 0) &&
+              (read(backup_keyfile_fd, &key_vno, 1) > 0) &&
+              (read(backup_keyfile_fd,(char *)old_key,sizeof(old_key)) > 0)) {
+           if (list) {
+               if (!first_printed) {
+                   (void) printf(VNO_HEADER);
+                   (void) printf(PAD);
+                   if (key) {
+                       (void) printf(KEY_HEADER);
+                       (void) printf(PAD);
+                   }
+                   (void) printf(PRINC_HEADER);
+                   first_printed = 1;
+               }
+               (void) printf(VNO_FORMAT, key_vno);
+               (void) printf(PAD);
+               if (key) {
+                   print_key(old_key);
+                   (void) printf(PAD);
+               }
+               print_name(sname, sinst, srealm);
+               (void) printf("\n");
+           }
+           else if (change) {
+               (void) printf("\nPrincipal: ");
+               print_name(sname, sinst, srealm);
+               (void) printf("; version %d\n", key_vno);
+               if (interactive)
+                   change_this_key = yn("Change this key?");
+               else if (change)
+                   change_this_key = 1;
+               else
+                   change_this_key = 0;
+               
+               if (change_this_key)
+                   (void) printf("Changing to version %d.\n", key_vno + 1);
+               else if (change)
+                   (void) printf("Not changing this key.\n");
+               
+               if (change_this_key) {
+                   /* Initialize non shared random sequence old key. */
+                   des_init_random_number_generator(&old_key);
+                   
+                   /* 
+                    * Pick a new key and determine whether or not
+                    * it is safe to change
+                    */
+                   if ((status = 
+                        get_svc_new_key(new_key, sname, sinst, 
+                                        srealm, keyfile)) == KADM_SUCCESS)
+                       key_vno++;
+                   else {
+                       (void) bcopy(old_key, new_key, sizeof(new_key));
+                       (void) fprintf(stderr, "%s: Key NOT changed: %s\n",
+                                      argv[0], krb_err_txt[status]);
+                       change_this_key = FALSE;
+                   }
+               }
+               else 
+                   (void) bcopy(old_key, new_key, sizeof(new_key));
+               append_srvtab(argv[0], work_keyfile, work_keyfile_fd, 
+                             sname, sinst, srealm, key_vno, new_key);
+               if (key && change_this_key) {
+                   (void) printf("Old key: ");
+                   print_key(old_key);
+                   (void) printf("; new key: ");
+                   print_key(new_key);
+                   (void) printf("\n");
+               }
+               if (change_this_key) {
+                   if ((status = kadm_change_pw(new_key)) == KADM_SUCCESS) {
+                       (void) printf("Key changed.\n");
+                       (void) dest_tkt();
+                   }
+                   else {
+                       com_err(argv[0], status, 
+                               " attempting to change password.");
+                       (void) dest_tkt();
+                       /* XXX This knows the format of a keyfile */
+                       if (lseek(work_keyfile_fd, -9, SEEK_CUR) >= 0) {
+                           key_vno--;
+                           safe_write(argv[0], work_keyfile,
+                                      work_keyfile_fd, (char *)&key_vno, 1);
+                           safe_write(argv[0], work_keyfile, work_keyfile_fd,
+                                      (char *)old_key, sizeof(des_cblock));
+                           (void) fsync(work_keyfile_fd);
+                           (void) fprintf(stderr,"Key NOT changed.\n");
+                       }
+                       else {
+                           (void)fprintf(stderr, 
+                                         "%s: Unable to revert keyfile: %s\n",
+                                         argv[0], strerror(errno));
+                           leave("", 1);
+                       }
+                   }
+               }
+           }
+           bzero((char *)old_key, sizeof(des_cblock));
+           bzero((char *)new_key, sizeof(des_cblock));
+       }
+    }
+    else if (add) {
+       do {
+           do {
+               safe_read_stdin("Name: ", databuf, sizeof(databuf));
+               (void) strncpy(sname, databuf, sizeof(sname) - 1);
+               safe_read_stdin("Instance: ", databuf, sizeof(databuf));
+               (void) strncpy(sinst, databuf, sizeof(sinst) - 1);
+               safe_read_stdin("Realm: ", databuf, sizeof(databuf));
+               (void) strncpy(srealm, databuf, sizeof(srealm) - 1);
+               safe_read_stdin("Version number: ", databuf, sizeof(databuf));
+               key_vno = atoi(databuf);
+               if (!srealm[0])
+                   (void) strcpy(srealm, local_realm);
+               (void) printf("New principal: ");
+               print_name(sname, sinst, srealm);
+               (void) printf("; version %d\n", key_vno);
+           } while (!yn("Is this correct?"));
+           get_key_from_password(&new_key);
+           if (key) {
+               (void) printf("Key: ");
+               print_key(new_key);
+               (void) printf("\n");
+           }
+           append_srvtab(argv[0], work_keyfile, work_keyfile_fd, 
+                         sname, sinst, srealm, key_vno, new_key);
+           (void) printf("Key successfully added.\n");
+       } while (yn("Would you like to add another key?"));
+    }
+    else if (get) {
+        ksrvutil_get();
+    }
+
+    if (change || list) 
+       if (close(backup_keyfile_fd) < 0) {
+           (void) fprintf(stderr, "%s: Failure closing %s: %s\n",
+                          argv[0], backup_keyfile, strerror(errno));
+           (void) fprintf(stderr, "continuing...\n");
+       }
+    
+    if (change || add || get) {
+       if (close(work_keyfile_fd) < 0) {
+           (void) fprintf(stderr, "%s: Failure closing %s: %s\n",
+                          argv[0], work_keyfile, strerror(errno));
+           exit(1);
+       }
+       if (rename(work_keyfile, keyfile) < 0) {
+           (void) fprintf(stderr, "%s: Failure renaming %s to %s: %s\n",
+                          argv[0], work_keyfile, keyfile, 
+                          strerror(errno));
+           exit(1);
+       }
+       (void) chmod(backup_keyfile, keyfile_mode);
+       (void) chmod(keyfile, keyfile_mode);
+       (void) printf("Old keyfile in %s.\n", backup_keyfile);
+    }
+
+    exit(0);
+}
+
+ksrvutil_get()
+{
+  char sname[ANAME_SZ];                /* name of service */
+  char sinst[INST_SZ];         /* instance of service */
+  char srealm[REALM_SZ];       /* realm of service */
+  char databuf[BUFSIZ];
+  char local_realm[REALM_SZ];  /* local kerberos realm */
+  char local_hostname[100];
+
+  if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
+    strcpy(local_realm, KRB_REALM);
+  gethostname(local_hostname, sizeof(local_hostname));
+  strcpy(local_hostname, krb_get_phost(local_hostname));
+  do {
+    do {
+      safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf));
+      if (databuf[0])
+       strncpy(sname, databuf, sizeof(sname) - 1);
+      else
+       strcpy(sname, "rcmd");
+
+      safe_read_stdin("Instance [hostname]: ", databuf, sizeof(databuf));
+      if (databuf[0])
+       strncpy(sinst, databuf, sizeof(sinst) - 1);
+      else
+       strcpy(sinst, local_hostname);
+
+      safe_read_stdin("Realm [localrealm]: ", databuf, sizeof(databuf));
+      if (databuf[0])
+       strncpy(srealm, databuf, sizeof(srealm) - 1);
+      else
+       strcpy(srealm, local_realm);
+
+      printf("New principal: ");
+      print_name(sname, sinst, srealm);
+    } while (!yn("Is this correct?"));
+    printf("NOT adding anything!!! Key successfully added.\n");
+  } while (yn("Would you like to add another key?"));
+}
diff --git a/kerberosIV/kstash/Makefile b/kerberosIV/kstash/Makefile
new file mode 100644 (file)
index 0000000..6d26029
--- /dev/null
@@ -0,0 +1,9 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+
+PROG=  kstash
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes 
+MAN=   kstash.8
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/kstash/kstash.8 b/kerberosIV/kstash/kstash.8
new file mode 100644 (file)
index 0000000..60a46fe
--- /dev/null
@@ -0,0 +1,40 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kstash.8,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $
+.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kstash \- stash Kerberos key distribution center database master key
+.SH SYNOPSIS
+kstash
+.SH DESCRIPTION
+.I kstash
+saves the Kerberos key distribution center (KDC) database master key in
+the master key cache file.
+.PP
+The user is prompted to enter the key, to verify the authenticity of the
+key and the authorization to store the key in the file.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.TP
+"kstash: Unable to open master key file"
+The attempt to open the cache file for writing failed (probably due to a
+system or access permission error).
+.TP
+"kstash: Write I/O error on master key file"
+The 
+.BR write (2)
+system call returned an error while
+.I kstash
+was attempting to write the key to the file.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/kerberosIV/kstash/kstash.c b/kerberosIV/kstash/kstash.c
new file mode 100644 (file)
index 0000000..c9c2df9
--- /dev/null
@@ -0,0 +1,73 @@
+/*     $Id: kstash.c,v 1.1.1.1 1995/12/14 06:52:41 tholo Exp $ */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <adm_locl.h>
+
+/* change this later, but krblib_dbm needs it for now */
+char   *progname;
+
+static des_cblock master_key;
+static des_key_schedule master_key_schedule;
+static int kfile;
+
+static void 
+clear_secrets(void)
+{
+    bzero(master_key_schedule, sizeof(master_key_schedule));
+    bzero(master_key, sizeof(master_key));
+}
+
+int
+main(int argc, char **argv)
+{
+    long    n;
+    if ((n = kerb_init())) {
+       fprintf(stderr, "Kerberos db and cache init failed = %ld\n", n);
+       exit(1);
+    }
+
+    if (kdb_get_master_key (TRUE, &master_key, master_key_schedule) != 0) {
+      fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]);
+      fflush (stderr);
+      clear_secrets();
+      exit (-1);
+    }
+
+    if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
+      clear_secrets();
+      exit (-1);
+    }
+
+    kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600);
+    if (kfile < 0) {
+       clear_secrets();
+       fprintf(stderr, "\n\07\07%s: Unable to open master key file\n",
+               argv[0]);
+       exit(1);
+    }
+    if (write(kfile, (char *) master_key, 8) < 0) {
+       clear_secrets();
+       fprintf(stderr, "\n%s: Write I/O error on master key file\n",
+               argv[0]);
+       exit(1);
+    }
+    (void) close(kfile);
+    clear_secrets();
+    exit(0);
+}
diff --git a/kerberosIV/make_keypair/Makefile b/kerberosIV/make_keypair/Makefile
new file mode 100644 (file)
index 0000000..a6de8e3
--- /dev/null
@@ -0,0 +1,10 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $
+
+PROG=  make_keypair
+MAN=   make_keypair.8
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../register
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/make_keypair/make_keypair.8 b/kerberosIV/make_keypair/make_keypair.8
new file mode 100644 (file)
index 0000000..6b39417
--- /dev/null
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1988, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    from @(#)make_keypair.8 8.2 (Berkeley) 12/11/93
+.\"    $Id: make_keypair.8,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $
+.\"
+.Dd December 11, 1993
+.Dt MAKE_KEYPAIR 8
+.Os
+.Sh NAME
+.Nm make_keypair
+.Nd generate Kerberos host key pair
+.Sh SYNOPSIS
+.Nm make_keypair
+.Ar hostname
+.Op Ar hostname ...
+.Sh DESCRIPTION
+The
+.Nm make_keypair
+command
+is used to create pairs of
+.Tn DES
+keys for
+each
+.Ar hostname .
+The keys are used by privileged programs such as
+.Xr register 1
+to make remote updates to the Kerberos database without
+having to have first acquired a Kerberos ticket granting ticket
+.Pq Tn TGT .
+The keys created by
+.Nm make_keypair
+are placed (by hand) in the filesystems of the
+kerberos server in
+.Pa /etc/kerberosIV/register_keys ,
+and in the root directory of the clients.
+For example, the file
+.Pa /.update.key128.32.130.3
+would
+contain a copy of the key of the client with
+IP address 128.32.130.3.
+These keys provide a shared secret which may be used to establish
+a secure channel between the client hosts and the Kerberos server.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keysxx -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/register_keys
+server's key storage directory
+.El
+.Sh SEE ALSO
+.Xr register 1 ,
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh HISTORY
+The
+.Nm make_keypair
+utility first appeared in 4.4BSD.
diff --git a/kerberosIV/make_keypair/make_keypair.c b/kerberosIV/make_keypair/make_keypair.c
new file mode 100644 (file)
index 0000000..d2dc124
--- /dev/null
@@ -0,0 +1,132 @@
+/*     $Id: make_keypair.c,v 1.1.1.1 1995/12/14 06:52:53 tholo Exp $   */
+
+/*-
+ * Copyright (c) 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)make_keypair.c     8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <strings.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+extern void herror();
+void make_key(), usage();
+
+main(argc, argv)
+       int     argc;
+       char    **argv;
+{
+       struct hostent  *hp;
+       char            *addr;
+       int             i;
+       struct sockaddr_in      sin;
+
+       if (argc != 2) {
+               usage(argv[0]);
+               exit(1);
+       }
+
+       if ((hp = gethostbyname(argv[1])) == NULL) {
+               herror(argv[1]);
+               exit(1);
+       }
+
+       for (i = 0; addr = hp->h_addr_list[i]; i++) {
+               addr = hp->h_addr_list[i];
+               bcopy(addr, &sin.sin_addr, hp->h_length);
+
+               printf("Making key for host %s (%s)\n",
+                       argv[1], inet_ntoa(sin.sin_addr));
+               make_key(sin.sin_addr);
+       }
+       printf("==========\n");
+       printf("One copy of the each key should be put in %s on the\n",
+               SERVER_KEYDIR);
+       printf("Kerberos server machine (mode 600, owner root).\n");
+       printf("Another copy of each key should be put on the named\n");
+       printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n",
+               CLIENT_KEYFILE);
+       printf("where the X's refer to digits of the host's inet address.\n");
+       (void)fflush(stdout);
+       exit(0);
+}
+
+void
+make_key(addr)
+       struct in_addr  addr;
+{
+       struct keyfile_data     kfile;
+       char            namebuf[255];
+       int             fd;
+
+       (void)sprintf(namebuf, ".%s%s",
+               CLIENT_KEYFILE,
+               inet_ntoa(addr));
+       fd = open(namebuf, O_WRONLY|O_CREAT, 0600);
+       if (fd < 0) {
+               perror("open");
+               exit(1);
+       }
+       random_key(kfile.kf_key);
+       printf("writing to file -> %s ...", namebuf);
+       if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) {
+               fprintf(stderr, "error writing file %s\n", namebuf);
+       }
+       printf("done.\n");
+       (void)close(fd);
+       return;
+}
+
+void
+usage(name)
+       char    *name;
+{
+       fprintf(stderr, "usage: %s host\n", name);
+}
diff --git a/kerberosIV/man/Makefile b/kerberosIV/man/Makefile
new file mode 100644 (file)
index 0000000..57197dc
--- /dev/null
@@ -0,0 +1,6 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+
+MAN=   kerberos.1 krb.conf.5 krb.equiv.5 krb.realms.5
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/man/kerberos.1 b/kerberosIV/man/kerberos.1
new file mode 100644 (file)
index 0000000..55be387
--- /dev/null
@@ -0,0 +1,258 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: kerberos.1,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+.TH KERBEROS 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kerberos \- introduction to the Kerberos system
+
+.SH DESCRIPTION
+The
+Kerberos
+system authenticates
+individual users in a network environment.
+After authenticating yourself to
+Kerberos,
+you can use network utilities such as
+.IR rlogin ,
+.IR rcp ,
+and
+.IR rsh
+without
+having to present passwords to remote hosts and without having to bother
+with
+.I \.rhosts
+files.
+Note that these utilities will work without passwords only if
+the remote machines you deal with
+support the
+Kerberos
+system.
+All Athena timesharing machines and public workstations support
+Kerberos.
+.PP
+Before you can use
+Kerberos,
+you must register as an Athena user,
+and you must make sure you have been added to
+the
+Kerberos
+database.
+You can use the
+.I kinit
+command to find out.
+This command
+tries to log you into the
+Kerberos
+system.
+.I kinit
+will prompt you for a username and password.
+Enter your username and password.
+If the utility lets you login without giving you a message,
+you have already been registered.
+.PP
+If you enter your username and
+.I kinit
+responds with this message:
+.nf
+
+Principal unknown (kerberos)
+
+.fi
+you haven't been registered as a
+Kerberos
+user.
+See your system administrator.
+.PP
+A Kerberos name contains three parts.
+The first is the
+.I principal name,
+which is usually a user's or service's name.
+The second is the
+.I instance,
+which in the case of a user is usually null.
+Some users may have privileged instances, however,
+such as ``root'' or ``admin''.
+In the case of a service, the instance is the
+name of the machine on which it runs; i.e. there
+can be an
+.I rlogin
+service running on the machine ABC, which
+is different from the rlogin service running on
+the machine XYZ.
+The third part of a Kerberos name
+is the
+.I realm.
+The realm corresponds to the Kerberos service providing
+authentication for the principal.
+For example, at MIT there is a Kerberos running at the
+Laboratory for Computer Science and one running at
+Project Athena.
+.PP
+When writing a Kerberos name, the principal name is
+separated from the instance (if not null) by a period,
+and the realm (if not the local realm) follows, preceded by
+an ``@'' sign.
+The following are examples of valid Kerberos names:
+.sp
+.nf
+.in +8
+billb
+jis.admin
+srz@lcs.mit.edu
+treese.root@athena.mit.edu
+.in -8
+.fi
+.PP
+When you authenticate yourself with
+Kerberos,
+through either the workstation
+.I toehold
+system or the
+.I kinit
+command,
+Kerberos
+gives you an initial
+Kerberos
+.IR ticket .
+(A
+Kerberos
+ticket
+is an encrypted protocol message that provides authentication.)
+Kerberos
+uses this ticket for network utilities
+such as
+.I rlogin
+and
+.IR rcp .
+The ticket transactions are done transparently,
+so you don't have to worry about their management.
+.PP
+Note, however, that tickets expire.
+Privileged tickets, such as root instance tickets,
+expire in a few minutes, while tickets that carry more ordinary
+privileges may be good for several hours or a day, depending on the
+installation's policy.
+If your login session extends beyond the time limit,
+you will have to re-authenticate yourself to
+Kerberos
+to get new tickets.
+Use the
+.IR kinit
+command to re-authenticate yourself.
+.PP
+If you use the
+.I kinit
+command to get your tickets,
+make sure you use the
+.I kdestroy
+command
+to destroy your tickets before you end your login session.
+You should probably put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+For more information about the
+.I kinit
+and
+.I kdestroy
+commands,
+see the
+.I kinit(1)
+and
+.I kdestroy(1)
+manual pages.
+.PP
+Currently,
+Kerberos
+supports the following network services:
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp .
+Other services are being worked on,
+such as the
+.IR pop
+mail system and NFS (network file system),
+but are not yet available.
+
+.SH "SEE ALSO"
+kdestroy(1), kinit(1), klist(1), kpasswd(1), des_crypt(3), kerberos(3),
+kadmin(8)
+.SH BUGS
+Kerberos
+will not do authentication forwarding.
+In other words,
+if you use
+.I rlogin
+to login to a remote host,
+you cannot use
+Kerberos
+services from that host
+until you authenticate yourself explicitly on that host.
+Although you may need to authenticate yourself on the remote
+host,
+be aware that when you do so,
+.I rlogin
+sends your password across the network in clear text.
+
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+
+The following people helped out on various aspects of the system:
+
+Jeff Schiller designed and wrote the administration server and its
+user interface, kadmin.
+He also wrote the dbm version of the database management system.
+
+Mark Colan developed the
+Kerberos
+versions of
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp ,
+as well as contributing work on the servers.
+
+John Ostlund developed the
+Kerberos
+versions of
+.I passwd
+and
+.IR userreg .
+
+Stan Zanarotti pioneered Kerberos in a foreign realm (LCS),
+and made many contributions based on that experience.
+
+Many people contributed code and/or useful ideas, including
+Jim Aspnes,
+Bob Baldwin,
+John Barba,
+Richard Basch,
+Jim Bloom,
+Bill Bryant,
+Rob French,
+Dan Geer,
+David Jedlinsky,
+John Kohl,
+John Kubiatowicz,
+Bob McKie,
+Brian Murphy,
+Ken Raeburn,
+Chris Reed,
+Jon Rochlis,
+Mike Shanzer,
+Bill Sommerfeld,
+Jennifer Steiner,
+Ted Ts'o,
+and
+Win Treese.
+
+.SH RESTRICTIONS
+
+COPYRIGHT 1985,1986 Massachusetts Institute of Technology
diff --git a/kerberosIV/man/krb.conf.5 b/kerberosIV/man/krb.conf.5
new file mode 100644 (file)
index 0000000..97a5365
--- /dev/null
@@ -0,0 +1,31 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: krb.conf.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+.TH KRB.CONF 5 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+/etc/kerberosIV/krb.conf \- Kerberos configuration file
+.SH DESCRIPTION
+.I krb.conf
+contains configuration information describing the Kerberos realm and the
+Kerberos key distribution center (KDC) servers for known realms.
+.PP
+.I krb.conf
+contains the name of the local realm in the first
+line, followed by lines indicating realm/host
+entries.  The first token is a realm name, and the second is the hostname
+of a host running a KDC for that realm.
+The words "admin server" following the hostname indicate that 
+the host also provides an administrative database server.
+For example:
+.nf
+.in +1i
+ATHENA.MIT.EDU
+ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ATHENA.MIT.EDU kerberos-2.mit.edu
+LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+.in -1i
+.SH SEE ALSO
+krb.realms(5), krb_get_krbhst(3), krb_get_lrealm(3)
diff --git a/kerberosIV/man/krb.equiv.5 b/kerberosIV/man/krb.equiv.5
new file mode 100644 (file)
index 0000000..edc438b
--- /dev/null
@@ -0,0 +1,25 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: krb.equiv.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+.TH KRB.EQUIV 5 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+/etc/kerberosIV/krb.equiv \- Kerberos equivalent hosts file
+.SH DESCRIPTION
+.I krb.equiv
+contains a list of IP address pairs that is to be considered being
+the same host for Kerberos purposes.
+.PP
+.I krb.equiv
+contains one pair of IP addresses per line.
+For example:
+.nf
+.in +1i
+130.237.223.3   192.16.126.3   # alv alv1
+130.237.223.4   192.16.126.4   # byse byse1
+130.237.228.152 192.16.126.9   # topsy topsy1
+.in -1i
+.SH SEE ALSO
+krb.conf(5), krb.realms(5), krb_equiv(3)
diff --git a/kerberosIV/man/krb.realms.5 b/kerberosIV/man/krb.realms.5
new file mode 100644 (file)
index 0000000..ebd7966
--- /dev/null
@@ -0,0 +1,38 @@
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.\"    $Id: krb.realms.5,v 1.1.1.1 1995/12/14 06:52:35 tholo Exp $
+.TH KRB.REALMS 5 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+/etc/kerberosIV/krb.realms \- host to Kerberos realm translation file
+.SH DESCRIPTION
+.I krb.realms
+provides a translation from a hostname to the Kerberos realm name for
+the services provided by that host.
+.PP
+Each line of the translation file is in one of the following forms
+(domain_name should be of the form .XXX.YYY, e.g. .LCS.MIT.EDU):
+.nf
+.in +5n
+host_name kerberos_realm
+domain_name kerberos_realm
+.in -5n
+.fi
+If a hostname exactly matches the 
+.I host_name
+field in a line of the first
+form, the corresponding realm is the realm of the host.
+If a hostname does not match any 
+.I host_name
+in the file, but its
+domain exactly matches the 
+.I domain_name
+field in a line of the second
+form, the corresponding realm is the realm of the host.
+.PP
+If no translation entry applies, the host's realm is considered to be
+the hostname's domain portion converted to upper case.
+.SH SEE ALSO
+krb_realmofhost(3)
diff --git a/kerberosIV/mk_cmds/Makefile b/kerberosIV/mk_cmds/Makefile
new file mode 100644 (file)
index 0000000..bce94a0
--- /dev/null
@@ -0,0 +1,16 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $
+
+PROG=  mk_cmds
+SRCS=  mk_cmds.c options.c utils.c ct.c cmd_tbl.c
+CFLAGS+=-I. -I${.CURDIR}/../ss
+LFLAGS=        -l
+LDADD+=        -ll
+DPADD+=        ${LIBL}
+CLEANFILES+=   y.tab.c y.tab.h lex.yy.c cmd_tbl.c ct.c
+BINDIR=        /usr/bin
+NOMAN= noman
+
+# don't install -- only needed during build of kerberos (so far)
+install:
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/mk_cmds/cmd_tbl.l b/kerberosIV/mk_cmds/cmd_tbl.l
new file mode 100644 (file)
index 0000000..1880864
--- /dev/null
@@ -0,0 +1,112 @@
+%{
+/*     $Id: cmd_tbl.l,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+%}
+
+N      [0-9]
+PC     [^\"]
+AN      [A-Z_a-z0-9]
+
+%{
+unsigned lineno = 1;
+
+static l_command_table(), l_request(), l_unimplemented(), l_end(),
+       l_quoted_string(), l_string();
+%}
+
+%%
+
+%{
+/* emptied */
+%}
+
+command_table  return l_command_table();
+request                return l_request();
+unimplemented  return l_unimplemented();
+end            return l_end();
+
+[\t ]          ;
+
+\n             ++lineno;
+
+\"{PC}*\"      return l_quoted_string();
+
+{AN}*          return l_string();
+
+#.*\n          ++lineno;
+
+.              return (*yytext);
+
+%%
+
+/*
+ * User-subroutines section.
+ *
+ * Have to put all this stuff here so that the include file
+ * from YACC output can be included, since LEX doesn't allow
+ * an include file before the code it generates for the above
+ * rules.
+ */
+
+#include <string.h>
+#include "y.tab.h"
+/* #include "copyright.h" */
+
+extern char *last_token, *ds();
+
+static l_command_table()
+{
+     last_token = "command_table";
+     return COMMAND_TABLE;
+}
+
+static l_request()
+{
+     last_token = "request";
+     return REQUEST;
+}
+
+static l_unimplemented()
+{
+     last_token = "unimplemented";
+     return UNIMPLEMENTED;
+}
+
+static l_end()
+{
+     last_token = "end";
+     return END;
+}
+
+static l_quoted_string()
+{
+     register char *p;
+     yylval.dynstr = ds(yytext+1);
+     if (p=strrchr(yylval.dynstr, '"'))
+         *p='\0';
+     last_token = ds(yylval.dynstr);
+     return STRING;
+}
+
+static l_string()
+{
+     yylval.dynstr = ds(yytext);
+     last_token = ds(yylval.dynstr);
+     return STRING;
+}
diff --git a/kerberosIV/mk_cmds/ct.y b/kerberosIV/mk_cmds/ct.y
new file mode 100644 (file)
index 0000000..f8b8c93
--- /dev/null
@@ -0,0 +1,92 @@
+%{
+/*     $Id: ct.y,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $     */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+char *str_concat3(), *ds(), *generate_rqte(), *quote();
+long flag_value();
+char *last_token = (char *)NULL;
+FILE *output_file;
+long gensym_n = 0;
+%}
+
+%union {
+       char *dynstr;
+       long flags;
+}
+
+%token COMMAND_TABLE REQUEST UNKNOWN UNIMPLEMENTED END
+%token <dynstr> STRING
+%token <dynstr> FLAGNAME
+%type <dynstr> namelist header request_list
+%type <dynstr> request_entry
+%type <flags> flag_list options
+%left OPTIONS
+%{
+#define NO_SS_ERR_H
+#include <ss/ss.h>
+%}
+%start command_table
+%%
+command_table :        header request_list END ';'
+               { write_ct($1, $2); }
+       ;
+
+header :       COMMAND_TABLE STRING ';'
+               { $$ = $2; }
+       ;
+
+request_list : request_list request_entry
+               { $$ = str_concat3($1, $2, ""); }
+       |
+               { $$ = ""; }
+       ;
+
+request_entry :        REQUEST STRING ',' STRING ',' namelist ',' options ';'
+               { $$ = generate_rqte($2, quote($4), $6, $8); }
+       |       REQUEST STRING ',' STRING ',' namelist ';'
+               { $$ = generate_rqte($2, quote($4), $6, 0); }
+       |       UNKNOWN namelist ';'
+               { $$ = generate_rqte("ss_unknown_request",
+                                       (char *)NULL, $2, 0); }
+       |       UNIMPLEMENTED STRING ',' STRING ',' namelist ';'
+               { $$ = generate_rqte("ss_unimplemented", quote($4), $6, 3); }
+       ;
+
+options        :       '(' flag_list ')'
+               { $$ = $2; }
+       |       '(' ')'
+               { $$ = 0; }
+       ;
+
+flag_list :    flag_list ',' STRING
+               { $$ = $1 | flag_val($3); }
+       |       STRING
+               { $$ = flag_val($1); }
+       ;
+
+namelist:      STRING
+               { $$ = quote(ds($1)); }
+       |       namelist ',' STRING
+               { $$ = str_concat3($1, quote($3), ",\n    "); }
+       ;
+
+%%
diff --git a/kerberosIV/mk_cmds/mk_cmds.c b/kerberosIV/mk_cmds/mk_cmds.c
new file mode 100644 (file)
index 0000000..b9a114b
--- /dev/null
@@ -0,0 +1,106 @@
+/*     $Id: mk_cmds.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#ifndef NPOSIX
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "mk_cmds_defs.h"
+
+static const char copyright[] =
+    "Copyright 1987 by MIT Student Information Processing Board";
+
+extern pointer malloc PROTOTYPE((unsigned));
+extern char *last_token;
+extern FILE *output_file;
+
+extern FILE *yyin, *yyout;
+extern unsigned lineno;
+
+main(argc, argv)
+    int argc;
+    char **argv;
+{
+    char c_file[MAXPATHLEN];
+    int result;
+    char *path, *p;
+
+    if (argc != 2) {
+       fputs("Usage: ", stderr);
+       fputs(argv[0], stderr);
+       fputs("cmdtbl.ct\n", stderr);
+       exit(1);
+    }
+
+    path = malloc(strlen(argv[1])+4); /* extra space to add ".ct" */
+    strcpy(path, argv[1]);
+    p = strrchr(path, '/');
+    if (p == (char *)NULL)
+       p = path;
+    else
+       p++;
+    p = strrchr(p, '.');
+    if (p == (char *)NULL || strcmp(p, ".ct"))
+       strcat(path, ".ct");
+    yyin = fopen(path, "r");
+    if (!yyin) {
+       perror(path);
+       exit(1);
+    }
+
+    p = strrchr(path, '.');
+    *p = '\0';
+    strcpy(c_file, path);
+    strcat(c_file, ".c");
+    *p = '.';
+
+    output_file = fopen(c_file, "w+");
+    if (!output_file) {
+       perror(c_file);
+       exit(1);
+    }
+
+    fputs("/* ", output_file); /* emacs fix -> */
+    fputs(c_file, output_file);
+    fputs(" - automatically generated from ", output_file);
+    fputs(path, output_file);
+    fputs(" */\n", output_file);
+    fputs("#include <ss/ss.h>\n\n", output_file);
+    fputs("#ifndef __STDC__\n#define const\n#endif\n\n", output_file);
+    /* parse it */
+    result = yyparse();
+    /* put file descriptors back where they belong */
+    fclose(yyin);              /* bye bye input file */
+    fclose(output_file);       /* bye bye output file */
+
+    return result;
+}
+
+yyerror(s)
+    char *s;
+{
+    fputs(s, stderr);
+    fprintf(stderr, "\nLine %d; last token was '%s'\n",
+           lineno, last_token);
+}
diff --git a/kerberosIV/mk_cmds/mk_cmds_defs.h b/kerberosIV/mk_cmds/mk_cmds_defs.h
new file mode 100644 (file)
index 0000000..8e9df96
--- /dev/null
@@ -0,0 +1,40 @@
+/*     $Id: mk_cmds_defs.h,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $   */
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __STDC__
+
+#define PROTOTYPE(p) p
+typedef void * pointer;
+
+#else
+
+#define const
+#define volatile
+#define PROTOTYPE(p) ()
+typedef char * pointer;
+
+#endif /* not __STDC__ */
+
+#if defined(__GNUC__)
+#define LOCAL_ALLOC(x) __builtin_alloca(x)
+#define LOCAL_FREE(x)
+#else
+#if defined(vax)
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+#if defined(__HIGHC__) /* Barf! */
+pragma on(alloca);
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+/* no alloca? */
+#define LOCAL_ALLOC(x) malloc(x)
+#define LOCAL_FREE(x) free(x)
+#endif
+#endif
+#endif                         /* LOCAL_ALLOC stuff */
diff --git a/kerberosIV/mk_cmds/options.c b/kerberosIV/mk_cmds/options.c
new file mode 100644 (file)
index 0000000..d3d9af0
--- /dev/null
@@ -0,0 +1,46 @@
+/*     $Id: options.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $        */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#define NO_SS_ERR_H
+#include <ss/ss.h>
+
+struct option {
+     char *text;
+     long value;
+};
+
+static struct option options[] = {
+     { "dont_list", SS_OPT_DONT_LIST },
+     { "^list", SS_OPT_DONT_LIST },
+     { "dont_summarize", SS_OPT_DONT_SUMMARIZE },
+     { "^summarize", SS_OPT_DONT_SUMMARIZE },
+     { (char *)NULL, 0 }
+};
+
+long
+flag_val(string)
+     register char *string;
+{
+     register struct option *opt;
+     for (opt = options; opt->text; opt++)
+         if (!strcmp(opt->text, string))
+              return(opt->value);
+     return(0);
+}
diff --git a/kerberosIV/mk_cmds/utils.c b/kerberosIV/mk_cmds/utils.c
new file mode 100644 (file)
index 0000000..c15d33b
--- /dev/null
@@ -0,0 +1,142 @@
+/*     $Id: utils.c,v 1.1.1.1 1995/12/14 06:52:48 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include <stdlib.h>
+#ifndef NPOSIX
+#include <string.h>
+#else
+#include <strings.h>
+#define memcpy(a, b, c) bcopy(b, a, c)
+#endif
+#define NO_SS_ERR_H
+#include "ss_internal.h"       /* includes stdio and string */
+
+extern FILE *output_file;
+char *gensym(), *str_concat3(), *quote(), *ds();
+extern long gensym_n;
+
+void write_ct(hdr, rql)
+    char const *hdr, *rql;
+{
+    char *sym;
+    sym = gensym("ssu");
+    fputs("static ss_request_entry ", output_file);
+    fputs(sym, output_file);
+    fputs("[] = {\n", output_file);
+    fputs(rql, output_file);
+    fputs("    { 0, 0, 0, 0 }\n", output_file);
+    fputs("};\n\nss_request_table ", output_file);
+    fputs(hdr, output_file);
+    fprintf(output_file, " = { %d, ", SS_RQT_TBL_V2);
+    fputs(sym, output_file);
+    fputs(" };\n", output_file);
+}
+
+char * generate_cmds_string(cmds)
+    char const *cmds;
+{
+    char * var_name = gensym("ssu");
+    fputs("static char const * const ", output_file);
+    fputs(var_name, output_file);
+    fputs("[] = {\n", output_file);
+    fputs(cmds, output_file);
+    fputs(",\n    (char const *)0\n};\n", output_file);
+    return(var_name);
+}
+
+void generate_function_definition(func)
+    char const *func;
+{
+    fputs("extern void ", output_file);
+    fputs(func, output_file);
+    fputs(" __P((int, const char * const *, int, void *));\n", output_file);
+}
+
+char * generate_rqte(func_name, info_string, cmds, options)
+    char const *func_name;
+    char const *info_string;
+    char const *cmds;
+    int options;
+{
+    int size;
+    char *string, *var_name, numbuf[16];
+    var_name = generate_cmds_string(cmds);
+    generate_function_definition(func_name);
+    size = 6;          /* "    { " */
+    size += strlen(var_name)+7; /* "quux, " */
+    size += strlen(func_name)+7; /* "foo, " */
+    size += strlen(info_string)+9; /* "\"Info!\", " */
+    sprintf(numbuf, "%d", options);
+    size += strlen(numbuf);
+    size += 4;         /* " }," + NL */
+    string = malloc(size * sizeof(char *));
+    strcpy(string, "    { ");
+    strcat(string, var_name);
+    strcat(string, ",\n      ");
+    strcat(string, func_name);
+    strcat(string, ",\n      ");
+    strcat(string, info_string);
+    strcat(string, ",\n      ");
+    strcat(string, numbuf);
+    strcat(string, " },\n");
+    return(string);
+}
+
+char *
+gensym(name)
+       char *name;
+{
+       char *symbol;
+
+       symbol = malloc((strlen(name)+6) * sizeof(char));
+       gensym_n++;
+       sprintf(symbol, "%s%05ld", name, gensym_n);
+       return(symbol);
+}
+
+/* concatenate three strings and return the result */
+char *str_concat3(a, b, c)
+       register char *a, *b, *c;
+{
+       char *result;
+       int size_a = strlen(a);
+       int size_b = strlen(b);
+       int size_c = strlen(c);
+
+       result = malloc((size_a + size_b + size_c + 2)*sizeof(char));
+       strcpy(result, a);
+       strcpy(&result[size_a], c);
+       strcpy(&result[size_a+size_c], b);
+       return(result);
+}
+
+/* return copy of string enclosed in double-quotes */
+char *quote(string)
+       register char *string;
+{
+       register char *result;
+       int len;
+       len = strlen(string)+1;
+       result = malloc(len+2);
+       result[0] = '"';
+       memcpy(&result[1], string, len-1);
+       result[len] = '"';
+       result[len+1] = '\0';
+       return(result);
+}
+
+/* make duplicate of string and return pointer */
+char *ds(s)
+       register char *s;
+{
+       register int len = strlen(s) + 1;
+       register char *new;
+       new = malloc(len);
+       memcpy(new, s, len);
+       return(new);
+}
diff --git a/kerberosIV/register/Makefile b/kerberosIV/register/Makefile
new file mode 100644 (file)
index 0000000..bdec3a0
--- /dev/null
@@ -0,0 +1,14 @@
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $
+
+PROG=  register
+SRCS=  register.c des_rw.c
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+CFLAGS+=-DKERBEROS
+DPADD+=        ${LIBKRB} ${LIBCRYPT} ${LIBDES}
+LDADD+=        -lkrb -lcrypt -ldes
+BINDIR=        /usr/bin
+BINOWN=        root
+BINMODE=4555
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/register/pathnames.h b/kerberosIV/register/pathnames.h
new file mode 100644 (file)
index 0000000..a71d628
--- /dev/null
@@ -0,0 +1,40 @@
+/*     $Id: pathnames.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $      */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from @(#)pathnames.h    8.1 (Berkeley) 6/1/93
+ */
+
+#define        SERVER_KEYDIR   "/etc/kerberosIV/register_keys"
+#define        CLIENT_KEYFILE  "/etc/kerberosIV/.update.key"
+#define        _PATH_KPASSWD   "/usr/bin/passwd"
diff --git a/kerberosIV/register/register.1 b/kerberosIV/register/register.1
new file mode 100644 (file)
index 0000000..cdb5226
--- /dev/null
@@ -0,0 +1,64 @@
+.\" Copyright (c) 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    from @(#)register.1     8.1 (Berkeley) 6/1/93
+.\"    $Id: register.1,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $
+.\"
+.TH REGISTER 1 "June 1, 1993"
+.UC 7
+.SH NAME
+register \- register with Kerberos
+.SH SYNOPSIS
+.B register
+.SH DESCRIPTION
+The
+.I register
+command
+is used to register a new user with Kerberos.
+The Kerberos server keeps record of certain trusted hosts
+from which it will accept new registrations.
+If the host on which
+.I register
+is run is trusted by Kerberos, the user
+is asked for his current password, and then
+a new password to be used with Kerberos.
+A user may only register with Kerberos one time.
+.SH FILES
+.br
+/.update.keyxx.xx.xx.xx    shared DES key with server
+.SH "SEE ALSO"
+registerd(8), kerberos(1)
+.SH DIAGNOSTICS
+\*(lqPrincipal not unique\*(rq
+if the user already exists in the Kerberos database.
+.br
+\*(lqPermission Denied,\*(rq
+if the host on which register is being run is untrusted.
diff --git a/kerberosIV/register/register.c b/kerberosIV/register/register.c
new file mode 100644 (file)
index 0000000..3104f3e
--- /dev/null
@@ -0,0 +1,316 @@
+/*     $Id: register.c,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $       */
+
+/*-
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <strings.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+#define        SERVICE "krbupdate"     /* service to add to KDC's database */
+#define        PROTO   "tcp"
+
+char   realm[REALM_SZ];
+char   krbhst[MAX_HSTNM];
+
+static char    pname[ANAME_SZ];
+static char    iname[INST_SZ];
+static char    password[_PASSWORD_LEN];
+
+/* extern char *sys_errlist; */
+void   die();
+void   setup_key(), type_info(), cleanup();
+
+main(argc, argv)
+       int     argc;
+       char    **argv;
+{
+       struct servent  *se;
+       struct hostent  *host;
+       struct sockaddr_in      sin, local;
+       int             rval;
+       int             sock, llen;
+       u_char          code;
+       static struct rlimit rl = { 0, 0 };
+
+       signal(SIGPIPE, die);
+
+       if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+               perror("rlimit");
+               exit(1);
+       }
+
+       if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
+               fprintf(stderr, "couldn't find entry for service %s\n",
+                       SERVICE);
+               exit(1);
+       }
+       if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
+               fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
+                       krb_err_txt[rval]);
+               exit(1);
+       }
+
+       if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
+               fprintf(stderr, "couldn't get Kerberos host: %s\n",
+                       krb_err_txt[rval]);
+               exit(1);
+       }
+
+       if ((host = gethostbyname(krbhst)) == NULL) {
+               fprintf(stderr, "couldn't get host entry for host %s\n",
+                       krbhst);
+               exit(1);
+       }
+
+       sin.sin_family = host->h_addrtype;
+       (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
+       sin.sin_port = se->s_port;
+
+       if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+               perror("socket");
+               exit(1);
+       }
+
+       if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+               perror("connect");
+               (void)close(sock);
+               exit(1);
+       }
+
+       llen = sizeof(local);
+       if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
+               perror("getsockname");
+               (void)close(sock);
+               exit(1);
+       }
+
+       setup_key(local);
+
+       type_info();
+
+       if (!get_user_info()) {
+               code = ABORT;
+               (void)des_write(sock, &code, 1);
+               cleanup();
+               exit(1);
+       }
+
+       code = APPEND_DB;
+       if (des_write(sock, &code, 1) != 1) {
+               perror("write 1");
+               cleanup();
+               exit(1);
+       }
+
+       if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
+               perror("write principal name");
+               cleanup();
+               exit(1);
+       }
+
+       if (des_write(sock, iname, INST_SZ) != INST_SZ) {
+               perror("write instance name");
+               cleanup();
+               exit(1);
+       }
+
+       if (des_write(sock, password, 255) != 255) {
+               perror("write password");
+               cleanup();
+               exit(1);
+       }
+
+       /* get return message */
+
+       {
+               int     cc;
+               char    msgbuf[BUFSIZ];
+
+               cc = read(sock, msgbuf, BUFSIZ);
+               if (cc <= 0) {
+                       fprintf(stderr, "protocol error during key verification\n");
+                       cleanup();
+                       exit(1);
+               }
+               if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
+                       fprintf(stderr, "%s: %s", krbhst, msgbuf);
+                       cleanup();
+                       exit(1);
+               }
+
+               cc = des_read(sock, msgbuf, BUFSIZ);
+               if (cc <= 0) {
+                       fprintf(stderr, "protocol error during read\n");
+                       cleanup();
+                       exit(1);
+               } else {
+                       printf("%s: %s", krbhst, msgbuf);
+               }
+       }
+
+       cleanup();
+       (void)close(sock);
+}
+
+void
+cleanup()
+{
+       bzero(password, 255);
+}
+
+extern char    *crypt();
+extern char    *getpass();
+
+int
+get_user_info()
+{
+       int     uid = getuid();
+       int     valid = 0, i;
+       struct  passwd  *pw;
+       char    *pas, *namep;
+
+       /* NB: we must run setuid-root to get at the real pw file */
+
+       if ((pw = getpwuid(uid)) == NULL) {
+               fprintf(stderr, "Who are you?\n");
+               return(0);
+       }
+       (void)seteuid(uid);
+       (void)strcpy(pname, pw->pw_name);       /* principal name */
+
+       for (i = 1; i < 3; i++) {
+               pas = getpass("login password:");
+               namep = crypt(pas, pw->pw_passwd);
+               if (strcmp(namep, pw->pw_passwd)) {
+                       fprintf(stderr, "Password incorrect\n");
+                       continue;
+               } else {
+                       valid = 1;
+                       break;
+               }
+       }
+       if (!valid)
+               return(0);
+       pas = getpass("Kerberos password (may be the same):");
+       while (*pas == NULL) {
+               printf("<NULL> password not allowed\n");
+               pas = getpass("Kerberos password (may be the same):");
+       }
+       (void)strcpy(password, pas);            /* password */
+       pas = getpass("Retype Kerberos password:");
+       if (strcmp(password, pas)) {
+               fprintf(stderr, "Password mismatch -- aborted\n");
+               return(0);
+       }
+
+       iname[0] = NULL;        /* null instance name */
+       return(1);
+}
+
+void
+setup_key(local)
+       struct  sockaddr_in     local;
+{
+       static  struct  keyfile_data    kdata;
+       static  Key_schedule            schedule;
+       int     fd;
+       char    namebuf[MAXPATHLEN];
+       extern int errno;
+
+       (void) sprintf(namebuf, "%s%s",
+               CLIENT_KEYFILE,
+               inet_ntoa(local.sin_addr));
+
+       fd = open(namebuf, O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "couldn't open key file %s for local host: ",
+                       namebuf);
+               perror("");
+               exit(1);
+       }
+
+       if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
+               fprintf(stderr,"size error reading key file for local host %s\n",
+                       inet_ntoa(local.sin_addr));
+               exit(1);
+       }
+       key_sched(&kdata.kf_key, schedule);
+       des_set_key(&kdata.kf_key, schedule);
+       return;
+}
+
+void
+type_info()
+{
+       printf("Kerberos user registration (realm %s)\n\n", realm);
+       printf("Please enter your login password followed by your new Kerberos password.\n");
+       printf("The Kerberos password you enter now will be used in the future\n");
+       printf("as your Kerberos password for all machines in the %s realm.\n", realm);
+       printf("You will only be allowed to perform this operation once, although you may run\n");
+       printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
+}
+
+void
+die()
+{
+       fprintf(stderr, "\nServer no longer listening\n");
+       fflush(stderr);
+       cleanup();
+       exit(1);
+}
diff --git a/kerberosIV/register/register_proto.h b/kerberosIV/register/register_proto.h
new file mode 100644 (file)
index 0000000..d5cb094
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from @(#)register_proto.h       8.1 (Berkeley) 6/1/93
+ *     $Id: register_proto.h,v 1.1.1.1 1995/12/14 06:52:33 tholo Exp $
+ */
+
+#define        APPEND_DB       0x01
+#define        ABORT           0x02
+
+#define        GOTKEY_MSG      "GOTKEY"
+
+struct keyfile_data {
+       C_Block         kf_key;
+};
diff --git a/kerberosIV/registerd/Makefile b/kerberosIV/registerd/Makefile
new file mode 100644 (file)
index 0000000..2019ed5
--- /dev/null
@@ -0,0 +1,16 @@
+# Copyright (c) 1990 The Regents of the University of California.
+# All rights reserved.
+#
+#      from @(#)Makefile       8.1 (Berkeley) 6/1/93
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $
+
+PROG=  registerd
+SRCS=  registerd.c des_rw.c
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../register
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN=   registerd.8
+BINDIR=        /usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/kerberosIV/registerd/registerd.8 b/kerberosIV/registerd/registerd.8
new file mode 100644 (file)
index 0000000..c53a0b5
--- /dev/null
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    from @(#)registerd.8    8.2 (Berkeley) 12/11/93
+.\"    $Id: registerd.8,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $
+.\"
+.Dd December 11, 1993
+.Dt REGISTERD 8
+.Os
+.Sh NAME
+.Nm registerd
+.Nd Kerberos registration daemon
+.Sh SYNOPSIS
+.Nm registerd
+.Sh DESCRIPTION
+Act as a registration agent for a Kerberos domain.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keys -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/principal*
+Kerberos database
+.It Pa /etc/kerberosIV/register_keys
+directory containing keys for trusted hosts
+.El
+.Sh SEE ALSO
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh DIAGNOSTICS
+.Dq Already exists ,
+if the user already exists in the Kerberos database.
+.Pp
+.Dq Permission Denied ,
+if the host on which register is being run is untrusted.
+.Sh HISTORY
+The
+.Nm registerd
+utility
+first appeared in 4.4BSD.
+
diff --git a/kerberosIV/registerd/registerd.c b/kerberosIV/registerd/registerd.c
new file mode 100644 (file)
index 0000000..a1f3fcc
--- /dev/null
@@ -0,0 +1,347 @@
+/*     $Id: registerd.c,v 1.1.1.1 1995/12/14 06:52:36 tholo Exp $      */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)registerd.c        8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include <stdio.h>
+#include <strings.h>
+#include "register_proto.h"
+#include "pathnames.h"
+
+#define        KBUFSIZ         (sizeof(struct keyfile_data))
+#define        RCRYPT          0x00
+#define        CLEAR           0x01
+
+char   *progname, msgbuf[BUFSIZ];
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       static  Key_schedule    schedule;
+       static struct rlimit rl = { 0, 0 };
+       struct  keyfile_data    *kfile;
+       u_char  code;
+       int     kf, retval, sval;
+       struct  sockaddr_in     sina;
+       char    keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
+       void die();
+
+       progname = argv[0];             /* for the library routines */
+
+       openlog("registerd", LOG_PID, LOG_AUTH);
+
+       (void)signal(SIGHUP, SIG_IGN);
+       (void)signal(SIGINT, SIG_IGN);
+       (void)signal(SIGTSTP, SIG_IGN);
+       (void)signal(SIGPIPE, die);
+
+       if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+               syslog(LOG_ERR, "setrlimit: %m");
+               exit(1);
+       }
+
+
+       /* figure out who we are talking to */
+
+       sval = sizeof(sina);
+       if (getpeername(0, (struct sockaddr *) &sina, &sval) < 0) {
+               syslog(LOG_ERR, "getpeername: %m");
+               exit(1);
+       }
+
+       /* get encryption key */
+
+       (void) sprintf(keyfile, "%s%s%s",
+               SERVER_KEYDIR,
+               CLIENT_KEYFILE,
+               inet_ntoa(sina.sin_addr));
+
+       if ((kf = open(keyfile, O_RDONLY)) < 0) {
+               syslog(LOG_ERR,
+                   "error opening Kerberos update keyfile (%s): %m", keyfile);
+               (void) sprintf(msgbuf,
+                   "couldn't open session keyfile for your host");
+               send_packet(msgbuf, CLEAR);
+               exit(1);
+       }
+
+       if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
+               syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
+               (void) sprintf(msgbuf,
+                       "couldn't read session key from your host's keyfile");
+               send_packet(msgbuf, CLEAR);
+               exit(1);
+       }
+       (void) sprintf(msgbuf, GOTKEY_MSG);
+       send_packet(msgbuf, CLEAR);
+       kfile = (struct keyfile_data *) keybuf;
+       key_sched(&kfile->kf_key, schedule);
+       des_set_key(&kfile->kf_key, schedule);
+
+       /* read the command code byte */
+
+       if (des_read(0, &code, 1) == 1) {
+
+               switch(code) {
+               case    APPEND_DB:
+                       retval = do_append(&sina);
+                       break;
+               case    ABORT:
+                       cleanup();
+                       close(0);
+                       exit(0);
+               default:
+                       retval = KFAILURE;
+                       syslog(LOG_NOTICE,
+                               "invalid command code on db update (0x%x)",
+                               code);
+               }
+
+       } else {
+               retval = KFAILURE;
+               syslog(LOG_ERR,
+                   "couldn't read command code on Kerberos update");
+       }
+
+       code = (u_char) retval; 
+       if (code != KSUCCESS) {
+               (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
+               send_packet(msgbuf, RCRYPT);
+       } else {
+               (void) sprintf(msgbuf, "Update complete.");
+               send_packet(msgbuf, RCRYPT);
+       }
+       cleanup();
+       close(0);
+       exit(0);
+}
+
+#define        MAX_PRINCIPAL   10
+static Principal       principal_data[MAX_PRINCIPAL];
+static C_Block         key, master_key;
+static Key_schedule    master_key_schedule;
+int
+do_append(sinp)
+       struct sockaddr_in *sinp;
+{
+       Principal       default_princ;
+       char            input_name[ANAME_SZ];
+       char            input_instance[INST_SZ];
+       int             j,n, more;
+       long            mkeyversion;
+
+
+
+       /* get master key from MKEYFILE */
+       if (kdb_get_master_key(0, &master_key, master_key_schedule) != 0) {
+               syslog(LOG_ERR, "couldn't get master key");
+               return(KFAILURE);
+       }
+
+       mkeyversion = kdb_verify_master_key(&master_key, master_key_schedule, NULL);
+       if (mkeyversion < 0) {
+               syslog(LOG_ERR, "couldn't validate master key");
+               return(KFAILURE);
+       }
+
+       n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+               &default_princ, 1, &more);
+
+       if (n != 1) {
+               syslog(LOG_ERR, "couldn't get default principal");
+               return(KFAILURE);
+       }
+
+       /*
+        * get principal name, instance, and password from network.
+        * convert password to key and store it
+        */
+
+       if (net_get_principal(input_name, input_instance, key) != 0) {
+               return(KFAILURE);
+       }
+
+
+       j = kerb_get_principal(
+               input_name,
+               input_instance,
+               principal_data,
+               MAX_PRINCIPAL,
+               &more
+       );
+
+       if (j != 0) {
+               /* already in database, no update */
+               syslog(LOG_NOTICE,
+                       "attempt to add duplicate entry for principal %s.%s",
+                       input_name, input_instance);
+               return(KDC_PR_N_UNIQUE);
+       }
+
+       /*
+        * set up principal's name, instance
+        */
+
+       strcpy(principal_data[0].name, input_name);
+       strcpy(principal_data[0].instance, input_instance);
+       principal_data[0].old = NULL;
+
+
+       /* and the expiration date and version #s */
+
+       principal_data[0].exp_date = default_princ.exp_date;
+       strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
+       principal_data[0].max_life = default_princ.max_life;
+       principal_data[0].attributes = default_princ.attributes;
+       principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
+
+
+       /* and the key */
+
+       kdb_encrypt_key(&key, &key, &master_key, master_key_schedule,
+                       ENCRYPT);
+       bcopy(key, &principal_data[0].key_low, 4);
+       bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
+       bzero(key, sizeof(key));
+
+       principal_data[0].key_version = 1;      /* 1st entry */
+
+       /* and write it to the database */
+
+       if (kerb_put_principal(&principal_data[0], 1)) {
+               syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
+               return(KFAILURE);
+       }
+
+       syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
+               principal_data[0].name,
+               principal_data[0].instance,
+               inet_ntoa(sinp->sin_addr)
+       );
+
+       return(KSUCCESS);
+
+}
+
+send_packet(msg,flag)
+       char    *msg;
+       int     flag;
+{
+       int     len = strlen(msg);
+       msg[len++] = '\n';
+       msg[len] = '\0';
+       if (len > sizeof(msgbuf)) {
+               syslog(LOG_ERR, "send_packet: invalid msg size");
+               return;
+       }
+       if (flag == RCRYPT) {
+               if (des_write(0, msg, len) != len)
+                       syslog(LOG_ERR, "couldn't write reply message");
+       } else if (flag == CLEAR) {
+               if (write(0, msg, len) != len)
+                       syslog(LOG_ERR, "couldn't write reply message");
+       } else
+                       syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
+
+}
+
+net_get_principal(pname, iname, keyp)
+       char    *pname, *iname;
+       C_Block *keyp;
+{
+       int     cc;
+       static  char    password[255];
+
+       cc = des_read(0, pname, ANAME_SZ);
+       if (cc != ANAME_SZ) {
+               syslog(LOG_ERR, "couldn't get principal name");
+               return(-1);
+       }
+
+       cc = des_read(0, iname, INST_SZ);
+       if (cc != INST_SZ) {
+               syslog(LOG_ERR, "couldn't get instance name");
+               return(-1);
+       }
+
+       cc = des_read(0, password, 255);
+       if (cc != 255) {
+               syslog(LOG_ERR, "couldn't get password");
+               bzero(password, 255);
+               return(-1);
+       }
+
+       string_to_key(password, keyp);
+       bzero(password, 255);
+       return(0);
+}
+
+cleanup()
+{
+       bzero(master_key, sizeof(master_key));
+       bzero(key, sizeof(key));
+       bzero(master_key_schedule, sizeof(master_key_schedule));
+}
+
+void
+die()
+{
+       syslog(LOG_ERR, "remote end died (SIGPIPE)");
+       cleanup();
+       exit(1);
+}
diff --git a/kerberosIV/ss/Makefile b/kerberosIV/ss/Makefile
new file mode 100644 (file)
index 0000000..c778fe6
--- /dev/null
@@ -0,0 +1,34 @@
+#      $Id: Makefile,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $
+
+LIB=   ss
+SRCS=  ss_err.c data.c error.c execute_cmd.c help.c invocation.c list_rqs.c \
+       listen.c pager.c parse.c prompt.c request_tbl.c requests.c \
+       std_rqs.c
+CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../com_err
+LDADD+=        ${COM_ERR}
+CLEANFILES+=   ss_err.c ss_err.h std_rqs.c ss
+
+ss_err.h ss_err.c:     ${.CURDIR}/ss_err.et
+       test -e ss_err.et || ln -s ${.CURDIR}/ss_err.et .
+       ${COMPILE_ET} ss_err.et
+       -test -h ss_err.et && rm ss_err.et
+
+std_rqs.c:             ${.CURDIR}/std_rqs.ct
+       test -e std_rqs.ct || ln -s ${.CURDIR}/std_rqs.ct .
+       ${MK_CMDS} std_rqs.ct
+       -test -h std_rqs.ct && rm std_rqs.ct
+
+beforeinstall:
+       -cd ${.OBJDIR}; \
+           if [ -f ss_err.h ]; then \
+               cmp -s ss_err.h ${DESTDIR}/usr/include/ss/ss_err.h || \
+               install -c -o ${BINOWN} -g ${BINGRP} -m 444 ss_err.h \
+               ${DESTDIR}/usr/include/ss; \
+           else \
+               true; \
+           fi
+
+beforedepend:
+       ln -s . ss
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/ss/data.c b/kerberosIV/ss/data.c
new file mode 100644 (file)
index 0000000..bba1b58
--- /dev/null
@@ -0,0 +1,27 @@
+/*     $Id: data.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $   */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include "ss_internal.h"
+
+const static char copyright[] =
+    "Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology";
+
+ss_data **_ss_table = (ss_data **)NULL;
+char *_ss_pager_name = (char *)NULL;
diff --git a/kerberosIV/ss/error.c b/kerberosIV/ss/error.c
new file mode 100644 (file)
index 0000000..0a6352a
--- /dev/null
@@ -0,0 +1,114 @@
+/*     $Id: error.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Our standalone dpANS environment on the RT doesn't include any
+ * header files.
+ */
+#if defined(__STDC__) && !defined(ibm032)
+#include <stdarg.h>
+#define STDARG
+#else
+#include <varargs.h>
+#define ss_error ss_error_external
+#endif
+
+#include <kerberosIV/com_err.h>
+#include "ss_internal.h"
+
+#undef ss_error
+
+char *
+ss_name(sci_idx)
+    int sci_idx;
+{
+    register char *ret_val;
+    register ss_data *infop;
+    
+    infop = ss_info(sci_idx);
+    if (infop->current_request == (char const *)NULL) {
+       ret_val = malloc((unsigned)
+                        (strlen(infop->subsystem_name)+1)
+                        * sizeof(char));
+       if (ret_val == (char *)NULL)
+           return((char *)NULL);
+       strcpy(ret_val, infop->subsystem_name);
+       return(ret_val);
+    }
+    else {
+       register char *cp;
+       register char const *cp1;
+       ret_val = malloc((unsigned)sizeof(char) * 
+                        (strlen(infop->subsystem_name)+
+                         strlen(infop->current_request)+
+                         4));
+       cp = ret_val;
+       cp1 = infop->subsystem_name;
+       while (*cp1)
+           *cp++ = *cp1++;
+       *cp++ = ' ';
+       *cp++ = '(';
+       cp1 = infop->current_request;
+       while (*cp1)
+           *cp++ = *cp1++;
+       *cp++ = ')';
+       *cp = '\0';
+       return(ret_val);
+    }
+}
+
+#ifdef STDARG
+void
+ss_error (int sci_idx, long code, const char * fmt, ...)
+#else
+void
+ss_error (va_alist)
+    va_dcl
+#endif
+{
+    register char *whoami;
+    va_list pvar;
+#ifndef STDARG
+    int sci_idx;
+    long code;
+    char * fmt;
+    va_start (pvar);
+    sci_idx = va_arg (pvar, int);
+    code = va_arg (pvar, long);
+    fmt = va_arg (pvar, char *);
+#else
+    va_start (pvar, fmt);
+#endif
+    whoami = ss_name (sci_idx);
+    com_err_va (whoami, code, fmt, pvar);
+    free (whoami);
+    va_end(pvar);
+}
+
+void
+ss_perror (sci_idx, code, msg) /* for compatibility */
+    int sci_idx;
+    long code;
+    char const *msg;
+{
+    ss_error (sci_idx, code, "%s", msg);
+}
diff --git a/kerberosIV/ss/execute_cmd.c b/kerberosIV/ss/execute_cmd.c
new file mode 100644 (file)
index 0000000..13230c8
--- /dev/null
@@ -0,0 +1,241 @@
+/*     $Id: execute_cmd.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ss_internal.h"
+
+#ifndef lint
+static char const rcsid[] =
+    "$Id: execute_cmd.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $";
+#endif
+
+/*
+ * get_request(tbl, idx)
+ *
+ * Function:
+ *      Gets the idx'th request from the request table pointed to
+ *      by tbl.
+ * Arguments:
+ *      tbl (ss_request_table *)
+ *              pointer to request table
+ *      idx (int)
+ *              index into table
+ * Returns:
+ *      (ss_request_entry *)
+ *              pointer to request table entry
+ * Notes:
+ *      Has been replaced by a macro.
+ */
+
+#ifdef __SABER__
+/* sigh.  saber won't deal with pointer-to-const-struct */
+static struct _ss_request_entry *
+get_request (tbl, idx)
+    ss_request_table * tbl;
+    int idx;
+{
+    struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
+    struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
+    return e + idx;
+}
+#else
+#define get_request(tbl,idx)    ((tbl) -> requests + (idx))
+#endif
+
+/*
+ * check_request_table(rqtbl, argc, argv, sci_idx)
+ *
+ * Function:
+ *      If the command string in argv[0] is in the request table, execute
+ *      the commands and return error code 0.  Otherwise, return error
+ *      code ss_et_command_not_found.
+ * Arguments:
+ *      rqtbl (ss_request_table *)
+ *              pointer to request table
+ *      argc (int)
+ *              number of elements in argv[]
+ *      argv (char *[])
+ *              argument string array
+ *      sci_idx (int)
+ *              ss-internal index for subsystem control info structure
+ * Returns:
+ *      (int)
+ *              zero if command found, ss_et_command_not_found otherwise
+ * Notes:
+ */
+
+static int
+check_request_table (rqtbl, argc, argv, sci_idx)
+    register ss_request_table *rqtbl;
+    int argc;
+    char *argv[];
+    int sci_idx;
+{
+#ifdef __SABER__
+    struct _ss_request_entry *request;
+#else
+    register ss_request_entry *request;
+#endif
+    register ss_data *info;
+    register char const * const * name;
+    char *string = argv[0];
+    int i;
+
+    info = ss_info(sci_idx);
+    info->argc = argc;
+    info->argv = argv;
+    for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
+       for (name = request->command_names; *name; name++)
+           if (!strcmp(*name, string)) {
+               info->current_request = request->command_names[0];
+               (request->function)(argc, (const char *const *) argv,
+                                   sci_idx,info->info_ptr);
+               info->current_request = (char *)NULL;
+               return(0);
+           }
+    }
+    return(SS_ET_COMMAND_NOT_FOUND);
+}
+
+/*
+ * really_execute_command(sci_idx, argc, argv)
+ *
+ * Function:
+ *      Fills in the argc, argv values in the subsystem entry and
+ *      call the appropriate routine.
+ * Arguments:
+ *      sci_idx (int)
+ *              ss-internal index for subsystem control info structure
+ *      argc (int)
+ *              number of arguments in argument list
+ *      argv (char **[])
+ *              pointer to parsed argument list (may be reallocated
+ *              on abbrev expansion)
+ *
+ * Returns:
+ *      (int)
+ *              Zero if successful, ss_et_command_not_found otherwise.
+ * Notes:
+ */
+
+static int
+really_execute_command (sci_idx, argc, argv)
+    int sci_idx;
+    int argc;
+    char **argv[];
+{
+    register ss_request_table **rqtbl;
+    register ss_data *info;
+
+    info = ss_info(sci_idx);
+
+    for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
+        if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
+            return(0);
+    }
+    return(SS_ET_COMMAND_NOT_FOUND);
+}
+
+/*
+ * ss_execute_command(sci_idx, argv)
+ *
+ * Function:
+ *     Executes a parsed command list within the subsystem.
+ * Arguments:
+ *     sci_idx (int)
+ *             ss-internal index for subsystem control info structure
+ *     argv (char *[])
+ *             parsed argument list
+ * Returns:
+ *     (int)
+ *             Zero if successful, ss_et_command_not_found otherwise.
+ * Notes:
+ */
+
+int
+ss_execute_command(sci_idx, argv)
+       int sci_idx;
+       register char *argv[];
+{
+       register int i, argc;
+       char **argp;
+
+       argc = 0;
+       for (argp = argv; *argp; argp++)
+               argc++;
+       argp = (char **)malloc((argc+1)*sizeof(char *));
+       for (i = 0; i <= argc; i++)
+               argp[i] = argv[i];
+       i = really_execute_command(sci_idx, argc, &argp);
+       free(argp);
+       return(i);
+}
+
+/*
+ * ss_execute_line(sci_idx, line_ptr)
+ *
+ * Function:
+ *      Parses and executes a command line within a subsystem.
+ * Arguments:
+ *      sci_idx (int)
+ *              ss-internal index for subsystem control info structure
+ *      line_ptr (char *)
+ *              Pointer to command line to be parsed.
+ * Returns:
+ *      (int)
+ *             Error code.
+ * Notes:
+ */
+
+int
+ss_execute_line (sci_idx, line_ptr)
+    int sci_idx;
+    char *line_ptr;
+{
+    char **argv;
+    int argc;
+    int retval;
+
+    /* flush leading whitespace */
+    while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
+        line_ptr++;
+
+    /* check if it should be sent to operating system for execution */
+    if (*line_ptr == '!') {
+        if (ss_info(sci_idx)->flags.escape_disabled)
+            return SS_ET_ESCAPE_DISABLED;
+        else {
+            line_ptr++;
+            system(line_ptr);
+           return 0;
+        }
+    }
+
+    /* parse it */
+    argv = ss_parse(sci_idx, line_ptr, &argc);
+    if (argc == 0)
+        return 0;
+
+    /* look it up in the request tables, execute if found */
+    retval = really_execute_command (sci_idx, argc, &argv);
+    free(argv);
+    return(retval);
+}
diff --git a/kerberosIV/ss/help.c b/kerberosIV/ss/help.c
new file mode 100644 (file)
index 0000000..64d94f0
--- /dev/null
@@ -0,0 +1,171 @@
+/*     $Id: help.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $   */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#ifndef NPOSIX
+#include <fcntl.h>
+#endif
+#include <sys/wait.h>
+#include "ss_internal.h"
+
+extern int errno;
+
+void
+ss_help (argc, argv, sci_idx, info_ptr)
+    int argc;
+    char const * const *argv;
+    int sci_idx;
+    pointer info_ptr;
+{
+    char buffer[MAXPATHLEN];
+    char const *request_name;
+    int code;
+    int fd, child;
+    register int idx;
+    register ss_data *info;
+
+    request_name = ss_current_request(sci_idx, &code);
+    if (code != 0) {
+       ss_perror(sci_idx, code, "");
+       return;         /* no ss_abort_line, if invalid invocation */
+    }
+    if (argc == 1) {
+       ss_list_requests(argc, argv, sci_idx, info_ptr);
+       return;
+    }
+    else if (argc != 2) {
+       /* should do something better than this */
+       sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
+               request_name, request_name);
+       ss_perror(sci_idx, 0, buffer);
+       return;
+    }
+    info = ss_info(sci_idx);
+    if (info->info_dirs == (char **)NULL) {
+       ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
+       return;
+    }
+    if (info->info_dirs[0] == (char *)NULL) {
+       ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
+       return;
+    }
+    for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
+       (void) strcpy(buffer, info->info_dirs[idx]);
+       (void) strcat(buffer, "/");
+       (void) strcat(buffer, argv[1]);
+       (void) strcat(buffer, ".info");
+       if ((fd = open(&buffer[0], O_RDONLY, 0)) >= 0) goto got_it;
+    }
+    if ((fd = open(&buffer[0], O_RDONLY, 0)) < 0) {
+       char buf[MAXPATHLEN];
+       strcpy(buf, "No info found for ");
+       strcat(buf, argv[1]);
+       ss_perror(sci_idx, 0, buf);
+       return;
+    }
+got_it:
+    switch (child = fork()) {
+    case -1:
+       ss_perror(sci_idx, errno, "Can't fork for pager");
+       return;
+    case 0:
+       (void) dup2(fd, 0); /* put file on stdin */
+       ss_page_stdin();
+    default:
+       (void) close(fd); /* what can we do if it fails? */
+#ifndef NPOSIX
+       while (wait((int *)0) != child) ;        /* do nothing if wrong pid */
+#else
+       while (wait((union wait *)0) != child) ; /* do nothing if wrong pid */
+#endif
+    }
+}
+
+#include <sys/types.h>
+#ifdef NPOSIX  
+#include <sys/dir.h>
+#else
+#include <dirent.h>
+#endif /* NPOSIX */
+
+void
+ss_add_info_dir(sci_idx, info_dir, code_ptr)
+    int sci_idx;
+    char *info_dir;
+    int *code_ptr;
+{
+    register ss_data *info;
+    DIR *d;
+    int n_dirs;
+    register char **dirs;
+
+    info = ss_info(sci_idx);
+    if (info_dir == NULL && *info_dir) {
+       *code_ptr = SS_ET_NO_INFO_DIR;
+       return;
+    }
+    if ((d = opendir(info_dir)) == (DIR *)NULL) {
+       *code_ptr = errno;
+       return;
+    }
+    closedir(d);
+    dirs = info->info_dirs;
+    for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
+       ;               /* get number of non-NULL dir entries */
+    dirs = (char **)realloc((char *)dirs,
+                           (unsigned)(n_dirs + 2)*sizeof(char *));
+    if (dirs == (char **)NULL) {
+       info->info_dirs = (char **)NULL;
+       *code_ptr = errno;
+       return;
+    }
+    info->info_dirs = dirs;
+    dirs[n_dirs + 1] = (char *)NULL;
+    dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
+    strcpy(dirs[n_dirs], info_dir);
+    *code_ptr = 0;
+}
+
+void
+ss_delete_info_dir(sci_idx, info_dir, code_ptr)
+    int sci_idx;
+    char *info_dir;
+    int *code_ptr;
+{
+    register char **i_d;
+    register char **info_dirs;
+
+    info_dirs = ss_info(sci_idx)->info_dirs;
+    for (i_d = info_dirs; *i_d; i_d++) {
+       if (!strcmp(*i_d, info_dir)) {
+           while (*i_d) {
+               *i_d = *(i_d+1);
+               i_d++;
+           }
+           *code_ptr = 0;
+           return;
+       }
+    }
+    *code_ptr = SS_ET_NO_INFO_DIR;
+}
diff --git a/kerberosIV/ss/invocation.c b/kerberosIV/ss/invocation.c
new file mode 100644 (file)
index 0000000..55caa5f
--- /dev/null
@@ -0,0 +1,97 @@
+/*     $Id: invocation.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $     */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdlib.h>
+#include "ss_internal.h"
+#define        size    sizeof(ss_data *)
+
+#ifndef lint
+static char const rcsid[] =
+    "$Id: invocation.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $";
+#endif
+
+int
+ss_create_invocation(subsystem_name, version_string, info_ptr,
+                        request_table_ptr, code_ptr)
+       char *subsystem_name, *version_string;
+       char *info_ptr;
+       ss_request_table *request_table_ptr;
+       int *code_ptr;
+{
+       register int sci_idx;
+       register ss_data *new_table;
+       register ss_data **table;
+
+       *code_ptr = 0;
+       table = _ss_table;
+       new_table = (ss_data *) malloc(sizeof(ss_data));
+
+       if (table == (ss_data **) NULL) {
+               table = (ss_data **) malloc(2 * size);
+               table[0] = table[1] = (ss_data *)NULL;
+       }
+       initialize_ss_error_table ();
+
+       for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++)
+               ;
+       table = (ss_data **) realloc((char *)table,
+                                    ((unsigned)sci_idx+2)*size);
+       table[sci_idx+1] = (ss_data *) NULL;
+       table[sci_idx] = new_table;
+
+       new_table->subsystem_name = subsystem_name;
+       new_table->subsystem_version = version_string;
+       new_table->argv = (char **)NULL;
+       new_table->current_request = (char *)NULL;
+       new_table->info_dirs = (char **)malloc(sizeof(char *));
+       *new_table->info_dirs = (char *)NULL;
+       new_table->info_ptr = info_ptr;
+       new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4);
+       strcpy(new_table->prompt, subsystem_name);
+       strcat(new_table->prompt, ":  ");
+#ifdef silly
+       new_table->abbrev_info = ss_abbrev_initialize("/etc/passwd", code_ptr);
+#else
+       new_table->abbrev_info = NULL;
+#endif
+       new_table->flags.escape_disabled = 0;
+       new_table->flags.abbrevs_disabled = 0;
+       new_table->rqt_tables =
+               (ss_request_table **) calloc(2, sizeof(ss_request_table *));
+       *(new_table->rqt_tables) = request_table_ptr;
+       *(new_table->rqt_tables+1) = (ss_request_table *) NULL;
+       _ss_table = table;
+       return(sci_idx);
+}
+
+void
+ss_delete_invocation(sci_idx)
+       int sci_idx;
+{
+       register ss_data *t;
+       int ignored_code;
+
+       t = ss_info(sci_idx);
+       free(t->prompt);
+       free((char *)t->rqt_tables);
+       while(t->info_dirs[0] != (char *)NULL)
+               ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code);
+       free((char *)t->info_dirs);
+       free((char *)t);
+}
diff --git a/kerberosIV/ss/list_rqs.c b/kerberosIV/ss/list_rqs.c
new file mode 100644 (file)
index 0000000..27f7013
--- /dev/null
@@ -0,0 +1,124 @@
+/*     $Id: list_rqs.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include "ss_internal.h"
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifdef lint     /* "lint returns a value which is sometimes ignored" */
+#define DONT_USE(x)     x=x;
+#else /* !lint */
+#define DONT_USE(x)     ;
+#endif /* lint */
+
+static char const twentyfive_spaces[26] =
+    "                         ";
+static char const NL[2] = "\n";
+
+int
+ss_list_requests(argc, argv, sci_idx, info_ptr)
+    int argc;
+    char **argv;
+    int sci_idx;
+    pointer info_ptr;
+{
+    register ss_request_entry *entry;
+    register char const * const *name;
+    register int spacing;
+    register ss_request_table **table;
+
+    char buffer[BUFSIZ];
+    FILE *output;
+    int fd;
+#ifndef NPOSIX
+    struct sigaction nsig, osig;
+    sigset_t nmask, omask;
+    int waitb;
+#else
+    int (*func)();
+    int mask;
+    union wait waitb;
+#endif
+
+    DONT_USE(argc);
+    DONT_USE(argv);
+
+#ifndef NPOSIX
+    sigemptyset(&nmask);
+    sigaddset(&nmask, SIGINT);
+    sigprocmask(SIG_BLOCK, &nmask, &omask);
+    
+    nsig.sa_handler = SIG_IGN;
+    sigemptyset(&nsig.sa_mask);
+    nsig.sa_flags = 0;
+    sigaction(SIGINT, &nsig, &osig);
+#else
+    mask = sigblock(sigmask(SIGINT));
+    func = signal(SIGINT, SIG_IGN);
+#endif
+    fd = ss_pager_create();
+    output = fdopen(fd, "w");
+#ifndef NPOSIX
+    sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
+#else
+    sigsetmask(mask);
+#endif
+
+    fprintf (output, "Available %s requests:\n\n",
+            ss_info (sci_idx) -> subsystem_name);
+
+    for (table = ss_info(sci_idx)->rqt_tables; *table; table++) {
+        entry = (*table)->requests;
+        for (; entry->command_names; entry++) {
+            spacing = -2;
+            buffer[0] = '\0';
+            if (entry->flags & SS_OPT_DONT_LIST)
+                continue;
+            for (name = entry->command_names; *name; name++) {
+                register int len = strlen(*name);
+                strncat(buffer, *name, len);
+                spacing += len + 2;
+                if (name[1]) {
+                    strcat(buffer, ", ");
+                }
+            }
+            if (spacing > 23) {
+                strcat(buffer, NL);
+                fputs(buffer, output);
+                spacing = 0;
+                buffer[0] = '\0';
+            }
+            strncat(buffer, twentyfive_spaces, 25-spacing);
+            strcat(buffer, entry->info_string);
+            strcat(buffer, NL);
+            fputs(buffer, output);
+        }
+    }
+    fclose(output);
+#ifndef NO_FORK
+    wait(&waitb);
+#endif
+#ifndef NPOSIX
+    sigaction(SIGINT, &osig, (struct sigaction *)0);
+#else
+    (void) signal(SIGINT, func);
+#endif
+}
diff --git a/kerberosIV/ss/listen.c b/kerberosIV/ss/listen.c
new file mode 100644 (file)
index 0000000..5e24f7f
--- /dev/null
@@ -0,0 +1,216 @@
+/*     $Id: listen.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Listener loop for subsystem library libss.a.
+ */
+
+#include "ss_internal.h"
+#include <stdio.h>
+#ifndef NPOSIX
+#include <string.h>
+#else
+#include <strings.h>
+#define memcpy(a, b, c) bcopy(b, a, c)
+#endif
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/param.h>
+#ifdef BSD
+#include <sgtty.h>
+#endif
+
+#ifndef        lint
+static char const rcs_id[] =
+    "$Id: listen.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $";
+#endif
+
+#ifndef NPOSIX
+#define sigtype void
+#else
+#define sigtype int
+#endif
+
+static ss_data *current_info;
+static jmp_buf listen_jmpb;
+
+static sigtype
+print_prompt()
+{
+#ifdef BSD
+    /* put input into a reasonable mode */
+    struct sgttyb ttyb;
+    if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
+       if (ttyb.sg_flags & (CBREAK|RAW)) {
+           ttyb.sg_flags &= ~(CBREAK|RAW);
+           (void) ioctl(0, TIOCSETP, &ttyb);
+       }
+    }
+#endif
+    (void) fputs(current_info->prompt, stdout);
+    (void) fflush(stdout);
+}
+
+static sigtype
+listen_int_handler()
+{
+    putc('\n', stdout);
+    longjmp(listen_jmpb, 1);
+}
+
+static sigtype print_prompt();
+
+int
+ss_listen (sci_idx)
+    int sci_idx;
+{
+    register char *cp;
+    register ss_data *info;
+    char input[BUFSIZ];
+    char expanded_input[BUFSIZ];
+    char buffer[BUFSIZ];
+    char *end = buffer;
+    int code;
+    jmp_buf old_jmpb;
+    ss_data *old_info = current_info;
+#ifndef NPOSIX
+    struct sigaction isig, csig, nsig, osig;
+    sigset_t nmask, omask;
+#else
+    register sigtype (*sig_cont)();
+    sigtype (*sig_int)(), (*old_sig_cont)();
+    int mask;
+#endif
+
+    current_info = info = ss_info(sci_idx);
+    info->abort = 0;
+#ifndef NPOSIX
+    csig.sa_handler = (sigtype (*)())0;
+    
+    sigemptyset(&nmask);
+    sigaddset(&nmask, SIGINT);
+    sigprocmask(SIG_BLOCK, &nmask, &omask);
+#else
+    sig_cont = (sigtype (*)())0;
+    mask = sigblock(sigmask(SIGINT));
+#endif
+
+    memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
+
+#ifndef NPOSIX    
+    nsig.sa_handler = listen_int_handler;
+    sigemptyset(&nsig.sa_mask);
+    nsig.sa_flags = 0;
+    sigaction(SIGINT, &nsig, &isig);
+#else
+    sig_int = signal(SIGINT, listen_int_handler);
+#endif
+
+    setjmp(listen_jmpb);
+
+#ifndef NPOSIX
+    sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
+#else
+    (void) sigsetmask(mask);
+#endif
+    while(!info->abort) {
+       print_prompt();
+       *end = '\0';
+#ifndef NPOSIX
+       nsig.sa_handler = listen_int_handler;   /* fgets is not signal-safe */
+       osig = csig;
+       sigaction(SIGCONT, &nsig, &csig);
+       if ((sigtype (*)())csig.sa_handler==(sigtype (*)())listen_int_handler)
+           csig = osig;
+#else
+       old_sig_cont = sig_cont;
+       sig_cont = signal(SIGCONT, print_prompt);
+#ifdef mips
+       /* The mips compiler breaks on determining the types, we help */
+       if ( (sigtype *) sig_cont == (sigtype *) print_prompt)
+           sig_cont = old_sig_cont;
+#else
+       if (sig_cont == print_prompt)
+           sig_cont = old_sig_cont;
+#endif
+#endif
+       if (fgets(input, BUFSIZ, stdin) != input) {
+           code = SS_ET_EOF;
+           goto egress;
+       }
+       cp = strchr(input, '\n');
+       if (cp) {
+           *cp = '\0';
+           if (cp == input)
+               continue;
+       }
+#ifndef NPOSIX
+       sigaction(SIGCONT, &csig, (struct sigaction *)0);
+#else
+       (void) signal(SIGCONT, sig_cont);
+#endif
+       for (end = input; *end; end++)
+           ;
+
+       code = ss_execute_line (sci_idx, input);
+       if (code == SS_ET_COMMAND_NOT_FOUND) {
+           register char *c = input;
+           while (*c == ' ' || *c == '\t')
+               c++;
+           cp = strchr (c, ' ');
+           if (cp)
+               *cp = '\0';
+           cp = strchr (c, '\t');
+           if (cp)
+               *cp = '\0';
+           ss_error (sci_idx, 0,
+                   "Unknown request \"%s\".  Type \"?\" for a request list.",
+                      c);
+       }
+    }
+    code = 0;
+egress:
+#ifndef NPOSIX
+    sigaction(SIGINT, &isig, (struct sigaction *)0);
+#else
+    (void) signal(SIGINT, sig_int);
+#endif
+    memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
+    current_info = old_info;
+    return code;
+}
+
+void
+ss_abort_subsystem(sci_idx, code)
+    int sci_idx;
+{
+    ss_info(sci_idx)->abort = 1;
+    ss_info(sci_idx)->exit_status = code;
+    
+}
+
+int
+ss_quit(argc, argv, sci_idx, infop)
+    int argc;
+    char **argv;
+    int sci_idx;
+    pointer infop;
+{
+    ss_abort_subsystem(sci_idx, 0);
+}
diff --git a/kerberosIV/ss/pager.c b/kerberosIV/ss/pager.c
new file mode 100644 (file)
index 0000000..f4484c0
--- /dev/null
@@ -0,0 +1,127 @@
+/*     $Id: pager.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Pager: Routines to create a "more" running out of a particular file
+ * descriptor.
+ */
+
+#include "ss_internal.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <signal.h>
+
+static char MORE[] = "more";
+extern char *_ss_pager_name;
+extern char *getenv();
+extern int errno;
+
+/*
+ * this needs a *lot* of work....
+ *
+ * run in same process
+ * handle SIGINT sensibly
+ * allow finer control -- put-page-break-here
+ */
+void ss_page_stdin();
+
+#ifndef NO_FORK
+int
+ss_pager_create() 
+{
+       int filedes[2];
+     
+       if (pipe(filedes) != 0)
+               return(-1);
+
+       switch(fork()) {
+       case -1:
+               return(-1);
+       case 0:
+               /*
+                * Child; dup read half to 0, close all but 0, 1, and 2
+                */
+               if (dup2(filedes[0], 0) == -1)
+                       exit(1);
+               ss_page_stdin();
+       default:
+               /*
+                * Parent:  close "read" side of pipe, return
+                * "write" side.
+                */
+               (void) close(filedes[0]);
+               return(filedes[1]);
+       }
+}
+#else /* don't fork */
+int
+ss_pager_create()
+{
+    int fd;
+    fd = open("/dev/tty", O_WRONLY, 0);
+    return fd;
+}
+#endif
+
+void
+ss_page_stdin()
+{
+       int i;
+#ifndef NPOSIX
+       struct sigaction sa;
+       sigset_t mask;
+#endif
+       
+       for (i = 3; i < 32; i++)
+               (void) close(i);
+#ifndef NPOSIX
+       sa.sa_handler = SIG_DFL;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = 0;
+       sigaction(SIGINT, &sa, (struct sigaction *)0);
+#else
+       (void) signal(SIGINT, SIG_DFL);
+#endif
+       {
+#ifndef NPOSIX
+               sigemptyset(&mask);
+               sigaddset(&mask, SIGINT);
+               sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)0);
+#else
+               register int mask = sigblock(0);
+               mask &= ~sigmask(SIGINT);
+               sigsetmask(mask);
+#endif
+       }
+       if (_ss_pager_name == (char *)NULL) {
+               if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL)
+                       _ss_pager_name = MORE;
+       }
+       (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
+       {
+               /* minimal recovery if pager program isn't found */
+               char buf[80];
+               register int n;
+               while ((n = read(0, buf, 80)) > 0)
+                       write(1, buf, n);
+       }
+       exit(errno);
+}
diff --git a/kerberosIV/ss/parse.c b/kerberosIV/ss/parse.c
new file mode 100644 (file)
index 0000000..6eff8ad
--- /dev/null
@@ -0,0 +1,155 @@
+/*     $Id: parse.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $  */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "ss_internal.h"
+
+#ifndef lint
+static char const rcsid[] =
+    "$Id: parse.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $";
+#endif
+
+enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
+
+/*
+ * parse(line_ptr, argc_ptr)
+ *
+ * Function:
+ *      Parses line, dividing at whitespace, into tokens, returns
+ *      the "argc" and "argv" values.
+ * Arguments:
+ *      line_ptr (char *)
+ *              Pointer to text string to be parsed.
+ *      argc_ptr (int *)
+ *              Where to put the "argc" (number of tokens) value.
+ * Returns:
+ *      argv (char **)
+ *              Series of pointers to parsed tokens.
+ */
+
+#define NEW_ARGV(old,n) (char **)realloc((char *)old,\
+                                        (unsigned)(n+2)*sizeof(char*))
+
+char **
+ss_parse (sci_idx, line_ptr, argc_ptr)
+    int sci_idx;
+    register char *line_ptr;
+    int *argc_ptr;
+{
+    register char **argv, *cp;
+    register int argc;
+    register enum parse_mode parse_mode;
+
+    *argc_ptr = 0;     /* In case of error return something sane */
+    argv = (char **) malloc (sizeof(char *));
+    if (argv == (char **)NULL) {
+       ss_error(sci_idx, errno, "Can't allocate storage");
+       return(argv);
+    }
+    *argv = (char *)NULL;
+
+    argc = 0;
+
+    parse_mode = WHITESPACE;   /* flushing whitespace */
+    cp = line_ptr;             /* cp is for output */
+    while (1) {
+#ifdef DEBUG
+       {
+           printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
+       }
+#endif
+       while (parse_mode == WHITESPACE) {
+           if (*line_ptr == '\0')
+               goto end_of_line;
+           if (*line_ptr == ' ' || *line_ptr == '\t') {
+               line_ptr++;
+               continue;
+           }
+           if (*line_ptr == '"') {
+               /* go to quoted-string mode */
+               parse_mode = QUOTED_STRING;
+               cp = line_ptr++;
+               argv = NEW_ARGV (argv, argc);
+               argv[argc++] = cp;
+               argv[argc] = NULL;
+           }
+           else {
+               /* random-token mode */
+               parse_mode = TOKEN;
+               cp = line_ptr;
+               argv = NEW_ARGV (argv, argc);
+               argv[argc++] = line_ptr;
+               argv[argc] = NULL;
+           }
+       }
+       while (parse_mode == TOKEN) {
+           if (*line_ptr == '\0') {
+               *cp++ = '\0';
+               goto end_of_line;
+           }
+           else if (*line_ptr == ' ' || *line_ptr == '\t') {
+               *cp++ = '\0';
+               line_ptr++;
+               parse_mode = WHITESPACE;
+           }
+           else if (*line_ptr == '"') {
+               line_ptr++;
+               parse_mode = QUOTED_STRING;
+           }
+           else {
+               *cp++ = *line_ptr++;
+           }
+       }
+       while (parse_mode == QUOTED_STRING) {
+           if (*line_ptr == '\0') {
+               ss_error (sci_idx, 0,
+                         "Unbalanced quotes in command line");
+               free (argv);
+               return NULL;
+           }
+           else if (*line_ptr == '"') {
+               if (*++line_ptr == '"') {
+                   *cp++ = '"';
+                   line_ptr++;
+               }
+               else {
+                   parse_mode = TOKEN;
+               }
+           }
+           else {
+               *cp++ = *line_ptr++;
+           }
+       }
+    }
+end_of_line:
+    *argc_ptr = argc;
+#ifdef DEBUG
+    {
+       int i;
+       printf ("argc = %d\n", argc);
+       for (i = 0; i <= argc; i++)
+           printf ("\targv[%2d] = `%s'\n", i,
+                   argv[i] ? argv[i] : "<NULL>");
+    }
+#endif
+    return(argv);
+}
diff --git a/kerberosIV/ss/prompt.c b/kerberosIV/ss/prompt.c
new file mode 100644 (file)
index 0000000..f4415e4
--- /dev/null
@@ -0,0 +1,43 @@
+/*     $Id: prompt.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $ */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * prompt.c: Routines for retrieving and setting a prompt.
+ */
+
+#include <stdio.h>
+#include "ss_internal.h"
+
+static const char rcsid[] =
+    "$Id: prompt.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $";
+
+int
+ss_set_prompt(sci_idx, new_prompt)
+     int sci_idx;
+     char *new_prompt;
+{
+     ss_info(sci_idx)->prompt = new_prompt;
+}
+
+char *
+ss_get_prompt(sci_idx)
+     int sci_idx;
+{
+     return(ss_info(sci_idx)->prompt);
+}
diff --git a/kerberosIV/ss/request_tbl.c b/kerberosIV/ss/request_tbl.c
new file mode 100644 (file)
index 0000000..64732d8
--- /dev/null
@@ -0,0 +1,80 @@
+/*     $Id: request_tbl.c,v 1.1.1.1 1995/12/14 06:52:47 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "ss_internal.h"
+
+#define ssrt ss_request_table  /* for some readable code... */
+
+void
+ss_add_request_table(sci_idx, rqtbl_ptr, position, code_ptr)
+       int sci_idx;
+       ssrt *rqtbl_ptr;
+       int position;           /* 1 -> becomes second... */
+       int *code_ptr;
+{
+       register ss_data *info;
+       register int i, size;
+
+       info = ss_info(sci_idx);
+       for (size=0; info->rqt_tables[size] != (ssrt *)NULL; size++)
+               ;
+       /* size == C subscript of NULL == #elements */
+       size += 2;              /* new element, and NULL */
+       info->rqt_tables = (ssrt **)realloc((char *)info->rqt_tables,
+                                           (unsigned)size*sizeof(ssrt));
+       if (info->rqt_tables == (ssrt **)NULL) {
+               *code_ptr = errno;
+               return;
+       }
+       if (position > size - 2)
+               position = size - 2;
+
+       if (size > 1)
+               for (i = size - 2; i >= position; i--)
+                       info->rqt_tables[i+1] = info->rqt_tables[i];
+
+       info->rqt_tables[position] = rqtbl_ptr;
+       info->rqt_tables[size-1] = (ssrt *)NULL;
+       *code_ptr = 0;
+}
+
+void
+ss_delete_request_table(sci_idx, rqtbl_ptr, code_ptr)
+     int sci_idx;
+     ssrt *rqtbl_ptr;
+     int *code_ptr;
+{
+     register ss_data *info;
+     register ssrt **rt1, **rt2;
+
+     *code_ptr = SS_ET_TABLE_NOT_FOUND;
+     info = ss_info(sci_idx);
+     rt1 = info->rqt_tables;
+     for (rt2 = rt1; *rt1; rt1++) {
+         if (*rt1 != rqtbl_ptr) {
+              *rt2++ = *rt1;
+              *code_ptr = 0;
+         }
+     }
+     *rt2 = (ssrt *)NULL;
+     return;
+}
diff --git a/kerberosIV/ss/requests.c b/kerberosIV/ss/requests.c
new file mode 100644 (file)
index 0000000..8484da0
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $Id: requests.c,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $       */
+
+/*-
+ * Copyright 1987, 1988, 1989 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Various minor routines...
+ */
+
+#include <stdio.h>
+#include "ss_internal.h"
+
+#define        DECLARE(name)   name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
+
+/*
+ * ss_self_identify -- assigned by default to the "." request
+ */
+DECLARE(ss_self_identify)
+{
+     register ss_data *info = ss_info(sci_idx);
+     printf("%s version %s\n", info->subsystem_name,
+           info->subsystem_version);
+}
+
+/*
+ * ss_subsystem_name -- print name of subsystem
+ */
+DECLARE(ss_subsystem_name)
+{
+     printf("%s\n", ss_info(sci_idx)->subsystem_name);
+}
+
+/*
+ * ss_subsystem_version -- print version of subsystem
+ */
+DECLARE(ss_subsystem_version)
+{
+     printf("%s\n", ss_info(sci_idx)->subsystem_version);
+}
+
+/*
+ * ss_unimplemented -- routine not implemented (should be
+ * set up as (dont_list,dont_summarize))
+ */
+DECLARE(ss_unimplemented)
+{
+     ss_perror(sci_idx, SS_ET_UNIMPLEMENTED, "");
+}
diff --git a/kerberosIV/ss/shlib_version b/kerberosIV/ss/shlib_version
new file mode 100644 (file)
index 0000000..d9961ea
--- /dev/null
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/kerberosIV/ss/ss_err.et b/kerberosIV/ss/ss_err.et
new file mode 100644 (file)
index 0000000..80e9dfa
--- /dev/null
@@ -0,0 +1,39 @@
+       error_table ss
+
+ec     SS_ET_SUBSYSTEM_ABORTED,
+       "Subsystem aborted"
+
+ec     SS_ET_VERSION_MISMATCH,
+       "Version mismatch"
+
+ec     SS_ET_NULL_INV,
+       "No current invocation"
+
+ec     SS_ET_NO_INFO_DIR,
+       "No info directory"
+
+ec     SS_ET_COMMAND_NOT_FOUND,
+       "Command not found"
+
+ec     SS_ET_LINE_ABORTED,
+       "Command line aborted"
+
+ec     SS_ET_EOF,
+       "End-of-file reached"
+
+ec     SS_ET_PERMISSION_DENIED,
+       "Permission denied"
+
+ec     SS_ET_TABLE_NOT_FOUND,
+       "Request table not found"
+
+ec     SS_ET_NO_HELP_FILE,
+       "No info available"
+
+ec     SS_ET_ESCAPE_DISABLED,
+       "Shell escapes are disabled"
+
+ec     SS_ET_UNIMPLEMENTED,
+       "Sorry, this request is not yet implemented"
+
+       end
diff --git a/kerberosIV/ss/ss_internal.h b/kerberosIV/ss/ss_internal.h
new file mode 100644 (file)
index 0000000..2c9e915
--- /dev/null
@@ -0,0 +1,130 @@
+/*     $Id: ss_internal.h,v 1.1.1.1 1995/12/14 06:52:46 tholo Exp $    */
+
+/*-
+ * Copyright 1987, 1988 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+#ifndef _ss_ss_internal_h
+#define _ss_ss_internal_h __FILE__
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __STDC__
+
+#define PROTOTYPE(p) p
+typedef void * pointer;
+
+#else
+
+#define const
+#define volatile
+#define PROTOTYPE(p) ()
+typedef char * pointer;
+
+#endif /* not __STDC__ */
+
+#include <ss/ss.h>
+
+#if defined(__GNUC__)
+#define LOCAL_ALLOC(x) __builtin_alloca(x)
+#define LOCAL_FREE(x)
+#else
+#if defined(vax)
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+#if defined(__HIGHC__) /* Barf! */
+pragma on(alloca);
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+/* no alloca? */
+#define LOCAL_ALLOC(x) malloc(x)
+#define LOCAL_FREE(x) free(x)
+#endif
+#endif
+#endif                         /* LOCAL_ALLOC stuff */
+
+typedef char BOOL;
+
+typedef struct _ss_abbrev_entry {
+    char *name;                        /* abbrev name */
+    char **abbrev;             /* new tokens to insert */
+    int beginning_of_line : 1;
+} ss_abbrev_entry;
+
+typedef struct _ss_abbrev_list {
+    int n_abbrevs;
+    ss_abbrev_entry *first_abbrev;
+} ss_abbrev_list;
+
+typedef struct {
+/*    char *path; */
+    ss_abbrev_list abbrevs[127];
+} ss_abbrev_info;
+
+typedef struct _ss_data {      /* init values */
+    /* this subsystem */
+    char *subsystem_name;
+    char *subsystem_version;
+    /* current request info */
+    int argc;
+    char **argv;               /* arg list */
+    char const *current_request; /* primary name */
+    /* info directory for 'help' */
+    char **info_dirs;
+    /* to be extracted by subroutines */
+    pointer info_ptr;          /* (void *) NULL */
+    /* for ss_listen processing */
+    char *prompt;
+    ss_request_table **rqt_tables;
+    ss_abbrev_info *abbrev_info;
+    struct {
+       int escape_disabled : 1,
+           abbrevs_disabled : 1;
+    } flags;
+    /* to get out */
+    int abort;                 /* exit subsystem */
+    int exit_status;
+} ss_data;
+
+#define CURRENT_SS_VERSION 1
+
+#define        ss_info(sci_idx)        (_ss_table[sci_idx])
+#define        ss_current_request(sci_idx,code_ptr)    \
+     (*code_ptr=0,ss_info(sci_idx)->current_request)
+void ss_unknown_function();
+void ss_delete_info_dir();
+int ss_execute_line();
+char **ss_parse();
+ss_abbrev_info *ss_abbrev_initialize PROTOTYPE((char *, int *));
+void ss_page_stdin();
+
+extern ss_data **_ss_table;
+extern char *ss_et_msgs[];
+
+#if 0
+extern pointer malloc PROTOTYPE((unsigned));
+extern pointer realloc PROTOTYPE((pointer, unsigned));
+extern pointer calloc PROTOTYPE((unsigned, unsigned));
+#ifndef sun
+extern int exit PROTOTYPE((int));
+#endif
+#endif /* 0 */
+
+#endif /* _ss_internal_h */
diff --git a/kerberosIV/ss/std_rqs.ct b/kerberosIV/ss/std_rqs.ct
new file mode 100644 (file)
index 0000000..500288a
--- /dev/null
@@ -0,0 +1,46 @@
+       command_table   ss_std_requests;
+
+       request ss_self_identify, "Identify the subsystem.",
+               ".",
+               (dont_list, dont_summarize);
+
+       request ss_help, "Display info on command or topic.",
+               help;
+
+       unimplemented
+               ss_list_help,
+               "List topics for which help is available.",
+               list_help, lh;
+
+       request ss_list_requests, "List available commands.",
+               list_requests, lr, "?";
+
+       request ss_quit, "Leave the subsystem.",
+               quit, q;
+
+       unimplemented
+               ss_abbrev,
+               "Enable/disable abbreviation processing of request lines.",
+               abbrev, ab;
+
+       unimplemented
+               ss_execute,
+               "Execute a UNIX command line.",
+               execute, e;
+
+       unimplemented
+               ss_summarize_requests,
+               "Produce a list of the most commonly used requests.",
+               "?";
+               
+       request ss_subsystem_name,
+               "Return the name of this subsystem.",
+               subsystem_name,
+               (dont_list);
+
+       request ss_subsystem_version,
+               "Return the version of this subsystem.",
+               subsystem_version,
+               (dont_list);
+
+       end;