summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eBones/ARTISTIC.libdes105
-rw-r--r--eBones/Copyright.MIT24
-rw-r--r--eBones/Copyright.SIPB23
-rw-r--r--eBones/Makefile25
-rw-r--r--eBones/Makefile.inc37
-rw-r--r--eBones/README.libdes56
-rw-r--r--eBones/acl/Makefile10
-rw-r--r--eBones/acl/acl_check.3183
-rw-r--r--eBones/acl/acl_files.c541
-rw-r--r--eBones/acl/acl_files.doc107
-rw-r--r--eBones/compile_et/Makefile15
-rw-r--r--eBones/compile_et/compile_et.c172
-rw-r--r--eBones/compile_et/error_message.c77
-rw-r--r--eBones/compile_et/error_table.h17
-rw-r--r--eBones/compile_et/error_table.y205
-rw-r--r--eBones/compile_et/et_lex.lex.l29
-rw-r--r--eBones/compile_et/et_name.c44
-rw-r--r--eBones/compile_et/init_et.c67
-rw-r--r--eBones/compile_et/perror.c76
-rw-r--r--eBones/compile_et/test/test.c43
-rw-r--r--eBones/compile_et/test/test1.et69
-rw-r--r--eBones/compile_et/test/test2.et9
-rw-r--r--eBones/des/3cbc_enc.c58
-rw-r--r--eBones/des/3ecb_enc.c35
-rw-r--r--eBones/des/MISSING17
-rw-r--r--eBones/des/Makefile27
-rw-r--r--eBones/des/cbc_cksm.c55
-rw-r--r--eBones/des/cbc_enc.c83
-rw-r--r--eBones/des/cfb_enc.c110
-rw-r--r--eBones/des/des.3503
-rw-r--r--eBones/des/docs.original/ARTISTIC105
-rw-r--r--eBones/des/docs.original/CHANGES16
-rw-r--r--eBones/des/docs.original/COPYING489
-rw-r--r--eBones/des/docs.original/FILES60
-rw-r--r--eBones/des/docs.original/INSTALL53
-rw-r--r--eBones/des/docs.original/KERBEROS38
-rw-r--r--eBones/des/docs.original/MODES.DES84
-rw-r--r--eBones/des/docs.original/README56
-rw-r--r--eBones/des/docs.original/VERSION185
-rw-r--r--eBones/des/ecb_enc.c123
-rw-r--r--eBones/des/enc_read.c147
-rw-r--r--eBones/des/enc_writ.c94
-rw-r--r--eBones/des/fcrypt.c581
-rw-r--r--eBones/des/include/des.h121
-rw-r--r--eBones/des/include/des_locl.h186
-rw-r--r--eBones/des/include/podd.h24
-rw-r--r--eBones/des/include/sk.h145
-rw-r--r--eBones/des/include/spr.h151
-rw-r--r--eBones/des/ofb_enc.c72
-rw-r--r--eBones/des/pcbc_enc.c78
-rw-r--r--eBones/des/qud_cksm.c93
-rw-r--r--eBones/des/rand_key.c45
-rw-r--r--eBones/des/read_pwd.c333
-rw-r--r--eBones/des/set_key.c190
-rw-r--r--eBones/des/str2key.c121
-rw-r--r--eBones/des/test/Makefile9
-rw-r--r--eBones/des/test/destest.c365
-rw-r--r--eBones/ext_srvtab/Makefile10
-rw-r--r--eBones/ext_srvtab/ext_srvtab.863
-rw-r--r--eBones/ext_srvtab/ext_srvtab.c164
-rw-r--r--eBones/include/ChangeLog25
-rw-r--r--eBones/include/Makefile17
-rw-r--r--eBones/include/addr_comp.h35
-rw-r--r--eBones/include/admin_server.h42
-rw-r--r--eBones/include/conf-bsd386i.h16
-rw-r--r--eBones/include/conf-bsdapollo.h21
-rw-r--r--eBones/include/conf-bsdibm032.h18
-rw-r--r--eBones/include/conf-bsdm68k.h16
-rw-r--r--eBones/include/conf-bsdsparc.h17
-rw-r--r--eBones/include/conf-bsdtahoe.h16
-rw-r--r--eBones/include/conf-bsdvax.h22
-rw-r--r--eBones/include/conf-ibm370.h15
-rw-r--r--eBones/include/conf-pc.h16
-rw-r--r--eBones/include/conf-pyr.h15
-rw-r--r--eBones/include/conf-ultmips2.h17
-rw-r--r--eBones/include/conf.h73
-rw-r--r--eBones/include/des.h44
-rw-r--r--eBones/include/highc.h32
-rw-r--r--eBones/include/kadm.h138
-rw-r--r--eBones/include/kdc.h36
-rw-r--r--eBones/include/klog.h39
-rw-r--r--eBones/include/kparse.h87
-rw-r--r--eBones/include/krb.h376
-rw-r--r--eBones/include/krb_conf.h29
-rw-r--r--eBones/include/krb_db.h100
-rw-r--r--eBones/include/lsb_addr_comp.h40
-rw-r--r--eBones/include/osconf.h51
-rw-r--r--eBones/include/passwd_server.h28
-rw-r--r--eBones/include/principal.h18
-rw-r--r--eBones/include/prot.h92
-rw-r--r--eBones/kadmin/kadmin.8158
-rw-r--r--eBones/kadmind/kadmind.8117
-rw-r--r--eBones/kdb/Makefile11
-rw-r--r--eBones/kdb/krb_cache.c193
-rw-r--r--eBones/kdb/krb_dbl.c1
-rw-r--r--eBones/kdb/krb_dbm.c741
-rw-r--r--eBones/kdb/krb_kdb_utils.c141
-rw-r--r--eBones/kdb/krb_lib.c242
-rw-r--r--eBones/kdb/print_princ.c50
-rw-r--r--eBones/kdb_destroy/Makefile8
-rw-r--r--eBones/kdb_destroy/kdb_destroy.833
-rw-r--r--eBones/kdb_destroy/kdb_destroy.c45
-rw-r--r--eBones/kdb_edit/Makefile12
-rw-r--r--eBones/kdb_edit/kdb_edit.855
-rw-r--r--eBones/kdb_edit/kdb_edit.c470
-rw-r--r--eBones/kdb_edit/maketime.c83
-rw-r--r--eBones/kdb_edit/time.h45
-rw-r--r--eBones/kdb_init/Makefile10
-rw-r--r--eBones/kdb_init/kdb_init.841
-rw-r--r--eBones/kdb_init/kdb_init.c178
-rw-r--r--eBones/kdb_util/Makefile13
-rw-r--r--eBones/kdb_util/kdb_util.864
-rw-r--r--eBones/kdb_util/kdb_util.c506
-rw-r--r--eBones/kdestroy/Makefile11
-rw-r--r--eBones/kdestroy/kdestroy.181
-rw-r--r--eBones/kdestroy/kdestroy.c78
-rw-r--r--eBones/kerberos/Makefile11
-rw-r--r--eBones/kerberos/cr_err_reply.c95
-rw-r--r--eBones/kerberos/kerberos.c810
-rw-r--r--eBones/kinit/Makefile11
-rw-r--r--eBones/kinit/kinit.1133
-rw-r--r--eBones/kinit/kinit.c214
-rw-r--r--eBones/klist/Makefile11
-rw-r--r--eBones/klist/klist.184
-rw-r--r--eBones/klist/klist.c275
-rw-r--r--eBones/krb/Makefile31
-rw-r--r--eBones/krb/add_ticket.c88
-rw-r--r--eBones/krb/create_auth_reply.c116
-rw-r--r--eBones/krb/create_ciph.c109
-rw-r--r--eBones/krb/create_death_packet.c63
-rw-r--r--eBones/krb/create_ticket.c130
-rw-r--r--eBones/krb/debug_decl.c18
-rw-r--r--eBones/krb/decomp_ticket.c123
-rw-r--r--eBones/krb/des_rw.c265
-rw-r--r--eBones/krb/dest_tkt.c87
-rw-r--r--eBones/krb/extract_ticket.c58
-rw-r--r--eBones/krb/fgetst.c39
-rw-r--r--eBones/krb/get_ad_tkt.c234
-rw-r--r--eBones/krb/get_admhst.c79
-rw-r--r--eBones/krb/get_cred.c60
-rw-r--r--eBones/krb/get_in_tkt.c288
-rw-r--r--eBones/krb/get_krbhst.c84
-rw-r--r--eBones/krb/get_krbrlm.c59
-rw-r--r--eBones/krb/get_phost.c53
-rw-r--r--eBones/krb/get_pw_tkt.c72
-rw-r--r--eBones/krb/get_request.c52
-rw-r--r--eBones/krb/get_svc_in_tkt.c73
-rw-r--r--eBones/krb/get_tf_fullname.c66
-rw-r--r--eBones/krb/get_tf_realm.c34
-rw-r--r--eBones/krb/getrealm.c104
-rw-r--r--eBones/krb/getst.c35
-rw-r--r--eBones/krb/in_tkt.c142
-rw-r--r--eBones/krb/k_gethostname.c65
-rw-r--r--eBones/krb/klog.c108
-rw-r--r--eBones/krb/kname_parse.c233
-rw-r--r--eBones/krb/kntoln.c60
-rw-r--r--eBones/krb/kparse.c763
-rw-r--r--eBones/krb/krb_err.et257
-rw-r--r--eBones/krb/krb_err_txt.c278
-rw-r--r--eBones/krb/krb_get_in_tkt.c297
-rw-r--r--eBones/krb/krb_realmofhost.3161
-rw-r--r--eBones/krb/krb_sendauth.3348
-rw-r--r--eBones/krb/krb_set_tkt_string.343
-rw-r--r--eBones/krb/krbglue.c252
-rw-r--r--eBones/krb/kuserok.363
-rw-r--r--eBones/krb/kuserok.c195
-rw-r--r--eBones/krb/log.c121
-rw-r--r--eBones/krb/mk_err.c63
-rw-r--r--eBones/krb/mk_priv.c203
-rw-r--r--eBones/krb/mk_req.c195
-rw-r--r--eBones/krb/mk_safe.c168
-rw-r--r--eBones/krb/month_sname.c31
-rw-r--r--eBones/krb/netread.c46
-rw-r--r--eBones/krb/netwrite.c42
-rw-r--r--eBones/krb/one.c20
-rw-r--r--eBones/krb/pkt_cipher.c38
-rw-r--r--eBones/krb/pkt_clen.c53
-rw-r--r--eBones/krb/rd_err.c79
-rw-r--r--eBones/krb/rd_priv.c204
-rw-r--r--eBones/krb/rd_req.c328
-rw-r--r--eBones/krb/rd_safe.c180
-rw-r--r--eBones/krb/read_service_key.c120
-rw-r--r--eBones/krb/recvauth.c286
-rw-r--r--eBones/krb/save_credentials.c53
-rw-r--r--eBones/krb/send_to_kdc.c313
-rw-r--r--eBones/krb/sendauth.c257
-rw-r--r--eBones/krb/stime.c40
-rw-r--r--eBones/krb/tf_shm.c174
-rw-r--r--eBones/krb/tf_util.3151
-rw-r--r--eBones/krb/tf_util.c572
-rw-r--r--eBones/krb/tkt_string.c79
-rw-r--r--eBones/krb/util.c72
-rw-r--r--eBones/ksrvtgt/Makefile11
-rw-r--r--eBones/ksrvtgt/ksrvtgt.151
-rw-r--r--eBones/ksrvtgt/ksrvtgt.c60
-rw-r--r--eBones/ksrvutil/ksrvutil.893
-rw-r--r--eBones/kstash/Makefile10
-rw-r--r--eBones/kstash/kstash.841
-rw-r--r--eBones/kstash/kstash.c92
-rw-r--r--eBones/lib/libacl/Makefile10
-rw-r--r--eBones/lib/libacl/acl_check.3183
-rw-r--r--eBones/lib/libacl/acl_files.c541
-rw-r--r--eBones/lib/libacl/acl_files.doc107
-rw-r--r--eBones/lib/libkdb/Makefile11
-rw-r--r--eBones/lib/libkdb/krb_cache.c193
-rw-r--r--eBones/lib/libkdb/krb_dbl.c1
-rw-r--r--eBones/lib/libkdb/krb_dbm.c741
-rw-r--r--eBones/lib/libkdb/krb_kdb_utils.c141
-rw-r--r--eBones/lib/libkdb/krb_lib.c242
-rw-r--r--eBones/lib/libkdb/print_princ.c50
-rw-r--r--eBones/lib/libkrb/Makefile31
-rw-r--r--eBones/lib/libkrb/add_ticket.c88
-rw-r--r--eBones/lib/libkrb/create_auth_reply.c116
-rw-r--r--eBones/lib/libkrb/create_ciph.c109
-rw-r--r--eBones/lib/libkrb/create_death_packet.c63
-rw-r--r--eBones/lib/libkrb/create_ticket.c130
-rw-r--r--eBones/lib/libkrb/debug_decl.c18
-rw-r--r--eBones/lib/libkrb/decomp_ticket.c123
-rw-r--r--eBones/lib/libkrb/des_rw.c265
-rw-r--r--eBones/lib/libkrb/dest_tkt.c87
-rw-r--r--eBones/lib/libkrb/extract_ticket.c58
-rw-r--r--eBones/lib/libkrb/fgetst.c39
-rw-r--r--eBones/lib/libkrb/get_ad_tkt.c234
-rw-r--r--eBones/lib/libkrb/get_admhst.c79
-rw-r--r--eBones/lib/libkrb/get_cred.c60
-rw-r--r--eBones/lib/libkrb/get_in_tkt.c288
-rw-r--r--eBones/lib/libkrb/get_krbhst.c84
-rw-r--r--eBones/lib/libkrb/get_krbrlm.c59
-rw-r--r--eBones/lib/libkrb/get_phost.c53
-rw-r--r--eBones/lib/libkrb/get_pw_tkt.c72
-rw-r--r--eBones/lib/libkrb/get_request.c52
-rw-r--r--eBones/lib/libkrb/get_svc_in_tkt.c73
-rw-r--r--eBones/lib/libkrb/get_tf_fullname.c66
-rw-r--r--eBones/lib/libkrb/get_tf_realm.c34
-rw-r--r--eBones/lib/libkrb/getrealm.c104
-rw-r--r--eBones/lib/libkrb/getst.c35
-rw-r--r--eBones/lib/libkrb/in_tkt.c142
-rw-r--r--eBones/lib/libkrb/k_gethostname.c65
-rw-r--r--eBones/lib/libkrb/klog.c108
-rw-r--r--eBones/lib/libkrb/kname_parse.c233
-rw-r--r--eBones/lib/libkrb/kntoln.c60
-rw-r--r--eBones/lib/libkrb/kparse.c763
-rw-r--r--eBones/lib/libkrb/krb_err.et257
-rw-r--r--eBones/lib/libkrb/krb_err_txt.c278
-rw-r--r--eBones/lib/libkrb/krb_get_in_tkt.c297
-rw-r--r--eBones/lib/libkrb/krb_realmofhost.3161
-rw-r--r--eBones/lib/libkrb/krb_sendauth.3348
-rw-r--r--eBones/lib/libkrb/krb_set_tkt_string.343
-rw-r--r--eBones/lib/libkrb/krbglue.c252
-rw-r--r--eBones/lib/libkrb/kuserok.363
-rw-r--r--eBones/lib/libkrb/kuserok.c195
-rw-r--r--eBones/lib/libkrb/log.c121
-rw-r--r--eBones/lib/libkrb/mk_err.c63
-rw-r--r--eBones/lib/libkrb/mk_priv.c203
-rw-r--r--eBones/lib/libkrb/mk_req.c195
-rw-r--r--eBones/lib/libkrb/mk_safe.c168
-rw-r--r--eBones/lib/libkrb/month_sname.c31
-rw-r--r--eBones/lib/libkrb/netread.c46
-rw-r--r--eBones/lib/libkrb/netwrite.c42
-rw-r--r--eBones/lib/libkrb/one.c20
-rw-r--r--eBones/lib/libkrb/pkt_cipher.c38
-rw-r--r--eBones/lib/libkrb/pkt_clen.c53
-rw-r--r--eBones/lib/libkrb/rd_err.c79
-rw-r--r--eBones/lib/libkrb/rd_priv.c204
-rw-r--r--eBones/lib/libkrb/rd_req.c328
-rw-r--r--eBones/lib/libkrb/rd_safe.c180
-rw-r--r--eBones/lib/libkrb/read_service_key.c120
-rw-r--r--eBones/lib/libkrb/recvauth.c286
-rw-r--r--eBones/lib/libkrb/save_credentials.c53
-rw-r--r--eBones/lib/libkrb/send_to_kdc.c313
-rw-r--r--eBones/lib/libkrb/sendauth.c257
-rw-r--r--eBones/lib/libkrb/stime.c40
-rw-r--r--eBones/lib/libkrb/tf_shm.c174
-rw-r--r--eBones/lib/libkrb/tf_util.3151
-rw-r--r--eBones/lib/libkrb/tf_util.c572
-rw-r--r--eBones/lib/libkrb/tkt_string.c79
-rw-r--r--eBones/lib/libkrb/util.c72
-rw-r--r--eBones/libexec/registerd/Makefile20
-rw-r--r--eBones/libexec/registerd/registerd.869
-rw-r--r--eBones/libexec/registerd/registerd.c341
-rw-r--r--eBones/make_keypair/Makefile9
-rw-r--r--eBones/make_keypair/make_keypair.887
-rw-r--r--eBones/make_keypair/make_keypair.c131
-rw-r--r--eBones/man/Makefile19
-rw-r--r--eBones/man/acl_check.3183
-rw-r--r--eBones/man/des.point1
-rw-r--r--eBones/man/des_crypt.3380
-rw-r--r--eBones/man/ext_srvtab.863
-rw-r--r--eBones/man/kadmin.8158
-rw-r--r--eBones/man/kadmind.8117
-rw-r--r--eBones/man/kdb_destroy.833
-rw-r--r--eBones/man/kdb_edit.855
-rw-r--r--eBones/man/kdb_init.841
-rw-r--r--eBones/man/kdb_util.864
-rw-r--r--eBones/man/kdestroy.181
-rw-r--r--eBones/man/kerberos.1259
-rw-r--r--eBones/man/kerberos.3461
-rw-r--r--eBones/man/kerberos.point1
-rw-r--r--eBones/man/kinit.1133
-rw-r--r--eBones/man/klist.184
-rw-r--r--eBones/man/klogind.8122
-rw-r--r--eBones/man/kpasswd.186
-rw-r--r--eBones/man/krb.conf.532
-rw-r--r--eBones/man/krb.realms.539
-rw-r--r--eBones/man/krb_realmofhost.3161
-rw-r--r--eBones/man/krb_sendauth.3348
-rw-r--r--eBones/man/krb_set_tkt_string.343
-rw-r--r--eBones/man/ksend.point1
-rw-r--r--eBones/man/kshd.8152
-rw-r--r--eBones/man/ksrvtgt.151
-rw-r--r--eBones/man/ksrvutil.893
-rw-r--r--eBones/man/kstash.841
-rw-r--r--eBones/man/ksu.183
-rw-r--r--eBones/man/kuserok.363
-rw-r--r--eBones/man/rcp.1129
-rw-r--r--eBones/man/realm.point1
-rw-r--r--eBones/man/rlogin.1199
-rw-r--r--eBones/man/rsh.1152
-rw-r--r--eBones/man/tcom.854
-rw-r--r--eBones/man/tf_util.3151
-rw-r--r--eBones/man/tftp.166
-rw-r--r--eBones/man/tftpd.839
-rw-r--r--eBones/patchlevel.h6
-rw-r--r--eBones/register/Makefile14
-rw-r--r--eBones/register/pathnames.h39
-rw-r--r--eBones/register/register.163
-rw-r--r--eBones/register/register.c311
-rw-r--r--eBones/register/register_proto.h43
-rw-r--r--eBones/registerd/Makefile20
-rw-r--r--eBones/registerd/registerd.869
-rw-r--r--eBones/registerd/registerd.c341
-rw-r--r--eBones/usr.bin/kadmin/kadmin.8158
-rw-r--r--eBones/usr.bin/kdestroy/Makefile11
-rw-r--r--eBones/usr.bin/kdestroy/kdestroy.181
-rw-r--r--eBones/usr.bin/kdestroy/kdestroy.c78
-rw-r--r--eBones/usr.bin/kinit/Makefile11
-rw-r--r--eBones/usr.bin/kinit/kinit.1133
-rw-r--r--eBones/usr.bin/kinit/kinit.c214
-rw-r--r--eBones/usr.bin/klist/Makefile11
-rw-r--r--eBones/usr.bin/klist/klist.184
-rw-r--r--eBones/usr.bin/klist/klist.c275
-rw-r--r--eBones/usr.bin/ksrvtgt/Makefile11
-rw-r--r--eBones/usr.bin/ksrvtgt/ksrvtgt.151
-rw-r--r--eBones/usr.bin/ksrvtgt/ksrvtgt.c60
-rw-r--r--eBones/usr.bin/register/Makefile14
-rw-r--r--eBones/usr.bin/register/pathnames.h39
-rw-r--r--eBones/usr.bin/register/register.163
-rw-r--r--eBones/usr.bin/register/register.c311
-rw-r--r--eBones/usr.bin/register/register_proto.h43
-rw-r--r--eBones/usr.sbin/ext_srvtab/Makefile10
-rw-r--r--eBones/usr.sbin/ext_srvtab/ext_srvtab.863
-rw-r--r--eBones/usr.sbin/ext_srvtab/ext_srvtab.c164
-rw-r--r--eBones/usr.sbin/kadmin/kadmind.8117
-rw-r--r--eBones/usr.sbin/kadmind/kadmind.8117
-rw-r--r--eBones/usr.sbin/kdb_destroy/Makefile8
-rw-r--r--eBones/usr.sbin/kdb_destroy/kdb_destroy.833
-rw-r--r--eBones/usr.sbin/kdb_destroy/kdb_destroy.c45
-rw-r--r--eBones/usr.sbin/kdb_edit/Makefile12
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.855
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.c470
-rw-r--r--eBones/usr.sbin/kdb_edit/maketime.c83
-rw-r--r--eBones/usr.sbin/kdb_edit/time.h45
-rw-r--r--eBones/usr.sbin/kdb_init/Makefile10
-rw-r--r--eBones/usr.sbin/kdb_init/kdb_init.841
-rw-r--r--eBones/usr.sbin/kdb_init/kdb_init.c178
-rw-r--r--eBones/usr.sbin/kdb_util/Makefile13
-rw-r--r--eBones/usr.sbin/kdb_util/kdb_util.864
-rw-r--r--eBones/usr.sbin/kdb_util/kdb_util.c506
-rw-r--r--eBones/usr.sbin/kerberos/Makefile11
-rw-r--r--eBones/usr.sbin/kerberos/cr_err_reply.c95
-rw-r--r--eBones/usr.sbin/kerberos/kerberos.c810
-rw-r--r--eBones/usr.sbin/ksrvutil/ksrvutil.893
-rw-r--r--eBones/usr.sbin/kstash/Makefile10
-rw-r--r--eBones/usr.sbin/kstash/kstash.841
-rw-r--r--eBones/usr.sbin/kstash/kstash.c92
-rw-r--r--eBones/usr.sbin/make_keypair/Makefile9
-rw-r--r--eBones/usr.sbin/make_keypair/make_keypair.887
-rw-r--r--eBones/usr.sbin/make_keypair/make_keypair.c131
-rw-r--r--usr.bin/compile_et/Makefile15
-rw-r--r--usr.bin/compile_et/compile_et.c172
-rw-r--r--usr.bin/compile_et/error_message.c77
-rw-r--r--usr.bin/compile_et/error_table.h17
-rw-r--r--usr.bin/compile_et/error_table.y205
-rw-r--r--usr.bin/compile_et/et_lex.lex.l29
-rw-r--r--usr.bin/compile_et/et_name.c44
-rw-r--r--usr.bin/compile_et/init_et.c67
-rw-r--r--usr.bin/compile_et/perror.c76
-rw-r--r--usr.bin/compile_et/test/test.c43
-rw-r--r--usr.bin/compile_et/test/test1.et69
-rw-r--r--usr.bin/compile_et/test/test2.et9
390 files changed, 46955 insertions, 0 deletions
diff --git a/eBones/ARTISTIC.libdes b/eBones/ARTISTIC.libdes
new file mode 100644
index 0000000..b382657
--- /dev/null
+++ b/eBones/ARTISTIC.libdes
@@ -0,0 +1,105 @@
+
+ The "Artistic License"
+
+ Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.
+
+6. Any programs linked with this library do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+
+7. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+8. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
+
diff --git a/eBones/Copyright.MIT b/eBones/Copyright.MIT
new file mode 100644
index 0000000..28dd55f
--- /dev/null
+++ b/eBones/Copyright.MIT
@@ -0,0 +1,24 @@
+# $Id: Copyright.MIT,v 1.2 1994/07/19 19:21:03 g89r4222 Exp $
+
+The following Copyright notice applies to the original Bones package.
+
+/*-
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
diff --git a/eBones/Copyright.SIPB b/eBones/Copyright.SIPB
new file mode 100644
index 0000000..c116ad2
--- /dev/null
+++ b/eBones/Copyright.SIPB
@@ -0,0 +1,23 @@
+# $Id: Copyright.SIPB,v 1.2 1994/07/19 19:21:05 g89r4222 Exp $
+
+The following Copyright notice applies to parts of the Bones package.
+See source code for exact references.
+
+/*-
+Copyright 1987 by the Student Information Processing Board
+ of the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice
+appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation,
+and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+M.I.T. and the M.I.T. S.I.P.B. make no representations about
+the suitability of this software for any purpose. It is
+provided "as is" without express or implied warranty.
+
+ */
+
diff --git a/eBones/Makefile b/eBones/Makefile
new file mode 100644
index 0000000..b63f933
--- /dev/null
+++ b/eBones/Makefile
@@ -0,0 +1,25 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.12 1994/09/30 13:34:39 g89r4222 Exp $
+
+SUBDIR= include
+
+SUBDIR+= des compile_et acl ext_srvtab include kdb kdb_destroy kdb_edit \
+ kdb_init kdb_util kdestroy kerberos kinit klist krb ksrvtgt \
+ kstash man register registerd make_keypair
+
+SDIR= ${.CURDIR}/..
+
+# These are the programs which depend on kerberos
+# It's nice to know who they are
+kprog:
+ cd ${SDIR}/bin/rcp; make cleandir obj ; make -DNOMAN depend all install
+ cd ${SDIR}/libexec/rlogind;make cleandir;make -DNOMAN depend all install
+ cd ${SDIR}/libexec/rshd; make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/usr.bin/login; make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/usr.bin/passwd;make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/usr.bin/rlogin;make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/usr.bin/rsh; make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/usr.bin/su; make cleandir; make -DNOMAN depend all install
+ cd ${SDIR}/libexec/kpasswdd; make cleandir; make depend all install
+
+.include <bsd.subdir.mk>
diff --git a/eBones/Makefile.inc b/eBones/Makefile.inc
new file mode 100644
index 0000000..fc75f4b
--- /dev/null
+++ b/eBones/Makefile.inc
@@ -0,0 +1,37 @@
+# From: @(#)Makefile.inc 5.1 (Berkeley) 6/25/90
+# $Id: Makefile.inc,v 1.3 1994/09/24 14:04:08 g89r4222 Exp $
+
+BINDIR?= /usr/sbin
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
+
+.if exists(${.CURDIR}/../des/obj)
+DESOBJDIR= ${.CURDIR}/../des/obj
+.else
+DESOBJDIR= ${.CURDIR}/../des
+.endif
+
+.if exists(${.CURDIR}/../krb/obj)
+KRBOBJDIR= ${.CURDIR}/../krb/obj
+.else
+KRBOBJDIR= ${.CURDIR}/../krb
+.endif
+
+.if exists(${.CURDIR}/../kdb/obj)
+KDBOBJDIR= ${.CURDIR}/../kdb/obj
+.else
+KDBOBJDIR= ${.CURDIR}/../kdb
+.endif
+
+.if exists(${.CURDIR}/../acl/obj)
+ACLOBJDIR= ${.CURDIR}/../acl/obj
+.else
+ACLOBJDIR= ${.CURDIR}/../acl
+.endif
+
+.if exists(${.CURDIR}/../compile_et/obj)
+COMPILE_ET= ${.CURDIR}/../compile_et/obj/compile_et
+.else
+COMPILE_ET= ${.CURDIR}/../compile_et/compile_et
+.endif
+
diff --git a/eBones/README.libdes b/eBones/README.libdes
new file mode 100644
index 0000000..6acd62c
--- /dev/null
+++ b/eBones/README.libdes
@@ -0,0 +1,56 @@
+
+ libdes, Version 3.00 93/10/07
+
+ Copyright (c) 1993, Eric Young
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of either:
+
+ a) the GNU General Public License as published by the Free
+ Software Foundation; either version 1, or (at your option) any
+ later version, or
+
+ b) the "Artistic License" which comes with this Kit.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
+ the GNU General Public License or the Artistic License for more details.
+
+ You should have received a copy of the Artistic License with this
+ Kit, in the file named "Artistic". If not, I'll be glad to provide one.
+
+ You should also have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+---
+This kit builds a DES encryption library and a DES encryption program.
+It suports ecb, cbc, ofb, cfb, triple ecb, triple cbc and MIT's pcbc
+encryption modes and also has a fast implementation of crypt(3).
+It contains support routines to read keys from a terminal,
+generate a random key, generate a key from an arbitary length string,
+read/write encrypted data from/to a file descriptor.
+
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+destest should be run after compilation to test the des routines.
+rpw should be run after compilation to test the read password routines.
+The des program is a replacement for the sun des command. I believe it
+conforms to the sun version.
+
+The Imakefile is setup for use in the kerberos distribution.
+
+These routines are best compiled with gcc or any other good
+optimising compiler.
+Just turn you optimiser up to the highest settings and run destest
+after the build to make sure everything works.
+
+I believe these routines are close to the fastest and most portable DES
+routines that use small lookup tables (4.5k) that are publicly available.
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
+(on a sun3/260 168 vs 336).
+
+Eric Young (eay@psych.psy.uq.oz.au)
diff --git a/eBones/acl/Makefile b/eBones/acl/Makefile
new file mode 100644
index 0000000..77c9a01
--- /dev/null
+++ b/eBones/acl/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.3 1994/09/09 21:43:17 g89r4222 Exp $
+
+LIB= acl
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-DDEBUG -DKERBEROS -I${.CURDIR}/../include
+SRCS= acl_files.c
+
+.include <bsd.lib.mk>
diff --git a/eBones/acl/acl_check.3 b/eBones/acl/acl_check.3
new file mode 100644
index 0000000..c142506
--- /dev/null
+++ b/eBones/acl/acl_check.3
@@ -0,0 +1,183 @@
+.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $
+.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+acl_canonicalize_principal, acl_check, acl_exact_match, acl_add,
+acl_delete, acl_initialize \- Access control list routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+cc <files> \-lacl \-lkrb
+.PP
+.ft B
+#include <krb.h>
+.PP
+.ft B
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf;
+.PP
+.ft B
+acl_check(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_add(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_initialize(acl_file, mode)
+char *acl_file;
+int mode;
+.fi
+.ft R
+.SH DESCRIPTION
+.SS Introduction
+.PP
+An access control list (ACL) is a list of principals, where each
+principal is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+.PP
+.SS Principal Names
+.PP
+Principal names have the form
+.nf
+.in +5n
+<name>[.<instance>][@<realm>]
+.in -5n
+e.g.:
+.in +5n
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+.in -5n
+.fi
+It is possible for principals to be underspecified. If an instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be the local realm as determined by
+.IR krb_get_lrealm (3).
+The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+.SS Routines
+.PP
+.I acl_canonicalize_principal
+stores the canonical form of
+.I principal
+in
+.IR buf .
+.I Buf
+must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ,
+respectively, in
+.IR /usr/include/krb.h .
+.PP
+.I acl_check
+returns nonzero if
+.I principal
+appears in
+.IR acl .
+Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards. The
+only supported wildcards are entries of the form
+name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the
+its component field. For example, "jtkohl.*@*" would match principal
+jtkohl, with any instance and any realm.
+.PP
+.I acl_exact_match
+performs like
+.IR acl_check ,
+but does no canonicalization or wildcard matching.
+.PP
+.I acl_add
+atomically adds
+.I principal
+to
+.IR acl .
+Returns 0 if successful, nonzero otherwise. It is considered a failure
+if
+.I principal
+is already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_delete
+atomically deletes
+.I principal
+from
+.IR acl .
+Returns 0 if successful,
+nonzero otherwise. It is considered a failure if
+.I principal
+is not
+already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_initialize
+initializes
+.IR acl_file .
+If the file
+.I acl_file
+does not exist,
+.I acl_initialize
+creates it with mode
+.IR mode .
+If the file
+.I acl_file
+exists,
+.I acl_initialize
+removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+.SH NOTES
+In the presence of concurrency, there is a very small chance that
+.I acl_add
+or
+.I acl_delete
+could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+.PP
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
+.SH SEE ALSO
+kerberos(3), krb_get_lrealm(3)
+.SH AUTHOR
+James Aspnes (MIT Project Athena)
diff --git a/eBones/acl/acl_files.c b/eBones/acl/acl_files.c
new file mode 100644
index 0000000..6f7f3fd
--- /dev/null
+++ b/eBones/acl/acl_files.c
@@ -0,0 +1,541 @@
+/*
+ *
+ * Copyright 1987,1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $
+ * $Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $";
+#endif lint
+
+
+/*** Routines for manipulating access control list files ***/
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <ctype.h>
+#include "krb.h"
+
+__BEGIN_DECLS
+static int acl_abort __P((char *, FILE *));
+__END_DECLS
+
+#ifndef KRB_REALM
+#define KRB_REALM "ATHENA.MIT.EDU"
+#endif
+
+/* "aname.inst@realm" */
+#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3)
+#define INST_SEP '.'
+#define REALM_SEP '@'
+
+#define LINESIZE 2048 /* Maximum line length in an acl file */
+
+#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
+#define WAIT_TIME 300 /* Maximum time allowed write acl file */
+
+#define CACHED_ACLS 8 /* How many acls to cache */
+ /* Each acl costs 1 open file descriptor */
+#define ACL_LEN 16 /* Twice a reasonable acl length */
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#define COR(a,b) ((a!=NULL)?(a):(b))
+
+extern int errno;
+
+extern char *malloc(), *calloc();
+extern time_t time();
+
+/* Canonicalize a principal name */
+/* If instance is missing, it becomes "" */
+/* If realm is missing, it becomes the local realm */
+/* Canonicalized form is put in canon, which must be big enough to hold
+ MAX_PRINCIPAL_SIZE characters */
+acl_canonicalize_principal(principal, canon)
+char *principal;
+char *canon;
+{
+ char *dot, *atsign, *end;
+ int len;
+
+ dot = index(principal, INST_SEP);
+ atsign = index(principal, REALM_SEP);
+
+ /* Maybe we're done already */
+ if(dot != NULL && atsign != NULL) {
+ if(dot < atsign) {
+ /* It's for real */
+ /* Copy into canon */
+ strncpy(canon, principal, MAX_PRINCIPAL_SIZE);
+ canon[MAX_PRINCIPAL_SIZE-1] = '\0';
+ return;
+ } else {
+ /* Nope, it's part of the realm */
+ dot = NULL;
+ }
+ }
+
+ /* No such luck */
+ end = principal + strlen(principal);
+
+ /* Get the principal name */
+ len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal);
+ strncpy(canon, principal, len);
+ canon += len;
+
+ /* Add INST_SEP */
+ *canon++ = INST_SEP;
+
+ /* Get the instance, if it exists */
+ if(dot != NULL) {
+ ++dot;
+ len = MIN(INST_SZ, COR(atsign, end) - dot);
+ strncpy(canon, dot, len);
+ canon += len;
+ }
+
+ /* Add REALM_SEP */
+ *canon++ = REALM_SEP;
+
+ /* Get the realm, if it exists */
+ /* Otherwise, default to local realm */
+ if(atsign != NULL) {
+ ++atsign;
+ len = MIN(REALM_SZ, end - atsign);
+ strncpy(canon, atsign, len);
+ canon += len;
+ *canon++ = '\0';
+ } else if(krb_get_lrealm(canon, 1) != KSUCCESS) {
+ strcpy(canon, KRB_REALM);
+ }
+}
+
+/* Get a lock to modify acl_file */
+/* Return new FILE pointer */
+/* or NULL if file cannot be modified */
+/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
+static FILE *acl_lock_file(acl_file)
+char *acl_file;
+{
+ struct stat s;
+ char new[LINESIZE];
+ int nfd;
+ FILE *nf;
+ int mode;
+
+ if(stat(acl_file, &s) < 0) return(NULL);
+ mode = s.st_mode;
+ sprintf(new, NEW_FILE, acl_file);
+ for(;;) {
+ /* Open the new file */
+ if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
+ if(errno == EEXIST) {
+ /* Maybe somebody got here already, maybe it's just old */
+ if(stat(new, &s) < 0) return(NULL);
+ if(time(0) - s.st_ctime > WAIT_TIME) {
+ /* File is stale, kill it */
+ unlink(new);
+ continue;
+ } else {
+ /* Wait and try again */
+ sleep(1);
+ continue;
+ }
+ } else {
+ /* Some other error, we lose */
+ return(NULL);
+ }
+ }
+
+ /* If we got to here, the lock file is ours and ok */
+ /* Reopen it under stdio */
+ if((nf = fdopen(nfd, "w")) == NULL) {
+ /* Oops, clean up */
+ unlink(new);
+ }
+ return(nf);
+ }
+}
+
+/* Commit changes to acl_file written onto FILE *f */
+/* Returns zero if successful */
+/* Returns > 0 if lock was broken */
+/* Returns < 0 if some other error occurs */
+/* Closes f */
+static int acl_commit(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ sprintf(new, NEW_FILE, acl_file);
+ if(fflush(f) < 0
+ || fstat(fileno(f), &s) < 0
+ || s.st_nlink == 0) {
+ acl_abort(acl_file, f);
+ return(-1);
+ }
+
+ ret = rename(new, acl_file);
+ fclose(f);
+ return(ret);
+}
+
+/*
+ * Abort changes to acl_file written onto FILE *f
+ * Returns 0 if successful, < 0 otherwise
+ * Closes f
+ */
+static int
+acl_abort(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ /* make sure we aren't nuking someone else's file */
+ if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) {
+ fclose(f);
+ return(-1);
+ } else {
+ sprintf(new, NEW_FILE, acl_file);
+ ret = unlink(new);
+ fclose(f);
+ return(ret);
+ }
+}
+
+/* Initialize an acl_file */
+/* Creates the file with permissions perm if it does not exist */
+/* Erases it if it does */
+/* Returns return value of acl_commit */
+int acl_initialize(acl_file, perm)
+char *acl_file;
+int perm;
+{
+ FILE *new;
+ int fd;
+
+ /* Check if the file exists already */
+ if((new = acl_lock_file(acl_file)) != NULL) {
+ return(acl_commit(acl_file, new));
+ } else {
+ /* File must be readable and writable by owner */
+ if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
+ return(-1);
+ } else {
+ close(fd);
+ return(0);
+ }
+ }
+}
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static nuke_whitespace(buf)
+char *buf;
+{
+ register char *pin, *pout;
+
+ for(pin = pout = buf; *pin != '\0'; pin++)
+ if(!isspace(*pin)) *pout++ = *pin;
+ *pout = '\0'; /* Terminate the string */
+}
+
+/* Hash table stuff */
+
+struct hashtbl {
+ int size; /* Max number of entries */
+ int entries; /* Actual number of entries */
+ char **tbl; /* Pointer to start of table */
+};
+
+/* Make an empty hash table of size s */
+static struct hashtbl *make_hash(size)
+int size;
+{
+ struct hashtbl *h;
+
+ if(size < 1) size = 1;
+ h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
+ h->size = size;
+ h->entries = 0;
+ h->tbl = (char **) calloc(size, sizeof(char *));
+ return(h);
+}
+
+/* Destroy a hash table */
+static destroy_hash(h)
+struct hashtbl *h;
+{
+ int i;
+
+ for(i = 0; i < h->size; i++) {
+ if(h->tbl[i] != NULL) free(h->tbl[i]);
+ }
+ free(h->tbl);
+ free(h);
+}
+
+/* Compute hash value for a string */
+static unsigned hashval(s)
+register char *s;
+{
+ register unsigned hv;
+
+ for(hv = 0; *s != '\0'; s++) {
+ hv ^= ((hv << 3) ^ *s);
+ }
+ return(hv);
+}
+
+/* Add an element to a hash table */
+static add_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+ char *s;
+ char **old;
+ int i;
+
+ /* Make space if it isn't there already */
+ if(h->entries + 1 > (h->size >> 1)) {
+ old = h->tbl;
+ h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
+ for(i = 0; i < h->size; i++) {
+ if(old[i] != NULL) {
+ hv = hashval(old[i]) % (h->size << 1);
+ while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
+ h->tbl[hv] = old[i];
+ }
+ }
+ h->size = h->size << 1;
+ free(old);
+ }
+
+ hv = hashval(el) % h->size;
+ while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
+ s = malloc(strlen(el)+1);
+ strcpy(s, el);
+ h->tbl[hv] = s;
+ h->entries++;
+}
+
+/* Returns nonzero if el is in h */
+static check_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+
+ for(hv = hashval(el) % h->size;
+ h->tbl[hv] != NULL;
+ hv = (hv + 1) % h->size) {
+ if(!strcmp(h->tbl[hv], el)) return(1);
+ }
+ return(0);
+}
+
+struct acl {
+ char filename[LINESIZE]; /* Name of acl file */
+ int fd; /* File descriptor for acl file */
+ struct stat status; /* File status at last read */
+ struct hashtbl *acl; /* Acl entries */
+};
+
+static struct acl acl_cache[CACHED_ACLS];
+
+static int acl_cache_count = 0;
+static int acl_cache_next = 0;
+
+/* Returns < 0 if unsuccessful in loading acl */
+/* Returns index into acl_cache otherwise */
+/* Note that if acl is already loaded, this is just a lookup */
+static int acl_load(name)
+char *name;
+{
+ int i;
+ FILE *f;
+ struct stat s;
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ /* See if it's there already */
+ for(i = 0; i < acl_cache_count; i++) {
+ if(!strcmp(acl_cache[i].filename, name)
+ && acl_cache[i].fd >= 0) goto got_it;
+ }
+
+ /* It isn't, load it in */
+ /* maybe there's still room */
+ if(acl_cache_count < CACHED_ACLS) {
+ i = acl_cache_count++;
+ } else {
+ /* No room, clean one out */
+ i = acl_cache_next;
+ acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
+ close(acl_cache[i].fd);
+ if(acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
+ }
+
+ /* Set up the acl */
+ strcpy(acl_cache[i].filename, name);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ /* Force reload */
+ acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+ /*
+ * See if the stat matches
+ *
+ * Use stat(), not fstat(), as the file may have been re-created by
+ * acl_add or acl_delete. If this happens, the old inode will have
+ * no changes in the mod-time and the following test will fail.
+ */
+ if(stat(acl_cache[i].filename, &s) < 0) return(-1);
+ if(acl_cache[i].acl == (struct hashtbl *) 0
+ || s.st_nlink != acl_cache[i].status.st_nlink
+ || s.st_mtime != acl_cache[i].status.st_mtime
+ || s.st_ctime != acl_cache[i].status.st_ctime) {
+ /* Gotta reload */
+ if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
+ if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = make_hash(ACL_LEN);
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ nuke_whitespace(buf);
+ acl_canonicalize_principal(buf, canon);
+ add_hash(acl_cache[i].acl, canon);
+ }
+ fclose(f);
+ acl_cache[i].status = s;
+ }
+ return(i);
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+
+ return((idx = acl_load(acl)) >= 0
+ && check_hash(acl_cache[idx].acl, principal));
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Recognizes wildcards in acl of the form
+ name.*@realm, *.*@realm, and *.*@* */
+acl_check(acl, principal)
+char *acl;
+char *principal;
+{
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+ char *realm;
+
+ acl_canonicalize_principal(principal, canon);
+
+ /* Is it there? */
+ if(acl_exact_match(acl, canon)) return(1);
+
+ /* Try the wildcards */
+ realm = index(canon, REALM_SEP);
+ *index(canon, INST_SEP) = '\0'; /* Chuck the instance */
+
+ sprintf(buf, "%s.*%s", canon, realm);
+ if(acl_exact_match(acl, buf)) return(1);
+
+ sprintf(buf, "*.*%s", realm);
+ if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
+
+ return(0);
+}
+
+/* Adds principal to acl */
+/* Wildcards are interpreted literally */
+acl_add(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL) {
+ if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL
+ || putc('\n', new) != '\n') {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ }
+ }
+ fputs(canon, new);
+ putc('\n', new);
+ return(acl_commit(acl, new));
+}
+
+/* Removes principal from acl */
+/* Wildcards are interpreted literally */
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((!acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL
+ && strcmp(acl_cache[idx].acl->tbl[i], canon)) {
+ fputs(acl_cache[idx].acl->tbl[i], new);
+ putc('\n', new);
+ }
+ }
+ return(acl_commit(acl, new));
+}
+
diff --git a/eBones/acl/acl_files.doc b/eBones/acl/acl_files.doc
new file mode 100644
index 0000000..78c448a
--- /dev/null
+++ b/eBones/acl/acl_files.doc
@@ -0,0 +1,107 @@
+PROTOTYPE ACL LIBRARY
+
+Introduction
+
+An access control list (ACL) is a list of principals, where each
+principal is is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+
+
+Usage
+
+cc <files> -lacl -lkrb.
+
+
+
+Principal Names
+
+Principal names have the form
+
+<name>[.<instance>][@<realm>]
+
+e.g.
+
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+
+It is possible for principals to be underspecified. If instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be local_realm. The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+
+
+Routines
+
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf; /*RETVAL*/
+
+Store the canonical form of principal in buf. Buf must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified in /usr/include/krb.h.
+
+acl_check(acl, principal)
+char *acl;
+char *principal;
+
+Returns nonzero if principal appears in acl. Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards.
+
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+
+Like acl_check, but does no canonicalization or wildcarding.
+
+acl_add(acl, principal)
+char *acl;
+char *principal;
+
+Atomically adds principal to acl. Returns 0 if successful, nonzero
+otherwise. It is considered a failure if principal is already in acl.
+This routine will canonicalize principal, but will treat wildcards
+literally.
+
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+
+Atomically deletes principal from acl. Returns 0 if successful,
+nonzero otherwise. It is consider a failure if principal is not
+already in acl. This routine will canonicalize principal, but will
+treat wildcards literally.
+
+acl_initialize(acl, mode)
+char *acl;
+int mode;
+
+Initialize acl. If acl file does not exist, creates it with mode
+mode. If acl exists, removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+
+
+Known problems
+
+In the presence of concurrency, there is a very small chance that
+acl_add or acl_delete could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
diff --git a/eBones/compile_et/Makefile b/eBones/compile_et/Makefile
new file mode 100644
index 0000000..9b988267
--- /dev/null
+++ b/eBones/compile_et/Makefile
@@ -0,0 +1,15 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:21:23 g89r4222 Exp $
+
+PROG= compile_et
+CFLAGS+=-I. -I${.CURDIR}
+SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c
+OBJS+= error_table.o
+DPADD= ${LIBL}
+LDADD= -ll
+CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c
+NOMAN= noman
+
+error_table.c: et_lex.lex.c
+
+.include <bsd.prog.mk>
diff --git a/eBones/compile_et/compile_et.c b/eBones/compile_et/compile_et.c
new file mode 100644
index 0000000..25be70b
--- /dev/null
+++ b/eBones/compile_et/compile_et.c
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright 1986, 1987 by MIT Student Information Processing Board
+ * For copyright info, see "Copyright.SIPB".
+ *
+ * $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include <sys/file.h>
+#include <strings.h>
+#include <sys/param.h>
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+extern char *gensym();
+extern char *current_token;
+extern int table_number, current;
+char buffer[BUFSIZ];
+char *table_name = (char *)NULL;
+FILE *hfile, *cfile;
+
+/* C library */
+extern char *malloc();
+extern int errno;
+
+/* lex stuff */
+extern FILE *yyin;
+extern int yylineno;
+
+/* pathnames */
+char c_file[MAXPATHLEN]; /* temporary file */
+char h_file[MAXPATHLEN]; /* output */
+char o_file[MAXPATHLEN]; /* output */
+char et_file[MAXPATHLEN]; /* input */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ register char *p;
+ int n_flag = 0, debug = 0;
+
+ while (argc > 2) {
+ register char *arg, ch;
+ arg = argv[--argc];
+ if (strlen(arg) != 2 || arg[0] != '-')
+ goto usage;
+ ch = arg[1];
+ if (ch == 'n')
+ n_flag++;
+ else if (ch == 'd')
+ debug++;
+ else
+ goto usage;
+ }
+
+ if (argc != 2) {
+ usage:
+ fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]);
+ exit(1);
+ }
+
+ strcpy(et_file, argv[1]);
+ p = rindex(et_file, '/');
+ if (p == (char *)NULL)
+ p = et_file;
+ else
+ p++;
+ p = rindex(p, '.');
+ if (!strcmp(p, ".et"))
+ *++p = '\0';
+ else {
+ if (!p)
+ p = et_file;
+ while (*p)
+ p++;
+ *p++ = '.';
+ *p = '\0';
+ }
+ /* p points at null where suffix should be */
+ strcpy(p, "et.c");
+ strcpy(c_file, et_file);
+ p[0] = 'h';
+ p[1] = '\0';
+ strcpy(h_file, et_file);
+ p[0] = 'o';
+ strcpy(o_file, et_file);
+ p[0] = 'e';
+ p[1] = 't';
+ p[2] = '\0';
+
+ yyin = fopen(et_file, "r");
+ if (!yyin) {
+ perror(et_file);
+ exit(1);
+ }
+
+ hfile = fopen(h_file, "w");
+ if (hfile == (FILE *)NULL) {
+ perror(h_file);
+ exit(1);
+ }
+
+ cfile = fopen(c_file, "w");
+ if (cfile == (FILE *)NULL) {
+ perror("Can't open temp file");
+ exit(1);
+ }
+
+ /* parse it */
+ fputs("#define NULL 0\n", cfile);
+ fputs("static char *_et[] = {\n", cfile);
+
+ yyparse();
+ fclose(yyin); /* bye bye input file */
+
+ fputs("\t(char *)0\n};\n", cfile);
+ fputs("extern int init_error_table();\n\n", cfile);
+ fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number);
+ fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name);
+ fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n",
+ table_number, current);
+ fclose(cfile);
+
+ fputs("extern int init_", hfile);
+ fputs(table_name, hfile);
+ fputs("_err_tbl();\nextern int ", hfile);
+ fputs(table_name, hfile);
+ fputs("_err_base;\n", hfile);
+ fclose(hfile); /* bye bye hfile */
+
+ if (n_flag)
+ exit(0);
+
+ if (!fork()) {
+ p = rindex(c_file, '/');
+ if (p) {
+ *p++ = '\0';
+ chdir(c_file);
+ }
+ else
+ p = c_file;
+ execlp("cc", "cc", "-c", "-R", "-O", p, 0);
+ perror("cc");
+ exit(1);
+ }
+ else wait(0);
+
+ if (!debug)
+ (void) unlink(c_file);
+ /* make it .o file name */
+ c_file[strlen(c_file)-1] = 'o';
+ if (!fork()) {
+ execlp("cp", "cp", c_file, o_file, 0);
+ perror("cp");
+ exit(1);
+ }
+ else wait(0);
+ if (!debug)
+ (void) unlink(c_file);
+
+ exit(0);
+}
+
+yyerror(s)
+ char *s;
+{
+ fputs(s, stderr);
+ fprintf(stderr, "\nLine number %d; last token was '%s'\n",
+ yylineno, current_token);
+}
diff --git a/eBones/compile_et/error_message.c b/eBones/compile_et/error_message.c
new file mode 100644
index 0000000..92cec57
--- /dev/null
+++ b/eBones/compile_et/error_message.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1987 by the Student Information Processing Board
+ * of the Massachusetts Institute of Technology
+ * For copyright info, see "Copyright.SIPB".
+ *
+ * from: error_message.c,v 1.1 86/11/10 21:34:34 spook Exp $
+ * $Id: error_message.c,v 1.3 1994/09/09 21:43:22 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include "error_table.h"
+extern int sys_nerr;
+
+static char buffer[25];
+
+char *
+error_message(code)
+ int code;
+{
+ register int offset;
+ register error_table **et;
+ register int table_num;
+ register int div;
+ register char *cp;
+
+ offset = code & ((1<<ERRCODE_RANGE)-1);
+ table_num = code - offset;
+ if ((_et_list == (error_table **)NULL) && table_num)
+ goto oops;
+ if (!table_num) {
+ if (offset < sys_nerr)
+ return(sys_errlist[offset]);
+ else
+ goto oops;
+ }
+ for (et = _et_list; *et != (error_table *)NULL; et++) {
+ if ((*et)->base == table_num) {
+ /* This is the right table */
+ if ((*et)->n_msgs <= offset)
+ goto oops;
+ return((*et)->msgs[offset]);
+ }
+ }
+ oops:
+ cp = buffer;
+ {
+ register char *cp1;
+ for (cp1 = "Unknown code "; *cp1; cp1++, cp++)
+ *cp = *cp1;
+ if (table_num) {
+ for (cp1 = error_table_name(table_num); *cp1; cp1++, cp++)
+ *cp = *cp1;
+ *cp++ = ' ';
+ *cp = '\0';
+ }
+ }
+ div = 1000000000;
+ if (offset == 0) {
+ *cp++ = '0';
+ *cp = '\0';
+ return(buffer);
+ }
+ while (div > offset)
+ div /= 10;
+ do {
+ register int n = offset / div;
+ *cp++ = '0' + n;
+ offset -= n * div;
+ div /= 10;
+ } while (offset && div);
+ while (div) {
+ *cp++ = '0';
+ div /= 10;
+ }
+ *cp = '\0';
+ return(buffer);
+}
diff --git a/eBones/compile_et/error_table.h b/eBones/compile_et/error_table.h
new file mode 100644
index 0000000..e32ec30
--- /dev/null
+++ b/eBones/compile_et/error_table.h
@@ -0,0 +1,17 @@
+#ifndef _ET
+extern int errno;
+typedef struct {
+ char **msgs;
+ int base;
+ int n_msgs;
+} error_table;
+extern error_table **_et_list;
+
+#define ERROR_CODE "int" /* type used for error codes */
+
+#define ERRCODE_RANGE 8 /* # of bits to shift table number */
+#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
+
+extern char *error_table_name();
+#define _ET
+#endif
diff --git a/eBones/compile_et/error_table.y b/eBones/compile_et/error_table.y
new file mode 100644
index 0000000..3913a84
--- /dev/null
+++ b/eBones/compile_et/error_table.y
@@ -0,0 +1,205 @@
+%{
+#include <stdio.h>
+char *str_concat(), *ds(), *quote(), *malloc(), *realloc();
+char *current_token = (char *)NULL;
+extern char *table_name;
+%}
+%union {
+ char *dynstr;
+}
+
+%token ERROR_TABLE ERROR_CODE_ENTRY END
+%token <dynstr> STRING QUOTED_STRING
+%type <dynstr> ec_name description table_id
+%{
+%}
+%start error_table
+%%
+
+error_table : ERROR_TABLE table_id error_codes END
+ { table_name = ds($2);
+ current_token = table_name;
+ put_ecs(); }
+ ;
+
+table_id : STRING
+ { current_token = $1;
+ set_table_num($1);
+ $$ = $1; }
+ ;
+
+error_codes : error_codes ec_entry
+ | ec_entry
+ ;
+
+ec_entry : ERROR_CODE_ENTRY ec_name ',' description
+ { add_ec($2, $4);
+ free($2);
+ free($4); }
+ | ERROR_CODE_ENTRY ec_name '=' STRING ',' description
+ { add_ec_val($2, $4, $6);
+ free($2);
+ free($4);
+ free($6);
+ }
+ ;
+
+ec_name : STRING
+ { $$ = ds($1);
+ current_token = $$; }
+ ;
+
+description : QUOTED_STRING
+ { $$ = ds($1);
+ current_token = $$; }
+ ;
+
+%%
+/*
+ * Copyright 1986, 1987 by the MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include "error_table.h"
+
+extern FILE *hfile, *cfile;
+
+static long gensym_n = 0;
+char *
+gensym(x)
+ char *x;
+{
+ char *symbol;
+ if (!gensym_n) {
+ struct timeval tv;
+ struct timezone tzp;
+ gettimeofday(&tv, &tzp);
+ gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
+ }
+ symbol = malloc(32 * sizeof(char));
+ gensym_n++;
+ sprintf(symbol, "et%ld", gensym_n);
+ return(symbol);
+}
+
+char *
+ds(string)
+ char *string;
+{
+ char *rv;
+ rv = malloc(strlen(string)+1);
+ strcpy(rv, string);
+ return(rv);
+}
+
+char *
+quote(string)
+ char *string;
+{
+ char *rv;
+ rv = malloc(strlen(string)+3);
+ strcpy(rv, "\"");
+ strcat(rv, string);
+ strcat(rv, "\"");
+ return(rv);
+}
+
+int table_number;
+int current = 0;
+char **error_codes = (char **)NULL;
+
+add_ec(name, description)
+ char *name, *description;
+{
+ fprintf(cfile, "\t\"%s\",\n", description);
+ if (error_codes == (char **)NULL) {
+ error_codes = (char **)malloc(sizeof(char *));
+ *error_codes = (char *)NULL;
+ }
+ error_codes = (char **)realloc((char *)error_codes,
+ (current + 2)*sizeof(char *));
+ error_codes[current++] = ds(name);
+ error_codes[current] = (char *)NULL;
+}
+
+add_ec_val(name, val, description)
+ char *name, *val, *description;
+{
+ int ncurrent = atoi(val);
+ if (ncurrent < current) {
+ printf("Error code %s (%d) out of order", name,
+ current);
+ return;
+ }
+
+ while (ncurrent > current)
+ fputs("\t(char *)NULL,\n", cfile), current++;
+
+ fprintf(cfile, "\t\"%s\",\n", description);
+ if (error_codes == (char **)NULL) {
+ error_codes = (char **)malloc(sizeof(char *));
+ *error_codes = (char *)NULL;
+ }
+ error_codes = (char **)realloc((char *)error_codes,
+ (current + 2)*sizeof(char *));
+ error_codes[current++] = ds(name);
+ error_codes[current] = (char *)NULL;
+}
+
+put_ecs()
+{
+ int i;
+ for (i = 0; i < current; i++) {
+ if (error_codes[i] != (char *)NULL)
+ fprintf(hfile, "#define %-40s ((%s)%d)\n",
+ error_codes[i], ERROR_CODE, table_number + i);
+ }
+}
+
+/*
+ * char_to_num -- maps letters and numbers into a small numbering space
+ * uppercase -> 1-26
+ * lowercase -> 27-52
+ * digits -> 53-62
+ * underscore-> 63
+ */
+int
+char_to_num(c)
+ char c;
+{
+ if (isupper(c))
+ return(c-'A'+1);
+ else if (islower(c))
+ return(c-'a'+27);
+ else if (isdigit(c))
+ return(c-'0'+53);
+ else {
+ fprintf(stderr, "Illegal character in name: %c\n", c);
+ exit(1);
+ /*NOTREACHED*/
+ }
+}
+
+set_table_num(string)
+ char *string;
+{
+ if (strlen(string) > 4) {
+ fprintf(stderr, "Table name %s too long, truncated ",
+ string);
+ string[4] = '\0';
+ fprintf(stderr, "to %s\n", string);
+ }
+ while (*string != '\0') {
+ table_number = (table_number << BITS_PER_CHAR)
+ + char_to_num(*string);
+ string++;
+ }
+ table_number = table_number << ERRCODE_RANGE;
+}
+
+#include "et_lex.lex.c"
diff --git a/eBones/compile_et/et_lex.lex.l b/eBones/compile_et/et_lex.lex.l
new file mode 100644
index 0000000..c041819
--- /dev/null
+++ b/eBones/compile_et/et_lex.lex.l
@@ -0,0 +1,29 @@
+%{
+extern int yylineno;
+int yylineno = 1;
+%}
+
+PC [^\"\n]
+AN [A-Z_a-z0-9]
+%%
+
+error_table return ERROR_TABLE;
+et return ERROR_TABLE;
+error_code return ERROR_CODE_ENTRY;
+ec return ERROR_CODE_ENTRY;
+end return END;
+
+[\t ]+ ;
+\n ++yylineno;
+
+\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1);
+ if (p=rindex(yylval.dynstr, '"')) *p='\0';
+ return QUOTED_STRING;
+ }
+
+{AN}* { yylval.dynstr = ds(yytext); return STRING; }
+
+#.*\n ++yylineno;
+
+. { return (*yytext); }
+%%
diff --git a/eBones/compile_et/et_name.c b/eBones/compile_et/et_name.c
new file mode 100644
index 0000000..98ccb08
--- /dev/null
+++ b/eBones/compile_et/et_name.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ *
+ * $Id: et_name.c,v 1.2 1994/07/19 19:21:27 g89r4222 Exp $
+ */
+
+#include "error_table.h"
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+char *malloc();
+
+char *
+error_table_name(num)
+ int num;
+{
+ register int ch;
+ register int i;
+ register char *buf, *p;
+
+ /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+ buf = malloc(5);
+ p = buf;
+ num >>= ERRCODE_RANGE;
+ /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+ num &= 077777777;
+ /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+ for (i = 0; i < 5; i++) {
+ ch = (num >> 24-6*i) & 077;
+ if (ch == 0)
+ continue;
+ else if (ch < 27)
+ *p++ = ch - 1 + 'A';
+ else if (ch < 53)
+ *p++ = ch - 27 + 'a';
+ else if (ch < 63)
+ *p++ = ch - 53 + '0';
+ else /* ch == 63 */
+ *p++ = '_';
+ }
+ return(buf);
+}
+
diff --git a/eBones/compile_et/init_et.c b/eBones/compile_et/init_et.c
new file mode 100644
index 0000000..c23facb
--- /dev/null
+++ b/eBones/compile_et/init_et.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1986 by MIT Information Systems and
+ * MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ *
+ * form: init_et.c,v 1.1 86/11/10 21:42:26 spook Exp $
+ * $Id: init_et.c,v 1.2 1994/07/19 19:21:28 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include "error_table.h"
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+extern char *malloc(), *realloc();
+
+/* useful */
+typedef error_table *etp;
+typedef etp *etpp;
+
+etpp _et_list = (etpp)NULL;
+static int n_allocated = 0, n_used = 0;
+
+int
+init_error_table(msgs, base, count)
+ char **msgs;
+ register int base;
+ int count;
+{
+ register int i;
+ register etp new_et;
+ register etpp list;
+
+ if (!base || !count || !msgs)
+ return;
+
+ new_et = (etp)malloc(sizeof(error_table));
+ new_et->msgs = msgs;
+ new_et->base = base;
+ new_et->n_msgs= count;
+
+ list = _et_list;
+ if (list == (etpp)NULL) {
+ _et_list = (etpp) malloc(10*sizeof(etp));
+ list = _et_list;
+ if (list == (etpp)NULL)
+ return; /* oops */
+ list[0] = new_et;
+ list[1] = (etp)NULL;
+ n_allocated = 10;
+ n_used = 1;
+ return;
+ }
+ for (i = 0; i < n_used; i++)
+ if (list[i]->base == base)
+ return; /* avoid duplicates */
+ if (n_used+2 > n_allocated) {
+ n_allocated += 10; /* don't re-allocate too often */
+ list = (etpp) realloc((char *)list,
+ (unsigned)n_allocated * sizeof(etp));
+ _et_list = list;
+ if (list == (etpp)NULL)
+ return; /* oops */
+ }
+ list[n_used++] = new_et;
+ list[n_used] = (etp)NULL;
+}
diff --git a/eBones/compile_et/perror.c b/eBones/compile_et/perror.c
new file mode 100644
index 0000000..ef50e07
--- /dev/null
+++ b/eBones/compile_et/perror.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB
+ *
+ * $Id: perror.c,v 1.2 1994/07/19 19:21:30 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include "error_table.h"
+
+typedef int (*int_func)();
+
+#if defined(mips) && defined(ultrix)
+int errno; /* this is needed to keep the loader from complaining */
+#endif
+
+int_func com_err_hook = (int_func) NULL;
+char *error_message();
+
+void
+com_err(whoami, code, message)
+ char *whoami;
+ int code;
+ char *message;
+{
+ struct iovec strings[6];
+
+ if (com_err_hook) {
+ (*com_err_hook)(whoami, code, message);
+ return;
+ }
+
+ strings[0].iov_base = whoami;
+ strings[0].iov_len = strlen(whoami);
+ if (whoami) {
+ strings[1].iov_base = ": ";
+ strings[1].iov_len = 2;
+ } else
+ strings[1].iov_len = 0;
+ if (code) {
+ register char *errmsg = error_message(code);
+ strings[2].iov_base = errmsg;
+ strings[2].iov_len = strlen(errmsg);
+ } else
+ strings[2].iov_len = 0;
+ strings[3].iov_base = " ";
+ strings[3].iov_len = 1;
+ strings[4].iov_base = message;
+ strings[4].iov_len = strlen(message);
+ strings[5].iov_base = "\n";
+ strings[5].iov_len = 1;
+ (void) writev(2, strings, 6);
+}
+
+int_func
+set_com_err_hook(new_proc)
+ int_func new_proc;
+{
+ register int_func x = com_err_hook;
+ com_err_hook = new_proc;
+ return (x);
+}
+
+reset_com_err_hook()
+{
+ com_err_hook = (int_func) NULL;
+}
+
+void
+perror(msg)
+ register const char *msg;
+{
+ com_err(msg, errno, (char *)NULL);
+}
diff --git a/eBones/compile_et/test/test.c b/eBones/compile_et/test/test.c
new file mode 100644
index 0000000..df430da
--- /dev/null
+++ b/eBones/compile_et/test/test.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <errno.h>
+#include "test1.h"
+#include "test2.h"
+char *error_message();
+extern int sys_nerr, errno;
+
+main()
+{
+ printf("\nBefore initiating error table:\n\n");
+ printf("Table name '%s'\n", error_table_name(KRB_MK_AP_TGTEXP));
+ printf("UNIX name '%s'\n", error_table_name(EPERM));
+ printf("Msg TGT-expired is '%s'\n", error_message(KRB_MK_AP_TGTEXP));
+ printf("Msg EPERM is '%s'\n", error_message(EPERM));
+ printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
+ printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
+ printf("Msg {sys_nerr} is '%s'\n", error_message(sys_nerr));
+
+ init_error_table(0, 0, 0);
+ printf("With 0: tgt-expired -> %s\n", error_message(KRB_MK_AP_TGTEXP));
+
+ init_krb_err_tbl();
+ printf("KRB error table initialized: base %d (%s), name %s\n",
+ krb_err_base, error_message(krb_err_base),
+ error_table_name(krb_err_base));
+ printf("With krb: tgt-expired -> %s\n",
+ error_message(KRB_MK_AP_TGTEXP));
+
+ init_quux_err_tbl();
+ printf("QUUX error table initialized: base %d (%s), name %s\n",
+ quux_err_base, error_message(quux_err_base),
+ error_table_name(quux_err_base));
+
+ printf("Msg for TGT-expired is '%s'\n",
+ error_message(KRB_MK_AP_TGTEXP));
+ printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
+ printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
+ printf("Msg KRB_SKDC_CANT is '%s'\n",
+ error_message(KRB_SKDC_CANT));
+ printf("Msg 1e6 is '%s'\n", error_message(1000000));
+ errno = FOO_ERR;
+ perror("FOO_ERR");
+}
diff --git a/eBones/compile_et/test/test1.et b/eBones/compile_et/test/test1.et
new file mode 100644
index 0000000..4c7b77f
--- /dev/null
+++ b/eBones/compile_et/test/test1.et
@@ -0,0 +1,69 @@
+ error_table krb
+
+ error_code KRB_MK_AP_TKFIL,
+ "Can't read ticket file"
+
+ ec KRB_MK_AP_NOTKT,
+ "Can't find ticket or TGT"
+
+ ec KRB_MK_AP_TGTEXP,
+ "TGT expired"
+
+ ec KRB_RD_AP_UNDEC,
+ "Can't decode authenticator"
+
+ ec KRB_RD_AP_EXP,
+ "Ticket expired"
+
+ ec KRB_RD_AP_REPEAT,
+ "Repeated request"
+
+ ec KRB_RD_AP_NOT_US,
+ "The ticket isn't for us"
+
+ ec KRB_RD_AP_INCON,
+ "Request is inconsistent"
+
+ ec KRB_RD_AP_TIME,
+ "Delta-T too big"
+
+ ec KRB_RD_AP_BADD,
+ "Incorrect net address"
+
+ ec KRB_RD_AP_VERSION,
+ "Protocol version mismatch"
+
+ ec KRB_RD_AP_MSG_TYPE,
+ "Invalid message type"
+
+ ec KRB_RD_AP_MODIFIED,
+ "Message stream modified"
+
+ ec KRB_RD_AP_ORDER,
+ "Message out of order"
+
+ ec KRB_RD_AP_UNAUTHOR,
+ "Unauthorized request"
+
+ ec KRB_GT_PW_NULL,
+ "Current password is null"
+
+ ec KRB_GT_PW_BADPW,
+ "Incorrect current password"
+
+ ec KRB_GT_PW_PROT,
+ "Protocol error"
+
+ ec KRB_GT_PW_KDCERR,
+ "Error returned by KDC"
+
+ ec KRB_GT_PW_NULLTKT,
+ "Null ticket returned by KDC"
+
+ ec KRB_SKDC_RETRY,
+ "Retry count exceeded"
+
+ ec KRB_SKDC_CANT,
+ "Can't send request"
+
+ end
diff --git a/eBones/compile_et/test/test2.et b/eBones/compile_et/test/test2.et
new file mode 100644
index 0000000..55ad74e
--- /dev/null
+++ b/eBones/compile_et/test/test2.et
@@ -0,0 +1,9 @@
+ error_table quux
+
+ ec FOO_ERR, "foo"
+
+ ec BAR_ERR, "bar"
+
+ ec BAZ_ERR, "meow"
+
+ end
diff --git a/eBones/des/3cbc_enc.c b/eBones/des/3cbc_enc.c
new file mode 100644
index 0000000..231cff5
--- /dev/null
+++ b/eBones/des/3cbc_enc.c
@@ -0,0 +1,58 @@
+/* 3cbc_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: 3cbc_enc.c,v 1.2 1994/07/19 19:21:37 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+int des_3cbc_encrypt(input,output,length,ks1,ks2,iv1,iv2,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule ks1,ks2;
+des_cblock *iv1,*iv2;
+int encrypt;
+ {
+ int off=length/8-1;
+ des_cblock niv1,niv2;
+
+printf("3cbc\n");
+xp(iv1);
+xp(iv1);
+xp(iv2);
+xp(input);
+ if (encrypt == DES_ENCRYPT)
+ {
+ des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv1,sizeof(des_cblock));
+ des_cbc_encrypt(output,output,length,ks2,iv1,!encrypt);
+ des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv2,sizeof(des_cblock));
+ bcopy(niv1,*iv1,sizeof(des_cblock));
+ }
+ else
+ {
+ if (length >= sizeof(des_cblock))
+ bcopy(input[off],niv1,sizeof(des_cblock));
+ des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+ des_cbc_encrypt(output,output,length,ks2,iv2,!encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv2,sizeof(des_cblock));
+ des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+ }
+ bcopy(niv1,iv1,sizeof(des_cblock));
+ bcopy(niv2,iv2,sizeof(des_cblock));
+xp(iv1);
+xp(iv1);
+xp(iv2);
+xp(output);
+ return(0);
+ }
+
+xp(a)
+unsigned char *a;
+{ int i; for(i=0; i<8; i++) printf("%02X",a[i]);printf("\n");}
diff --git a/eBones/des/3ecb_enc.c b/eBones/des/3ecb_enc.c
new file mode 100644
index 0000000..1081f9d
--- /dev/null
+++ b/eBones/des/3ecb_enc.c
@@ -0,0 +1,35 @@
+/* 3ecb_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: 3ecb_enc.c,v 1.2 1994/07/19 19:21:38 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+int des_3ecb_encrypt(input,output,ks1,ks2,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule ks1,ks2;
+int encrypt;
+ {
+ register unsigned long l0,l1,t;
+ register unsigned char *in,*out;
+ unsigned long ll[2];
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ c2l(in,l0);
+ c2l(in,l1);
+ ll[0]=l0;
+ ll[1]=l1;
+ des_encrypt(ll,ll,ks1,encrypt);
+ des_encrypt(ll,ll,ks2,!encrypt);
+ des_encrypt(ll,ll,ks1,encrypt);
+ l0=ll[0];
+ l1=ll[1];
+ l2c(l0,out);
+ l2c(l1,out);
+ return(0);
+ }
+
diff --git a/eBones/des/MISSING b/eBones/des/MISSING
new file mode 100644
index 0000000..bffc690
--- /dev/null
+++ b/eBones/des/MISSING
@@ -0,0 +1,17 @@
+# $Id: MISSING,v 1.2 1994/07/19 19:21:40 g89r4222 Exp $
+
+The following symbols (you can find in the USA libdes) are still missing
+in this source.
+
+_des_cblock_print_file
+_des_generate_random_block
+_des_init_random_number_generator
+_des_new_random_key
+_des_set_random_generator_seed
+_des_set_sequence_number
+_des_check_key_parity
+_des_fixup_key_parity
+_des_debug
+
+# END
+
diff --git a/eBones/des/Makefile b/eBones/des/Makefile
new file mode 100644
index 0000000..5afd5b5
--- /dev/null
+++ b/eBones/des/Makefile
@@ -0,0 +1,27 @@
+# @(#)Makefile 5.4 (Berkeley) 5/7/91
+# $Id: Makefile,v 1.4 1994/09/09 21:43:30 g89r4222 Exp $
+
+LIB= des
+SRCS= cbc_cksm.c cbc_enc.c ecb_enc.c enc_read.c enc_writ.c pcbc_enc.c \
+ qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \
+ cfb_enc.c 3ecb_enc.c ofb_enc.c 3cbc_enc.c
+#MAN1= des.1
+#MAN3= des.3
+
+#LINKS= crypt
+CFLAGS+= -DDES_ENCRYPT -DKRBDES_ENCRYPT
+
+# Kerberos 4?
+#CFLAGS+=-DKRB4
+#SRCS+= kerberos.c
+
+# Kerberos 5?
+#CFLAGS+= -DKRB5
+#SRCS+= kerberos5.c
+
+CFLAGS+= -I${.CURDIR}/include -DAUTHENTICATE
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
+
+.include "/usr/src/lib/Makefile.inc"
+.include <bsd.lib.mk>
diff --git a/eBones/des/cbc_cksm.c b/eBones/des/cbc_cksm.c
new file mode 100644
index 0000000..b28dc75
--- /dev/null
+++ b/eBones/des/cbc_cksm.c
@@ -0,0 +1,55 @@
+/* cbc_cksm.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: cbc_cksm.c,v 1.2 1994/07/19 19:21:45 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+ {
+ register unsigned long tout0,tout1,tin0,tin1;
+ register long l=length;
+ unsigned long tin[2],tout[2];
+ unsigned char *in,*out,*iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (; l>0; l-=8)
+ {
+ if (l >= 8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ }
+ else
+ c2ln(in,tin0,tin1,l);
+
+ tin0^=tout0;
+ tin1^=tout1;
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt((unsigned long *)tin,(unsigned long *)tout,
+ schedule,DES_ENCRYPT);
+ /* fix 15/10/91 eay - thanks to keithr@sco.COM */
+ tout0=tout[0];
+ tout1=tout[1];
+ }
+ if (out != NULL)
+ {
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ tout0=tin0=tin1=tin[0]=tin[1]=tout[0]=tout[1]=0;
+ return(tout1);
+ }
diff --git a/eBones/des/cbc_enc.c b/eBones/des/cbc_enc.c
new file mode 100644
index 0000000..c2ebd3a
--- /dev/null
+++ b/eBones/des/cbc_enc.c
@@ -0,0 +1,83 @@
+/* cbc_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: cbc_enc.c,v 1.2 1994/07/19 19:21:47 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+ {
+ register unsigned long tin0,tin1;
+ register unsigned long tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ unsigned long tout[2],tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (encrypt)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (; l>0; l-=8)
+ {
+ if (l >= 8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ }
+ else
+ c2ln(in,tin0,tin1,l);
+ tin0^=tout0;
+ tin1^=tout1;
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt((unsigned long *)tin,(unsigned long *)tout,
+ schedule,encrypt);
+ tout0=tout[0];
+ tout1=tout[1];
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ }
+ else
+ {
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (; l>0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt((unsigned long *)tin,(unsigned long *)tout,
+ schedule,encrypt);
+ tout0=tout[0]^xor0;
+ tout1=tout[1]^xor1;
+ if (l >= 8)
+ {
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ else
+ l2cn(tout0,tout1,out,l);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=tout[0]=tout[1]=0;
+ return(0);
+ }
+
diff --git a/eBones/des/cfb_enc.c b/eBones/des/cfb_enc.c
new file mode 100644
index 0000000..367da5f
--- /dev/null
+++ b/eBones/des/cfb_enc.c
@@ -0,0 +1,110 @@
+/* cfb_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: cfb_enc.c,v 1.2 1994/07/19 19:21:48 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second. The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+int des_cfb_encrypt(in,out,numbits,length,schedule,ivec,encrypt)
+unsigned char *in,*out;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+ {
+ register unsigned long d0,d1,v0,v1,n=(numbits+7)/8;
+ register unsigned long mask0,mask1;
+ register long l=length;
+ register int num=numbits;
+ unsigned long ti[2],to[2];
+ unsigned char *iv;
+
+ if (num > 64) return(0);
+ if (num > 32)
+ {
+ mask0=0xffffffff;
+ if (num == 64)
+ mask1=mask0;
+ else
+ mask1=(1L<<(num-32))-1;
+ }
+ else
+ {
+ if (num == 32)
+ mask0=0xffffffff;
+ else
+ mask0=(1L<<num)-1;
+ mask1=0x00000000;
+ }
+
+ iv=(unsigned char *)ivec;
+ c2l(iv,v0);
+ c2l(iv,v1);
+ if (encrypt)
+ {
+ while (l-- > 0)
+ {
+ ti[0]=v0;
+ ti[1]=v1;
+ des_encrypt((unsigned long *)ti,(unsigned long *)to,
+ schedule,DES_ENCRYPT);
+ c2ln(in,d0,d1,n);
+ in+=n;
+ d0=(d0^to[0])&mask0;
+ d1=(d1^to[1])&mask1;
+ l2cn(d0,d1,out,n);
+ out+=n;
+ if (num > 32)
+ {
+ v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff;
+ v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff;
+ }
+ else
+ {
+ v0=((v0>>num)|(v1<<(32-num)))&0xffffffff;
+ v1=((v1>>num)|(d0<<(32-num)))&0xffffffff;
+ }
+ }
+ }
+ else
+ {
+ while (l-- > 0)
+ {
+ ti[0]=v0;
+ ti[1]=v1;
+ des_encrypt((unsigned long *)ti,(unsigned long *)to,
+ schedule,DES_ENCRYPT);
+ c2ln(in,d0,d1,n);
+ in+=n;
+ if (num > 32)
+ {
+ v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffff;
+ v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffff;
+ }
+ else
+ {
+ v0=((v0>>num)|(v1<<(32-num)))&0xffffffff;
+ v1=((v1>>num)|(d0<<(32-num)))&0xffffffff;
+ }
+ d0=(d0^to[0])&mask0;
+ d1=(d1^to[1])&mask1;
+ l2cn(d0,d1,out,n);
+ out+=n;
+ }
+ }
+ iv=(unsigned char *)ivec;
+ l2c(v0,iv);
+ l2c(v1,iv);
+ v0=v1=d0=d1=ti[0]=ti[1]=to[0]=to[1]=0;
+ return(0);
+ }
+
diff --git a/eBones/des/des.3 b/eBones/des/des.3
new file mode 100644
index 0000000..280860d
--- /dev/null
+++ b/eBones/des/des.3
@@ -0,0 +1,503 @@
+.\" $Id: des.3,v 1.2 1994/07/19 19:21:50 g89r4222 Exp $
+.TH DES_CRYPT 3
+.SH NAME
+des_read_password, des_read_2password,
+des_string_to_key, des_string_to_2key, des_read_pw_string,
+des_random_key, des_set_key,
+des_key_sched, des_ecb_encrypt, des_3ecb_encrypt, des_cbc_encrypt,
+des_3cbc_encrypt,
+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,
+des_cbc_cksum, des_quad_cksum,
+des_enc_read, des_enc_write, des_set_odd_parity,
+des_is_weak_key, crypt \- (non USA) DES encryption
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+.PP
+.B int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+.PP
+.B int des_read_2password(key1,key2,prompt,verify)
+des_cblock *key1,*key2;
+char *prompt;
+int verify;
+.PP
+.B int des_string_to_key(str,key)
+char *str;
+des_cblock *key;
+.PP
+.B int des_string_to_2keys(str,key1,key2)
+char *str;
+des_cblock *key1,*key2;
+.PP
+.B int des_read_pw_string(buf,length,prompt,verify)
+char *buf;
+int length;
+char *prompt;
+int verify;
+.PP
+.B int des_random_key(key)
+des_cblock *key;
+.PP
+.B int des_set_key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.B int des_key_sched(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.B int des_ecb_encrypt(input,output,schedule,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule schedule;
+int encrypt;
+.PP
+.B int des_3ecb_encrypt(input,output,ks1,ks2,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule ks1,ks2;
+int encrypt;
+.PP
+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule sk1;
+des_key_schedule sk2;
+des_cblock *ivec1;
+des_cblock *ivec2;
+int encrypt;
+.PP
+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)
+unsigned char *input;
+unsigned char *output;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)
+unsigned char *input,*output;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.B unsigned long des_quad_cksum(input,output,length,out_count,seed)
+des_cblock *input;
+des_cblock *output;
+long length;
+int out_count;
+des_cblock *seed;
+.PP
+.B int des_check_key;
+.PP
+.B int des_enc_read(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+.PP
+.B int des_enc_write(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+.PP
+.B extern int des_rw_mode;
+.PP
+.B void des_set_odd_parity(key)
+des_cblock *key;
+.PP
+.B int des_is_weak_key(key)
+des_cblock *key;
+.PP
+.B char *crypt(passwd,salt)
+char *passwd;
+char *salt;
+.PP
+.fi
+.SH DESCRIPTION
+This library contains a fast implementation of the DES encryption
+algorithm.
+.PP
+There are two phases to the use of DES encryption.
+The first is the generation of a
+.I des_key_schedule
+from a key,
+the second is the actual encryption.
+A des key is of type
+.I des_cblock.
+This type is made from 8 characters with odd parity.
+The least significant bit in the character is the parity bit.
+The key schedule is an expanded form of the key; it is used to speed the
+encryption process.
+.PP
+.I des_read_password
+writes the string specified by prompt to the standard output,
+turns off echo and reads an input string from standard input
+until terminated with a newline.
+If verify is non-zero, it prompts and reads the input again and verifies
+that both entered passwords are the same.
+The entered string is converted into a des key by using the
+.I des_string_to_key
+routine.
+The new key is placed in the
+.I des_cblock
+that was passed (by reference) to the routine.
+If there were no errors,
+.I des_read_password
+returns 0,
+-1 is returned if there was a terminal error and 1 is returned for
+any other error.
+.PP
+.I des_read_2password
+operates in the same way as
+.I des_read_password
+except that it generates 2 keys by using the
+.I des_string_to_2key
+function.
+.PP
+.I des_read_pw_string
+is called by
+.I des_read_password
+to read and verify a string from a terminal device.
+The string is returned in
+.I buf.
+The size of
+.I buf
+is passed to the routine via the
+.I length
+parameter.
+.PP
+.I des_string_to_key
+converts a string into a valid des key.
+.PP
+.I des_string_to_2key
+converts a string into 2 valid des keys.
+This routine is best suited for used to generate keys for use with
+.I des_3ecb_encrypt.
+.PP
+.I des_random_key
+returns a random key that is made of a combination of process id,
+time and an increasing counter.
+.PP
+Before a des key can be used it is converted into a
+.I des_key_schedule
+via the
+.I des_set_key
+routine.
+If the
+.I des_check_key
+flag is non-zero,
+.I des_set_key
+will check that the key passed is of odd parity and is not a week or
+semi-weak key.
+If the parity is wrong,
+then -1 is returned.
+If the key is a weak key,
+then -2 is returned.
+If an error is returned,
+the key schedule is not generated.
+.PP
+.I des_key_sched
+is another name for the
+.I des_set_key
+function.
+.PP
+The following routines mostly operate on an input and output stream of
+.I des_cblock's.
+.PP
+.I des_ecb_encrypt
+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
+.I des_cblock
+in
+.I electronic code book
+mode.
+It always transforms the input data, pointed to by
+.I input,
+into the output data,
+pointed to by the
+.I output
+argument.
+If the
+.I encrypt
+argument is non-zero (DES_ENCRYPT),
+the
+.I input
+(cleartext) is encrypted in to the
+.I output
+(ciphertext) using the key_schedule specified by the
+.I schedule
+argument,
+previously set via
+.I des_set_key.
+If
+.I encrypt
+is zero (DES_DECRYPT),
+the
+.I input
+(now ciphertext)
+is decrypted into the
+.I output
+(now cleartext).
+Input and output may overlap.
+No meaningful value is returned.
+.PP
+.I des_3ecb_encrypt
+encrypts/decrypts the
+.I input
+block by using triple ecb DES encryption.
+This involves encrypting the input with
+.I ks1,
+decryption with the key schedule
+.I ks2,
+and then encryption with the first again.
+This routine greatly reduces the chances of brute force breaking of
+DES and has the advantage of if
+.I ks1
+and
+.I ks2
+are the same, it is equivalent to just encryption using ecb mode and
+.I ks1
+as the key.
+.PP
+.I des_cbc_encrypt
+encrypts/decrypts using the
+.I cipher-block-chaining
+mode of DES.
+If the
+.I encrypt
+argument is non-zero,
+the routine cipher-block-chain encrypts the cleartext data pointed to by the
+.I input
+argument into the ciphertext pointed to by the
+.I output
+argument,
+using the key schedule provided by the
+.I schedule
+argument,
+and initialisation vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral multiple of eight bytes,
+the last block is copied to a temporary area and zero filled.
+The output is always
+an integral multiple of eight bytes.
+To make multiple cbc encrypt calls on a large amount of data appear to
+be one
+.I des_cbc_encrypt
+call, the
+.I ivec
+of subsequent calls should be the last 8 bytes of the output.
+.PP
+.I des_3cbc_encrypt
+encrypts/decrypts the
+.I input
+block by using triple cbc DES encryption.
+This involves encrypting the input with key schedule
+.I ks1,
+decryption with the key schedule
+.I ks2,
+and then encryption with the first again.
+2 initialisation vectors are required,
+.I ivec1
+and
+.I ivec2.
+Unlike
+.I des_cbc_encrypt,
+these initialisation vectors are modified by the subroutine.
+This routine greatly reduces the chances of brute force breaking of
+DES and has the advantage of if
+.I ks1
+and
+.I ks2
+are the same, it is equivalent to just encryption using cbc mode and
+.I ks1
+as the key.
+.PP
+.I des_pcbc_encrypt
+encrypt/decrypts using a modified block chaining mode.
+It provides better error propagation characteristics than cbc
+encryption.
+.PP
+.I des_cfb_encrypt
+encrypt/decrypts using cipher feedback mode. This method takes an
+array of characters as input and outputs and array of characters. It
+does not require any padding to 8 character groups. Note: the ivec
+variable is changed and the new changed value needs to be passed to
+the next call to this function. Since this function runs a complete
+DES ecb encryption per numbits, this function is only suggested for
+use when sending small numbers of characters.
+.PP
+.I des_ofb_encrypt
+encrypt using output feedback mode. This method takes an
+array of characters as input and outputs and array of characters. It
+does not require any padding to 8 character groups. Note: the ivec
+variable is changed and the new changed value needs to be passed to
+the next call to this function. Since this function runs a complete
+DES ecb encryption per numbits, this function is only suggested for
+use when sending small numbers of characters.
+.PP
+.I des_cbc_cksum
+produces an 8 byte checksum based on the input stream (via cbc encryption).
+The last 4 bytes of the checksum is returned and the complete 8 bytes is
+placed in
+.I output.
+.PP
+.I des_quad_cksum
+returns a 4 byte checksum from the input bytes.
+The algorithm can be iterated over the input,
+depending on
+.I out_count,
+1, 2, 3 or 4 times.
+If
+.I output
+is non-NULL,
+the 8 bytes generated by each pass are written into
+.I output.
+.PP
+.I des_enc_write
+is used to write
+.I len
+bytes
+to file descriptor
+.I fd
+from buffer
+.I buf.
+The data is encrypted via
+.I pcbc_encrypt
+(default) using
+.I sched
+for the key and
+.I iv
+as a starting vector.
+The actual data send down
+.I fd
+consists of 4 bytes (in network byte order) containing the length of the
+following encrypted data. The encrypted data then follows, padded with random
+data out to a multiple of 8 bytes.
+.PP
+.I des_enc_read
+is used to read
+.I len
+bytes
+from file descriptor
+.I fd
+into buffer
+.I buf.
+The data being read from
+.I fd
+is assumed to have come from
+.I des_enc_write
+and is decrypted using
+.I sched
+for the key schedule and
+.I iv
+for the initial vector.
+The
+.I des_enc_read/des_enc_write
+pair can be used to read/write to files, pipes and sockets.
+I have used them in implementing a version of rlogin in which all
+data is encrypted.
+.PP
+.I des_rw_mode
+is used to specify the encryption mode to use with
+.I des_enc_read
+and
+.I des_end_write.
+If set to
+.I DES_PCBC_MODE
+(the default), des_pcbc_encrypt is used.
+If set to
+.I DES_CBC_MODE
+des_cbc_encrypt is used.
+These two routines and the variable are not part of the normal MIT library.
+.PP
+.I des_set_odd_parity
+sets the parity of the passed
+.I key
+to odd. This routine is not part of the standard MIT library.
+.PP
+.I des_is_weak_key
+returns 1 is the passed key is a weak key (pick again :-),
+0 if it is ok.
+This routine is not part of the standard MIT library.
+.PP
+.I crypt
+is a replacement for the normal system crypt.
+It is much faster than the system crypt.
+.PP
+.SH FILES
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.PP
+The encryption routines have been tested on 16bit, 32bit and 64bit
+machines of various endian and even works under VMS.
+.PP
+.SH BUGS
+.PP
+If you think this manual is sparse,
+read the des_crypt(3) manual from the MIT kerberos (or bones outside
+of the USA) distribution.
+.PP
+.I des_cfb_encrypt
+and
+.I des_ofb_encrypt
+operates on input of 8 bits. What this means is that if you set
+numbits to 12, and length to 2, the first 12 bits will come from the 1st
+input byte and the low half of the second input byte. The second 12
+bits will have the low 8 bits taken from the 3rd input byte and the
+top 4 bits taken from the 4th input byte. The same holds for output.
+This function has been implemented this way because most people will
+be using a multiple of 8 and because once you get into pulling bytes input
+bytes apart things get ugly!
+.PP
+.I des_read_pw_string
+is the most machine/OS dependent function and normally generates the
+most problems when porting this code.
+.PP
+.I des_string_to_key
+is probably different from the MIT version since there are lots
+of fun ways to implement one-way encryption of a text string.
+.PP
+The routines are optimised for 32 bit machines and so are not efficient
+on IBM PCs.
+.SH AUTHOR
+Eric Young (eay@psych.psy.uq.oz.au),
+Psychology Department,
+University of Queensland, Australia.
diff --git a/eBones/des/docs.original/ARTISTIC b/eBones/des/docs.original/ARTISTIC
new file mode 100644
index 0000000..b382657
--- /dev/null
+++ b/eBones/des/docs.original/ARTISTIC
@@ -0,0 +1,105 @@
+
+ The "Artistic License"
+
+ Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.
+
+6. Any programs linked with this library do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+
+7. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+8. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
+
diff --git a/eBones/des/docs.original/CHANGES b/eBones/des/docs.original/CHANGES
new file mode 100644
index 0000000..4f441fa
--- /dev/null
+++ b/eBones/des/docs.original/CHANGES
@@ -0,0 +1,16 @@
+The main changes in this package since it was last posted to
+comp.sources.misc are
+
+The main changes are
+- Major changes to the Copyright restrictions.
+- Lots and lots of features added to the des(1) command, including
+ - Triple DES, both triple ECB and triple CBC options.
+ - uuencodeing/uudecoding built in to des(1).
+ - generate checksums.
+ - hex keys.
+- Cleaned up the prototypes in des.h
+- Filenames are now mostly <= 8 characters long.
+- OFB, CFB, triple ECB and triple CBC modes of DES added to the library.
+- Compiles and runs of all 64bit machines I could test the code on
+ (Cray, ETA10, DEC Alpha).
+- It really does work with kerberos v 4 now :-).
diff --git a/eBones/des/docs.original/COPYING b/eBones/des/docs.original/COPYING
new file mode 100644
index 0000000..9b1a932
--- /dev/null
+++ b/eBones/des/docs.original/COPYING
@@ -0,0 +1,489 @@
+Copyright (C) 1993 Eric Young
+
+This is a DES implementation written by Eric Young (eay@psych.psy.uq.oz.au)
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/eBones/des/docs.original/FILES b/eBones/des/docs.original/FILES
new file mode 100644
index 0000000..a010ad1
--- /dev/null
+++ b/eBones/des/docs.original/FILES
@@ -0,0 +1,60 @@
+/* General stuff */
+CHANGES - Changes since the last posting to comp.sources.misc.
+ARTISTIC - Copying info.
+COPYING - Copying info.
+MODES.DES - A description of the features of the different modes of DES.
+FILES - This file.
+INSTALL - How to make things compile.
+Imakefile - For use with kerberos.
+README - What this package is.
+VERSION - Which version this is.
+KERBEROS - Kerberos version 4 notes.
+makefile - The make file.
+times - Some outputs from 'speed' on my local machines.
+vms.com - For use when compiling under VMS
+
+/* My sunOS des(1) replacement */
+des.c - des(1) source code.
+des.man - des(1) manual.
+
+/* Testing and timing programs. */
+destest.c - Source for libdes.a test program.
+speed.c - Source for libdes.a timing program.
+rpw.c - Source for libdes.a testing password reading routines.
+
+/* libdes.a source code */
+des_crypt.man - libdes.a manual page.
+des.h - Public libdes.a header file.
+ecb_enc.c - des_ecb_encrypt() source, this contains the basic DES code.
+3ecb_enc.c - des_3ecb_encrypt() source.
+cbc_ckm.c - des_cbc_cksum() source.
+cbc_enc.c - des_cbc_encrypt() source.
+3cbc_enc.c - des_3cbc_encrypt() source.
+cfb_enc.c - des_cfb_encrypt() source.
+ofb_enc.c - des_cfb_encrypt() source.
+enc_read.c - des_enc_read() source.
+enc_writ.c - des_enc_write() source.
+pcbc_enc.c - des_pcbc_encrypt() source.
+qud_cksm.c - quad_cksum() source.
+rand_key.c - des_random_key() source.
+read_pwd.c - Source for des_read_password() plus related functions.
+set_key.c - Source for des_set_key().
+str2key.c - Covert a string of any length into a key.
+fcrypt.c - A small, fast version of crypt(3).
+des_locl.h - Internal libdes.a header file.
+podd.h - Odd parity tables - used in des_set_key().
+sk.h - Lookup tables used in des_set_key().
+spr.h - What is left of the S tables - used in ecb_encrypt().
+
+/* The perl scripts - you can ignore these files they are only
+ * included for the curious */
+des.pl - des in perl anyone? des_set_key and des_ecb_encrypt
+ both done in a perl library.
+testdes.pl - Testing program for des.pl
+doIP - Perl script used to develop IP xor/shift code.
+doPC1 - Perl script used to develop PC1 xor/shift code.
+doPC2 - Generates sk.h.
+PC1 - Output of doPC1 should be the same as output from PC1.
+PC2 - used in development of doPC2.
+shifts.pl - Perl library used by my perl scripts.
+
diff --git a/eBones/des/docs.original/INSTALL b/eBones/des/docs.original/INSTALL
new file mode 100644
index 0000000..d34debe
--- /dev/null
+++ b/eBones/des/docs.original/INSTALL
@@ -0,0 +1,53 @@
+Check the CC and CFLAGS lines in the makefile
+
+If your C library does not support the times(3) function, change the
+#define TIMES to
+#undef TIMES in speed.c
+If it does, check the HZ value for the times(3) function.
+If your system does not define CLK_TCK it will be assumed to
+be 60.
+
+If possible use gcc v 2.2.2
+Turn on the maximum optimising
+
+type 'make'
+
+run './destest' to check things are ok.
+run './rpw' to check the tty code for reading passwords works.
+run './speed' to see how fast those optimisations make the library run :-)
+
+A make install will by default install
+libdes.a in /usr/local/lib/libdes.a
+des in /usr/local/bin/des
+des_crypt.man in /usr/local/man/man3/des_crypt.3
+des.man in /usr/local/man/man1/des.1
+des.h in /usr/include/des.h
+
+des(1) should be compatible with sunOS's but I have been unable to
+test it.
+
+These routines should compile on MSDOS, most 32bit and 64bit version
+of Unix (BSD and SYSV) and VMS, without modification.
+The only problems should be #include files that are in the wrong places.
+
+These routines can be compiled under MSDOS.
+I have successfully encrypted files using des(1) under MSDOS and then
+decrypted the files on a SparcStation.
+I have been able to compile and test the routines with
+Microsoft C v 5.1 and Turbo C v 2.0.
+The code in this library is in no way optimised for the 16bit
+operation of MSDOS. Microsoft C generates code that is 40% slower
+than Turbo C's code. I believe this is due to problems it has with
+code generation with the 32bit shift operation in the IP and FP
+sections. I have added some 16bit optimization in ecb_encrypt.c
+and this generated a %70 speedup under Turbo C. Such are the
+limitations of DOS compilers :-(.
+
+For Turbo C v 2.0, make sure to define MSDOS, in the relevant menu.
+
+There is an alternative version of the D_ENCRYPT macro that can be
+enabled with the -DALT_ECB option in the makefile. This alternative
+macro can make a +-%20 speed difference to the DES encryption speed,
+depending on the compiler/CPU combinations.
+It has its greatest effect on Sparc machines when using the sun compiler.
+If in doubt, try enable/disable it and running speed.
diff --git a/eBones/des/docs.original/KERBEROS b/eBones/des/docs.original/KERBEROS
new file mode 100644
index 0000000..d8734b2
--- /dev/null
+++ b/eBones/des/docs.original/KERBEROS
@@ -0,0 +1,38 @@
+To use this library with Bones (kerberos without DES):
+1) Get my modified Bones - eBones. It can be found on
+ gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z
+ and
+ nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z
+
+2) Unpack this library in src/lib/des, makeing sure it is version
+ 3.00 or greater (libdes.tar.93-10-07.Z). This versions differences
+ from the version in comp.sources.misc volume 29 patchlevel2.
+ The primarily difference is that it should compile under kerberos :-).
+ It can be found at.
+ ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z
+
+Now do a normal kerberos build and things should work.
+
+One problem I found when I was build on my local sun.
+---
+For sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c
+
+*** make_commands.c.orig Fri Jul 3 04:18:35 1987
+--- make_commands.c Wed May 20 08:47:42 1992
+***************
+*** 98,104 ****
+ if (!rename(o_file, z_file)) {
+ if (!vfork()) {
+ chdir("/tmp");
+! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n",
+ z_file+5, 0);
+ perror("/bin/ld");
+ _exit(1);
+--- 98,104 ----
+ if (!rename(o_file, z_file)) {
+ if (!vfork()) {
+ chdir("/tmp");
+! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r",
+ z_file+5, 0);
+ perror("/bin/ld");
+ _exit(1);
diff --git a/eBones/des/docs.original/MODES.DES b/eBones/des/docs.original/MODES.DES
new file mode 100644
index 0000000..fe9c038
--- /dev/null
+++ b/eBones/des/docs.original/MODES.DES
@@ -0,0 +1,84 @@
+Modes of DES
+Quite a bit of the following information has been taken from
+ AS 2805.5.2
+ Australian Standard
+ Electronic funds transfer - Requirements for interfaces,
+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
+ Appendix A
+
+There are several different modes in which DES can be used, they are
+as follows.
+
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
+- 64 bits are enciphered at a time.
+- The order of the blocks can be rearranged without detection.
+- The same plaintext block always produces the same ciphertext block
+ (for the same key) making it vulnerable to a 'dictionary attack'.
+- An error will only affect one ciphertext block.
+
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
+- a multiple of 64 bits are enciphered at a time.
+- The CBC mode produces the same ciphertext whenever the same
+ plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext blocks dependent on the
+ current and all preceding plaintext blocks and therefore blocks can not
+ be rearranged.
+- The use of different starting variables prevents the same plaintext
+ enciphering to the same ciphertext.
+- An error will affect the current and the following ciphertext blocks.
+
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The CFB mode produces the same ciphertext whenever the same
+ plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext variables dependent on the
+ current and all preceding variables and therefore j-bit variables are
+ chained together and con not be rearranged.
+- The use of different starting variables prevents the same plaintext
+ enciphering to the same ciphertext.
+- The strength of the CFB mode depends on the size of k (maximal if
+ j == k). In my implementation this is always the case.
+- Selection of a small value for j will require more cycles through
+ the encipherment algorithm per unit of plaintext and thus cause
+ greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- An error will affect the current and the following ciphertext variables.
+
+Output Feedback Mode (OFB) (des_ofb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The OFB mode produces the same ciphertext whenever the same
+ plaintext enciphered using the same key and starting variable. More
+ over, in the OFB mode the same key stream is produced when the same
+ key and start variable are used. Consequently, for security reasons
+ a specific start variable should be used only once for a given key.
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
+- The use of different start variables values prevents the same
+ plaintext enciphering to the same ciphertext, by producing different
+ key streams.
+- Selection of a small value for j will require more cycles through
+ the encipherment algorithm per unit of plaintext and thus cause
+ greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- OFB mode of operation does not extend ciphertext errors in the
+ resultant plaintext output. Every bit error in the ciphertext causes
+ only one bit to be in error in the deciphered plaintext.
+- OFB mode is not self-synchronising. If the two operation of
+ encipherment and decipherment get out of synchronism, the system needs
+ to be re-initialised.
+- Each re-initialisation should use a value of the start variable
+different from the start variable values used before with the same
+key. The reason for this is that an identical bit stream would be
+produced each time from the same parameters. This would be
+susceptible to a ' known plaintext' attack.
+
+Triple ECB Mode (des_3ecb_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key1 again.
+- As for ECB encryption but increases the effective key length to 112 bits.
+- If both keys are the same it is equivalent to encrypting once with
+ just one key.
+
+Triple CBC Mode (des_3cbc_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key1 again.
+- As for CBC encryption but increases the effective key length to 112 bits.
+- If both keys are the same it is equivalent to encrypting once with
+ just one key.
diff --git a/eBones/des/docs.original/README b/eBones/des/docs.original/README
new file mode 100644
index 0000000..6acd62c
--- /dev/null
+++ b/eBones/des/docs.original/README
@@ -0,0 +1,56 @@
+
+ libdes, Version 3.00 93/10/07
+
+ Copyright (c) 1993, Eric Young
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of either:
+
+ a) the GNU General Public License as published by the Free
+ Software Foundation; either version 1, or (at your option) any
+ later version, or
+
+ b) the "Artistic License" which comes with this Kit.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
+ the GNU General Public License or the Artistic License for more details.
+
+ You should have received a copy of the Artistic License with this
+ Kit, in the file named "Artistic". If not, I'll be glad to provide one.
+
+ You should also have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+---
+This kit builds a DES encryption library and a DES encryption program.
+It suports ecb, cbc, ofb, cfb, triple ecb, triple cbc and MIT's pcbc
+encryption modes and also has a fast implementation of crypt(3).
+It contains support routines to read keys from a terminal,
+generate a random key, generate a key from an arbitary length string,
+read/write encrypted data from/to a file descriptor.
+
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+destest should be run after compilation to test the des routines.
+rpw should be run after compilation to test the read password routines.
+The des program is a replacement for the sun des command. I believe it
+conforms to the sun version.
+
+The Imakefile is setup for use in the kerberos distribution.
+
+These routines are best compiled with gcc or any other good
+optimising compiler.
+Just turn you optimiser up to the highest settings and run destest
+after the build to make sure everything works.
+
+I believe these routines are close to the fastest and most portable DES
+routines that use small lookup tables (4.5k) that are publicly available.
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
+(on a sun3/260 168 vs 336).
+
+Eric Young (eay@psych.psy.uq.oz.au)
diff --git a/eBones/des/docs.original/VERSION b/eBones/des/docs.original/VERSION
new file mode 100644
index 0000000..21e3b8d
--- /dev/null
+++ b/eBones/des/docs.original/VERSION
@@ -0,0 +1,185 @@
+Release apon comp.sources.misc
+Version 3.01 08/10/93
+ Added des_3cbc_encrypt()
+
+Version 3.00 07/10/93
+ Fixed up documentation.
+ quad_cksum definitly compatable with MIT's now.
+
+Version 2.30 24/08/93
+ Tripple DES now defaults to tripple cbc but can do tripple ecb
+ with the -b flag.
+ Fixed some MSDOS uuen/uudecoding problems, thanks to
+ Added prototypes.
+
+Version 2.22 29/06/93
+ Fixed a bug in des_is_weak_key() which stopped it working :-(
+ thanks to engineering@MorningStar.Com.
+
+Version 2.21 03/06/93
+ des(1) with no arguments gives quite a bit of help.
+ Added -c (generate ckecksum) flag to des(1).
+ Added -3 (tripple DES) flag to des(1).
+ Added cfb and ofb routines to the library.
+
+Version 2.20 11/03/93
+ Added -u (uuencode) flag to des(1).
+ I have been playing with byte order in quad_cksum to make it
+ compatible with MIT's version. All I can say is aviod this
+ function if possible since MIT's output is endian dependent.
+
+Version 2.12 14/10/92
+ Added MSDOS specific macro in ecb_encrypt which gives a %70
+ speed up when the code is compiled with turbo C.
+
+Version 2.11 12/10/92
+ Speedup in set_key (recoding of PC-1)
+ I now do it in 47 simple operations, down from 60.
+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ for motivating me to look for a faster system :-)
+ The speedup is probably less that 1% but it is still 13
+ instructions less :-).
+
+Version 2.10 06/10/92
+ The code now works on the 64bit ETA10 and CRAY without modifications or
+ #defines. I believe the code should work on any machine that
+ defines long, int or short to be 8 bytes long.
+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
+ for helping me fix the code to run on 64bit machines (he had
+ access to an ETA10).
+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
+ for testing the routines on a CRAY.
+ read_password.c has been renamed to read_passwd.c
+ string_to_key.c has been renamed to string2key.c
+
+Version 2.00 14/09/92
+ Made mods so that the library should work on 64bit CPU's.
+ Removed all my uchar and ulong defs. To many different
+ versions of unix define them in their header files in too many
+ different combinations :-)
+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
+
+Version 1.99 26/08/92
+ Fixed a bug or 2 in enc_read.c
+ Fixed a bug in enc_write.c
+ Fixed a pseudo bug in fcrypt.c (very obscure).
+
+Version 1.98 31/07/92
+ Support for the ETA10. This is a strange machine that defines
+ longs and ints as 8 bytes and shorts as 4 bytes.
+ Since I do evil things with long * that assume that they are 4
+ bytes. Look in the Makefile for the option to compile for
+ this machine. quad_cksum appears to have problems but I
+ will don't have the time to fix it right now, and this is not
+ a function that uses DES and so will not effect the main uses
+ of the library.
+
+Version 1.97 20/05/92 eay
+ Fixed the Imakefile and made some changes to des.h to fix some
+ problems when building this package with Kerberos v 4.
+
+Version 1.96 18/05/92 eay
+ Fixed a small bug in string_to_key() where problems could
+ occur if des_check_key was set to true and the string
+ generated a weak key.
+
+Patch2 posted to comp.sources.misc
+Version 1.95 13/05/92 eay
+ Added an alternative version of the D_ENCRYPT macro in
+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
+ other will be faster. This was inspired by
+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
+ *(ulong *)((uchar *)ptr+(value&0xfc))
+ vs
+ ptr[value&0x3f]
+ to stop the C compiler doing a <<2 to convert the long array index.
+
+Version 1.94 05/05/92 eay
+ Fixed an incompatibility between my string_to_key and the MIT
+ version. When the key is longer than 8 chars, I was wrapping
+ with a different method. To use the old version, define
+ OLD_STR_TO_KEY in the makefile. Thanks to
+ viktor@newsu.shearson.com (Viktor Dukhovni).
+
+Version 1.93 28/04/92 eay
+ Fixed the VMS mods so that echo is now turned off in
+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
+ MSDOS support added. The routines can be compiled with
+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
+
+Patch1 posted to comp.sources.misc
+Version 1.92 13/04/92 eay
+ Changed D_ENCRYPT so that the rotation of R occurs outside of
+ the loop. This required rotating all the longs in sp.h (now
+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ speed.c has been changed so it will work without SIGALRM. If
+ times(3) is not present it will try to use ftime() instead.
+
+Version 1.91 08/04/92 eay
+ Added -E/-D options to des(1) so it can use string_to_key.
+ Added SVR4 mods suggested by witr@rwwa.COM
+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
+ anyone knows how to turn of tty echo in VMS please tell me or
+ implement it yourself :-).
+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
+ does not like IN/OUT being used.
+
+Libdes posted to comp.sources.misc
+Version 1.9 24/03/92 eay
+ Now contains a fast small crypt replacement.
+ Added des(1) command.
+ Added des_rw_mode so people can use cbc encryption with
+ enc_read and enc_write.
+
+Version 1.8 15/10/91 eay
+ Bug in cbc_cksum.
+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
+ one out.
+
+Version 1.7 24/09/91 eay
+ Fixed set_key :-)
+ set_key is 4 times faster and takes less space.
+ There are a few minor changes that could be made.
+
+Version 1.6 19/09/1991 eay
+ Finally go IP and FP finished.
+ Now I need to fix set_key.
+ This version is quite a bit faster that 1.51
+
+Version 1.52 15/06/1991 eay
+ 20% speedup in ecb_encrypt by changing the E bit selection
+ to use 2 32bit words. This also required modification of the
+ sp table. There is still a way to speedup the IP and IP-1
+ (hints from outer@sq.com) still working on this one :-(.
+
+Version 1.51 07/06/1991 eay
+ Faster des_encrypt by loop unrolling
+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
+
+Version 1.50 28/05/1991 eay
+ Optimized the code a bit more for the sparc. I have improved the
+ speed of the inner des_encrypt by speeding up the initial and
+ final permutations.
+
+Version 1.40 23/10/1990 eay
+ Fixed des_random_key, it did not produce a random key :-(
+
+Version 1.30 2/10/1990 eay
+ Have made des_quad_cksum the same as MIT's, the full package
+ should be compatible with MIT's
+ Have tested on a DECstation 3100
+ Still need to fix des_set_key (make it faster).
+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
+
+Version 1.20 18/09/1990 eay
+ Fixed byte order dependencies.
+ Fixed (I hope) all the word alignment problems.
+ Speedup in des_ecb_encrypt.
+
+Version 1.10 11/09/1990 eay
+ Added des_enc_read and des_enc_write.
+ Still need to fix des_quad_cksum.
+ Still need to document des_enc_read and des_enc_write.
+
+Version 1.00 27/08/1990 eay
diff --git a/eBones/des/ecb_enc.c b/eBones/des/ecb_enc.c
new file mode 100644
index 0000000..e410eb8
--- /dev/null
+++ b/eBones/des/ecb_enc.c
@@ -0,0 +1,123 @@
+/* ecb_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: ecb_enc.c,v 1.2 1994/07/19 19:21:53 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+#include "spr.h"
+
+int des_ecb_encrypt(input,output,ks,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule ks;
+int encrypt;
+ {
+ register unsigned long l0,l1;
+ register unsigned char *in,*out;
+ unsigned long ll[2];
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ c2l(in,l0);
+ c2l(in,l1);
+ ll[0]=l0;
+ ll[1]=l1;
+ des_encrypt(ll,ll,ks,encrypt);
+ l0=ll[0];
+ l1=ll[1];
+ l2c(l0,out);
+ l2c(l1,out);
+ l0=l1=ll[0]=ll[1]=0;
+ return(0);
+ }
+
+int des_encrypt(input,output,ks,encrypt)
+unsigned long *input;
+unsigned long *output;
+des_key_schedule ks;
+int encrypt;
+ {
+ register unsigned long l,r,t,u;
+#ifdef ALT_ECB
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifdef MSDOS
+ union fudge {
+ unsigned long l;
+ unsigned short s[2];
+ unsigned char c[4];
+ } U,T;
+#endif
+ register int i;
+ register unsigned long *s;
+
+ l=input[0];
+ r=input[1];
+
+ /* do IP */
+ PERM_OP(r,l,t, 4,0x0f0f0f0f);
+ PERM_OP(l,r,t,16,0x0000ffff);
+ PERM_OP(r,l,t, 2,0x33333333);
+ PERM_OP(l,r,t, 8,0x00ff00ff);
+ PERM_OP(r,l,t, 1,0x55555555);
+ /* r and l are reversed - remember that :-) - fix
+ * it in the next step */
+
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ t=(r<<1)|(r>>31);
+ r=(l<<1)|(l>>31);
+ l=t;
+
+ /* clear the top bits on machines with 8byte longs */
+ l&=0xffffffff;
+ r&=0xffffffff;
+
+ s=(unsigned long *)ks;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (encrypt)
+ {
+ for (i=0; i<32; i+=4)
+ {
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ }
+ }
+ else
+ {
+ for (i=30; i>0; i-=4)
+ {
+ D_ENCRYPT(l,r,i-0); /* 16 */
+ D_ENCRYPT(r,l,i-2); /* 15 */
+ }
+ }
+ l=(l>>1)|(l<<31);
+ r=(r>>1)|(r<<31);
+ /* clear the top bits on machines with 8byte longs */
+ l&=0xffffffff;
+ r&=0xffffffff;
+
+ /* swap l and r
+ * we will not do the swap so just remember they are
+ * reversed for the rest of the subroutine
+ * luckily FP fixes this problem :-) */
+
+ PERM_OP(r,l,t, 1,0x55555555);
+ PERM_OP(l,r,t, 8,0x00ff00ff);
+ PERM_OP(r,l,t, 2,0x33333333);
+ PERM_OP(l,r,t,16,0x0000ffff);
+ PERM_OP(r,l,t, 4,0x0f0f0f0f);
+
+ output[0]=l;
+ output[1]=r;
+ l=r=t=u=0;
+ return(0);
+ }
+
diff --git a/eBones/des/enc_read.c b/eBones/des/enc_read.c
new file mode 100644
index 0000000..1b77c4c
--- /dev/null
+++ b/eBones/des/enc_read.c
@@ -0,0 +1,147 @@
+/* enc_read.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: enc_read.c,v 1.2 1994/07/19 19:21:54 g89r4222 Exp $
+ */
+
+#include <errno.h>
+#include "des_locl.h"
+
+/* This has some uglies in it but it works - even over sockets. */
+extern int errno;
+int des_rw_mode=DES_PCBC_MODE;
+
+int des_enc_read(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+ {
+ /* data to be unencrypted */
+ int net_num=0;
+ unsigned char net[BSIZE];
+ /* extra unencrypted data
+ * for when a block of 100 comes in but is des_read one byte at
+ * a time. */
+ static char unnet[BSIZE];
+ static int unnet_start=0;
+ static int unnet_left=0;
+ int i;
+ long num=0,rnum;
+ unsigned char *p;
+
+ /* left over data from last decrypt */
+ if (unnet_left != 0)
+ {
+ if (unnet_left < len)
+ {
+ /* we still still need more data but will return
+ * with the number of bytes we have - should always
+ * check the return value */
+ bcopy(&(unnet[unnet_start]),buf,unnet_left);
+ /* eay 26/08/92 I had the next 2 lines
+ * reversed :-( */
+ i=unnet_left;
+ unnet_start=unnet_left=0;
+ }
+ else
+ {
+ bcopy(&(unnet[unnet_start]),buf,len);
+ unnet_start+=len;
+ unnet_left-=len;
+ i=len;
+ }
+ return(i);
+ }
+
+ /* We need to get more data. */
+ if (len > MAXWRITE) len=MAXWRITE;
+
+ /* first - get the length */
+ net_num=0;
+ while (net_num < HDRSIZE)
+ {
+ i=read(fd,&(net[net_num]),HDRSIZE-net_num);
+ if ((i == -1) && (errno == EINTR)) continue;
+ if (i <= 0) return(0);
+ net_num+=i;
+ }
+
+ /* we now have at net_num bytes in net */
+ p=net;
+ num=0;
+ n2l(p,num);
+ /* num should be rounded up to the next group of eight
+ * we make sure that we have read a multiple of 8 bytes from the net.
+ */
+ if ((num > MAXWRITE) || (num < 0)) /* error */
+ return(-1);
+ rnum=(num < 8)?8:((num+7)/8*8);
+
+ net_num=0;
+ while (net_num < rnum)
+ {
+ i=read(fd,&(net[net_num]),rnum-net_num);
+ if ((i == -1) && (errno == EINTR)) continue;
+ if (i <= 0) return(0);
+ net_num+=i;
+ }
+
+ /* Check if there will be data left over. */
+ if (len < num)
+ {
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+ num,sched,iv,DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+ num,sched,iv,DES_DECRYPT);
+ bcopy(unnet,buf,len);
+ unnet_start=len;
+ unnet_left=num-len;
+
+ /* The following line is done because we return num
+ * as the number of bytes read. */
+ num=len;
+ }
+ else
+ {
+ /* >output is a multiple of 8 byes, if len < rnum
+ * >we must be careful. The user must be aware that this
+ * >routine will write more bytes than he asked for.
+ * >The length of the buffer must be correct.
+ * FIXED - Should be ok now 18-9-90 - eay */
+ if (len < rnum)
+ {
+ char tmpbuf[BSIZE];
+
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,
+ (des_cblock *)tmpbuf,
+ num,sched,iv,DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,
+ (des_cblock *)tmpbuf,
+ num,sched,iv,DES_DECRYPT);
+
+ /* eay 26/08/92 fix a bug that returned more
+ * bytes than you asked for (returned len bytes :-( */
+ bcopy(tmpbuf,buf,num);
+ }
+ else
+ {
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,
+ (des_cblock *)buf,num,sched,iv,
+ DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,
+ (des_cblock *)buf,num,sched,iv,
+ DES_DECRYPT);
+ }
+ }
+ return(num);
+ }
+
diff --git a/eBones/des/enc_writ.c b/eBones/des/enc_writ.c
new file mode 100644
index 0000000..602106b
--- /dev/null
+++ b/eBones/des/enc_writ.c
@@ -0,0 +1,94 @@
+/* enc_writ.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: enc_writ.c,v 1.2 1994/07/19 19:21:56 g89r4222 Exp $
+ */
+
+#include <errno.h>
+#include "des_locl.h"
+
+int des_enc_write(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+ {
+ long rnum;
+ int i,j,k,outnum;
+ char outbuf[BSIZE+HDRSIZE];
+ char shortbuf[8];
+ char *p;
+ static int start=1;
+
+ /* If we are sending less than 8 bytes, the same char will look
+ * the same if we don't pad it out with random bytes */
+ if (start)
+ {
+ start=0;
+ srandom(time(NULL));
+ }
+
+ /* lets recurse if we want to send the data in small chunks */
+ if (len > MAXWRITE)
+ {
+ j=0;
+ for (i=0; i<len; i+=k)
+ {
+ k=des_enc_write(fd,&(buf[i]),
+ ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
+ if (k < 0)
+ return(k);
+ else
+ j+=k;
+ }
+ return(j);
+ }
+
+ /* write length first */
+ p=outbuf;
+ l2n(len,p);
+
+ /* pad short strings */
+ if (len < 8)
+ {
+ p=shortbuf;
+ bcopy(buf,shortbuf,len);
+ for (i=len; i<8; i++)
+ shortbuf[i]=random();
+ rnum=8;
+ }
+ else
+ {
+ p=buf;
+ rnum=((len+7)/8*8); /* round up to nearest eight */
+ }
+
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+ (long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
+ else
+ cbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+ (long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
+
+ /* output */
+ outnum=rnum+HDRSIZE;
+
+ for (j=0; j<outnum; j+=i)
+ {
+ /* eay 26/08/92 I was not doing writing from where we
+ * got upto. */
+ i=write(fd,&(outbuf[j]),(int)(outnum-j));
+ if (i == -1)
+ {
+ if (errno == EINTR)
+ i=0;
+ else /* This is really a bad error - very bad
+ * It will stuff-up both ends. */
+ return(-1);
+ }
+ }
+
+ return(len);
+ }
diff --git a/eBones/des/fcrypt.c b/eBones/des/fcrypt.c
new file mode 100644
index 0000000..c7f41ce
--- /dev/null
+++ b/eBones/des/fcrypt.c
@@ -0,0 +1,581 @@
+/* fcrypt.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: fcrypt.c,v 1.2 1994/07/19 19:21:58 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+
+/* Eric Young.
+ * This version of crypt has been developed from my MIT compatable
+ * DES library.
+ * The library is available at pub/DES at ftp.psy.uq.oz.au
+ * eay@psych.psy.uq.oz.au
+ */
+
+typedef unsigned char des_cblock[8];
+
+typedef struct des_ks_struct
+ {
+ union {
+ des_cblock _;
+ /* make sure things are correct size on machines with
+ * 8 byte longs */
+ unsigned long pad[2];
+ } ks;
+#define _ ks._
+ } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
+ l|=((unsigned long)(*((c)++)))<< 8, \
+ l|=((unsigned long)(*((c)++)))<<16, \
+ l|=((unsigned long)(*((c)++)))<<24)
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+static unsigned long SPtrans[8][64]={
+/* nibble 0 */
+0x00820200, 0x00020000, 0x80800000, 0x80820200,
+0x00800000, 0x80020200, 0x80020000, 0x80800000,
+0x80020200, 0x00820200, 0x00820000, 0x80000200,
+0x80800200, 0x00800000, 0x00000000, 0x80020000,
+0x00020000, 0x80000000, 0x00800200, 0x00020200,
+0x80820200, 0x00820000, 0x80000200, 0x00800200,
+0x80000000, 0x00000200, 0x00020200, 0x80820000,
+0x00000200, 0x80800200, 0x80820000, 0x00000000,
+0x00000000, 0x80820200, 0x00800200, 0x80020000,
+0x00820200, 0x00020000, 0x80000200, 0x00800200,
+0x80820000, 0x00000200, 0x00020200, 0x80800000,
+0x80020200, 0x80000000, 0x80800000, 0x00820000,
+0x80820200, 0x00020200, 0x00820000, 0x80800200,
+0x00800000, 0x80000200, 0x80020000, 0x00000000,
+0x00020000, 0x00800000, 0x80800200, 0x00820200,
+0x80000000, 0x80820000, 0x00000200, 0x80020200,
+/* nibble 1 */
+0x10042004, 0x00000000, 0x00042000, 0x10040000,
+0x10000004, 0x00002004, 0x10002000, 0x00042000,
+0x00002000, 0x10040004, 0x00000004, 0x10002000,
+0x00040004, 0x10042000, 0x10040000, 0x00000004,
+0x00040000, 0x10002004, 0x10040004, 0x00002000,
+0x00042004, 0x10000000, 0x00000000, 0x00040004,
+0x10002004, 0x00042004, 0x10042000, 0x10000004,
+0x10000000, 0x00040000, 0x00002004, 0x10042004,
+0x00040004, 0x10042000, 0x10002000, 0x00042004,
+0x10042004, 0x00040004, 0x10000004, 0x00000000,
+0x10000000, 0x00002004, 0x00040000, 0x10040004,
+0x00002000, 0x10000000, 0x00042004, 0x10002004,
+0x10042000, 0x00002000, 0x00000000, 0x10000004,
+0x00000004, 0x10042004, 0x00042000, 0x10040000,
+0x10040004, 0x00040000, 0x00002004, 0x10002000,
+0x10002004, 0x00000004, 0x10040000, 0x00042000,
+/* nibble 2 */
+0x41000000, 0x01010040, 0x00000040, 0x41000040,
+0x40010000, 0x01000000, 0x41000040, 0x00010040,
+0x01000040, 0x00010000, 0x01010000, 0x40000000,
+0x41010040, 0x40000040, 0x40000000, 0x41010000,
+0x00000000, 0x40010000, 0x01010040, 0x00000040,
+0x40000040, 0x41010040, 0x00010000, 0x41000000,
+0x41010000, 0x01000040, 0x40010040, 0x01010000,
+0x00010040, 0x00000000, 0x01000000, 0x40010040,
+0x01010040, 0x00000040, 0x40000000, 0x00010000,
+0x40000040, 0x40010000, 0x01010000, 0x41000040,
+0x00000000, 0x01010040, 0x00010040, 0x41010000,
+0x40010000, 0x01000000, 0x41010040, 0x40000000,
+0x40010040, 0x41000000, 0x01000000, 0x41010040,
+0x00010000, 0x01000040, 0x41000040, 0x00010040,
+0x01000040, 0x00000000, 0x41010000, 0x40000040,
+0x41000000, 0x40010040, 0x00000040, 0x01010000,
+/* nibble 3 */
+0x00100402, 0x04000400, 0x00000002, 0x04100402,
+0x00000000, 0x04100000, 0x04000402, 0x00100002,
+0x04100400, 0x04000002, 0x04000000, 0x00000402,
+0x04000002, 0x00100402, 0x00100000, 0x04000000,
+0x04100002, 0x00100400, 0x00000400, 0x00000002,
+0x00100400, 0x04000402, 0x04100000, 0x00000400,
+0x00000402, 0x00000000, 0x00100002, 0x04100400,
+0x04000400, 0x04100002, 0x04100402, 0x00100000,
+0x04100002, 0x00000402, 0x00100000, 0x04000002,
+0x00100400, 0x04000400, 0x00000002, 0x04100000,
+0x04000402, 0x00000000, 0x00000400, 0x00100002,
+0x00000000, 0x04100002, 0x04100400, 0x00000400,
+0x04000000, 0x04100402, 0x00100402, 0x00100000,
+0x04100402, 0x00000002, 0x04000400, 0x00100402,
+0x00100002, 0x00100400, 0x04100000, 0x04000402,
+0x00000402, 0x04000000, 0x04000002, 0x04100400,
+/* nibble 4 */
+0x02000000, 0x00004000, 0x00000100, 0x02004108,
+0x02004008, 0x02000100, 0x00004108, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x00004100,
+0x02000108, 0x02004008, 0x02004100, 0x00000000,
+0x00004100, 0x02000000, 0x00004008, 0x00000108,
+0x02000100, 0x00004108, 0x00000000, 0x02000008,
+0x00000008, 0x02000108, 0x02004108, 0x00004008,
+0x02004000, 0x00000100, 0x00000108, 0x02004100,
+0x02004100, 0x02000108, 0x00004008, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x02000100,
+0x02000000, 0x00004100, 0x02004108, 0x00000000,
+0x00004108, 0x02000000, 0x00000100, 0x00004008,
+0x02000108, 0x00000100, 0x00000000, 0x02004108,
+0x02004008, 0x02004100, 0x00000108, 0x00004000,
+0x00004100, 0x02004008, 0x02000100, 0x00000108,
+0x00000008, 0x00004108, 0x02004000, 0x02000008,
+/* nibble 5 */
+0x20000010, 0x00080010, 0x00000000, 0x20080800,
+0x00080010, 0x00000800, 0x20000810, 0x00080000,
+0x00000810, 0x20080810, 0x00080800, 0x20000000,
+0x20000800, 0x20000010, 0x20080000, 0x00080810,
+0x00080000, 0x20000810, 0x20080010, 0x00000000,
+0x00000800, 0x00000010, 0x20080800, 0x20080010,
+0x20080810, 0x20080000, 0x20000000, 0x00000810,
+0x00000010, 0x00080800, 0x00080810, 0x20000800,
+0x00000810, 0x20000000, 0x20000800, 0x00080810,
+0x20080800, 0x00080010, 0x00000000, 0x20000800,
+0x20000000, 0x00000800, 0x20080010, 0x00080000,
+0x00080010, 0x20080810, 0x00080800, 0x00000010,
+0x20080810, 0x00080800, 0x00080000, 0x20000810,
+0x20000010, 0x20080000, 0x00080810, 0x00000000,
+0x00000800, 0x20000010, 0x20000810, 0x20080800,
+0x20080000, 0x00000810, 0x00000010, 0x20080010,
+/* nibble 6 */
+0x00001000, 0x00000080, 0x00400080, 0x00400001,
+0x00401081, 0x00001001, 0x00001080, 0x00000000,
+0x00400000, 0x00400081, 0x00000081, 0x00401000,
+0x00000001, 0x00401080, 0x00401000, 0x00000081,
+0x00400081, 0x00001000, 0x00001001, 0x00401081,
+0x00000000, 0x00400080, 0x00400001, 0x00001080,
+0x00401001, 0x00001081, 0x00401080, 0x00000001,
+0x00001081, 0x00401001, 0x00000080, 0x00400000,
+0x00001081, 0x00401000, 0x00401001, 0x00000081,
+0x00001000, 0x00000080, 0x00400000, 0x00401001,
+0x00400081, 0x00001081, 0x00001080, 0x00000000,
+0x00000080, 0x00400001, 0x00000001, 0x00400080,
+0x00000000, 0x00400081, 0x00400080, 0x00001080,
+0x00000081, 0x00001000, 0x00401081, 0x00400000,
+0x00401080, 0x00000001, 0x00001001, 0x00401081,
+0x00400001, 0x00401080, 0x00401000, 0x00001001,
+/* nibble 7 */
+0x08200020, 0x08208000, 0x00008020, 0x00000000,
+0x08008000, 0x00200020, 0x08200000, 0x08208020,
+0x00000020, 0x08000000, 0x00208000, 0x00008020,
+0x00208020, 0x08008020, 0x08000020, 0x08200000,
+0x00008000, 0x00208020, 0x00200020, 0x08008000,
+0x08208020, 0x08000020, 0x00000000, 0x00208000,
+0x08000000, 0x00200000, 0x08008020, 0x08200020,
+0x00200000, 0x00008000, 0x08208000, 0x00000020,
+0x00200000, 0x00008000, 0x08000020, 0x08208020,
+0x00008020, 0x08000000, 0x00000000, 0x00208000,
+0x08200020, 0x08008020, 0x08008000, 0x00200020,
+0x08208000, 0x00000020, 0x00200020, 0x08008000,
+0x08208020, 0x00200000, 0x08200000, 0x08000020,
+0x00208000, 0x00008020, 0x08008020, 0x08200000,
+0x00000020, 0x08208000, 0x00208020, 0x00000000,
+0x08000000, 0x08200020, 0x00008000, 0x00208020};
+static unsigned long skb[8][64]={
+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x00000010,0x20000000,0x20000010,
+0x00010000,0x00010010,0x20010000,0x20010010,
+0x00000800,0x00000810,0x20000800,0x20000810,
+0x00010800,0x00010810,0x20010800,0x20010810,
+0x00000020,0x00000030,0x20000020,0x20000030,
+0x00010020,0x00010030,0x20010020,0x20010030,
+0x00000820,0x00000830,0x20000820,0x20000830,
+0x00010820,0x00010830,0x20010820,0x20010830,
+0x00080000,0x00080010,0x20080000,0x20080010,
+0x00090000,0x00090010,0x20090000,0x20090010,
+0x00080800,0x00080810,0x20080800,0x20080810,
+0x00090800,0x00090810,0x20090800,0x20090810,
+0x00080020,0x00080030,0x20080020,0x20080030,
+0x00090020,0x00090030,0x20090020,0x20090030,
+0x00080820,0x00080830,0x20080820,0x20080830,
+0x00090820,0x00090830,0x20090820,0x20090830,
+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+0x00000000,0x02000000,0x00002000,0x02002000,
+0x00200000,0x02200000,0x00202000,0x02202000,
+0x00000004,0x02000004,0x00002004,0x02002004,
+0x00200004,0x02200004,0x00202004,0x02202004,
+0x00000400,0x02000400,0x00002400,0x02002400,
+0x00200400,0x02200400,0x00202400,0x02202400,
+0x00000404,0x02000404,0x00002404,0x02002404,
+0x00200404,0x02200404,0x00202404,0x02202404,
+0x10000000,0x12000000,0x10002000,0x12002000,
+0x10200000,0x12200000,0x10202000,0x12202000,
+0x10000004,0x12000004,0x10002004,0x12002004,
+0x10200004,0x12200004,0x10202004,0x12202004,
+0x10000400,0x12000400,0x10002400,0x12002400,
+0x10200400,0x12200400,0x10202400,0x12202400,
+0x10000404,0x12000404,0x10002404,0x12002404,
+0x10200404,0x12200404,0x10202404,0x12202404,
+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+0x00000000,0x00000001,0x00040000,0x00040001,
+0x01000000,0x01000001,0x01040000,0x01040001,
+0x00000002,0x00000003,0x00040002,0x00040003,
+0x01000002,0x01000003,0x01040002,0x01040003,
+0x00000200,0x00000201,0x00040200,0x00040201,
+0x01000200,0x01000201,0x01040200,0x01040201,
+0x00000202,0x00000203,0x00040202,0x00040203,
+0x01000202,0x01000203,0x01040202,0x01040203,
+0x08000000,0x08000001,0x08040000,0x08040001,
+0x09000000,0x09000001,0x09040000,0x09040001,
+0x08000002,0x08000003,0x08040002,0x08040003,
+0x09000002,0x09000003,0x09040002,0x09040003,
+0x08000200,0x08000201,0x08040200,0x08040201,
+0x09000200,0x09000201,0x09040200,0x09040201,
+0x08000202,0x08000203,0x08040202,0x08040203,
+0x09000202,0x09000203,0x09040202,0x09040203,
+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+0x00000000,0x00100000,0x00000100,0x00100100,
+0x00000008,0x00100008,0x00000108,0x00100108,
+0x00001000,0x00101000,0x00001100,0x00101100,
+0x00001008,0x00101008,0x00001108,0x00101108,
+0x04000000,0x04100000,0x04000100,0x04100100,
+0x04000008,0x04100008,0x04000108,0x04100108,
+0x04001000,0x04101000,0x04001100,0x04101100,
+0x04001008,0x04101008,0x04001108,0x04101108,
+0x00020000,0x00120000,0x00020100,0x00120100,
+0x00020008,0x00120008,0x00020108,0x00120108,
+0x00021000,0x00121000,0x00021100,0x00121100,
+0x00021008,0x00121008,0x00021108,0x00121108,
+0x04020000,0x04120000,0x04020100,0x04120100,
+0x04020008,0x04120008,0x04020108,0x04120108,
+0x04021000,0x04121000,0x04021100,0x04121100,
+0x04021008,0x04121008,0x04021108,0x04121108,
+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x10000000,0x00010000,0x10010000,
+0x00000004,0x10000004,0x00010004,0x10010004,
+0x20000000,0x30000000,0x20010000,0x30010000,
+0x20000004,0x30000004,0x20010004,0x30010004,
+0x00100000,0x10100000,0x00110000,0x10110000,
+0x00100004,0x10100004,0x00110004,0x10110004,
+0x20100000,0x30100000,0x20110000,0x30110000,
+0x20100004,0x30100004,0x20110004,0x30110004,
+0x00001000,0x10001000,0x00011000,0x10011000,
+0x00001004,0x10001004,0x00011004,0x10011004,
+0x20001000,0x30001000,0x20011000,0x30011000,
+0x20001004,0x30001004,0x20011004,0x30011004,
+0x00101000,0x10101000,0x00111000,0x10111000,
+0x00101004,0x10101004,0x00111004,0x10111004,
+0x20101000,0x30101000,0x20111000,0x30111000,
+0x20101004,0x30101004,0x20111004,0x30111004,
+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+0x00000000,0x08000000,0x00000008,0x08000008,
+0x00000400,0x08000400,0x00000408,0x08000408,
+0x00020000,0x08020000,0x00020008,0x08020008,
+0x00020400,0x08020400,0x00020408,0x08020408,
+0x00000001,0x08000001,0x00000009,0x08000009,
+0x00000401,0x08000401,0x00000409,0x08000409,
+0x00020001,0x08020001,0x00020009,0x08020009,
+0x00020401,0x08020401,0x00020409,0x08020409,
+0x02000000,0x0A000000,0x02000008,0x0A000008,
+0x02000400,0x0A000400,0x02000408,0x0A000408,
+0x02020000,0x0A020000,0x02020008,0x0A020008,
+0x02020400,0x0A020400,0x02020408,0x0A020408,
+0x02000001,0x0A000001,0x02000009,0x0A000009,
+0x02000401,0x0A000401,0x02000409,0x0A000409,
+0x02020001,0x0A020001,0x02020009,0x0A020009,
+0x02020401,0x0A020401,0x02020409,0x0A020409,
+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+0x00000000,0x00000100,0x00080000,0x00080100,
+0x01000000,0x01000100,0x01080000,0x01080100,
+0x00000010,0x00000110,0x00080010,0x00080110,
+0x01000010,0x01000110,0x01080010,0x01080110,
+0x00200000,0x00200100,0x00280000,0x00280100,
+0x01200000,0x01200100,0x01280000,0x01280100,
+0x00200010,0x00200110,0x00280010,0x00280110,
+0x01200010,0x01200110,0x01280010,0x01280110,
+0x00000200,0x00000300,0x00080200,0x00080300,
+0x01000200,0x01000300,0x01080200,0x01080300,
+0x00000210,0x00000310,0x00080210,0x00080310,
+0x01000210,0x01000310,0x01080210,0x01080310,
+0x00200200,0x00200300,0x00280200,0x00280300,
+0x01200200,0x01200300,0x01280200,0x01280300,
+0x00200210,0x00200310,0x00280210,0x00280310,
+0x01200210,0x01200310,0x01280210,0x01280310,
+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+0x00000000,0x04000000,0x00040000,0x04040000,
+0x00000002,0x04000002,0x00040002,0x04040002,
+0x00002000,0x04002000,0x00042000,0x04042000,
+0x00002002,0x04002002,0x00042002,0x04042002,
+0x00000020,0x04000020,0x00040020,0x04040020,
+0x00000022,0x04000022,0x00040022,0x04040022,
+0x00002020,0x04002020,0x00042020,0x04042020,
+0x00002022,0x04002022,0x00042022,0x04042022,
+0x00000800,0x04000800,0x00040800,0x04040800,
+0x00000802,0x04000802,0x00040802,0x04040802,
+0x00002800,0x04002800,0x00042800,0x04042800,
+0x00002802,0x04002802,0x00042802,0x04042802,
+0x00000820,0x04000820,0x00040820,0x04040820,
+0x00000822,0x04000822,0x00040822,0x04040822,
+0x00002820,0x04002820,0x00042820,0x04042820,
+0x00002822,0x04002822,0x00042822,0x04042822,
+};
+
+/* See ecb_encrypt.c for a pseudo description of these macros. */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))\
+
+static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+
+static int body();
+static int des_set___key();
+
+static int des_set___key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+ {
+ register unsigned long c,d,t,s;
+ register unsigned char *in;
+ register unsigned long *k;
+ register int i;
+
+ k=(unsigned long *)schedule;
+ in=(unsigned char *)key;
+
+ c2l(in,c);
+ c2l(in,d);
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d,c,t,4,0x0f0f0f0f);
+ HPERM_OP(c,t,-2,0xcccc0000);
+ HPERM_OP(d,t,-2,0xcccc0000);
+ PERM_OP (d,c,t,1,0x55555555);
+ PERM_OP (c,d,t,8,0x00ff00ff);
+ PERM_OP (d,c,t,1,0x55555555);
+ d= (((d&0x000000ff)<<16)| (d&0x0000ff00) |
+ ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
+ c&=0x0fffffff;
+
+ for (i=0; i<ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
+ else
+ { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
+ c&=0x0fffffff;
+ d&=0x0fffffff;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s= skb[0][ (c )&0x3f ]|
+ skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
+ skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
+ skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
+ ((c>>22)&0x38)];
+ t= skb[4][ (d )&0x3f ]|
+ skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
+ skb[6][ (d>>15)&0x3f ]|
+ skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
+
+ /* table contained 0213 4657 */
+ *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
+ s= ((s>>16)|(t&0xffff0000));
+
+ s=(s<<4)|(s>>28);
+ *(k++)=s&0xffffffff;
+ }
+ return(0);
+ }
+
+/******************************************************************
+ * modified stuff for crypt.
+ ******************************************************************/
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture. gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ */
+#ifdef ALT_ECB
+#define D_ENCRYPT(L,R,S) \
+ v=(R^(R>>16)); \
+ u=(v&E0); \
+ v=(v&E1); \
+ u=((u^(u<<16))^R^s[S ])<<2; \
+ t=(v^(v<<16))^R^s[S+1]; \
+ t=(t>>2)|(t<<30); \
+ L^= \
+ *(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
+ *(unsigned long *)(des_SP+ ((u )&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
+#else /* original version */
+#define D_ENCRYPT(L,R,S) \
+ v=(R^(R>>16)); \
+ u=(v&E0); \
+ v=(v&E1); \
+ u=(u^(u<<16))^R^s[S ]; \
+ t=(v^(v<<16))^R^s[S+1]; \
+ t=(t>>4)|(t<<28); \
+ L^= SPtrans[1][(t )&0x3f]| \
+ SPtrans[3][(t>> 8)&0x3f]| \
+ SPtrans[5][(t>>16)&0x3f]| \
+ SPtrans[7][(t>>24)&0x3f]| \
+ SPtrans[0][(u )&0x3f]| \
+ SPtrans[2][(u>> 8)&0x3f]| \
+ SPtrans[4][(u>>16)&0x3f]| \
+ SPtrans[6][(u>>24)&0x3f];
+#endif
+
+unsigned char con_salt[128]={
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
+0x3D,0x3E,0x3F,0x00,0x00,0x00,0x00,0x00,
+};
+
+unsigned char cov_2char[64]={
+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+char *crypt(buf,salt)
+char *buf;
+char *salt;
+ {
+ unsigned int i,j,x,y;
+ unsigned long Eswap0=0,Eswap1=0;
+ unsigned long out[2],ll;
+ des_cblock key;
+ des_key_schedule ks;
+ static unsigned char buff[20];
+ unsigned char bb[9];
+ unsigned char *b=bb;
+ unsigned char c,u;
+
+ /* eay 25/08/92
+ * If you call crypt("pwd","*") as often happens when you
+ * have * as the pwd field in /etc/passwd, the function
+ * returns *\0XXXXXXXXX
+ * The \0 makes the string look like * so the pwd "*" would
+ * crypt to "*". This was found when replacing the crypt in
+ * our shared libraries. People found that the disbled
+ * accounts effectivly had no passwd :-(. */
+ if (salt[0] == '\0') salt[0]='A';
+ if (salt[1] == '\0') salt[1]='A';
+ x=buff[0]=salt[0];
+ Eswap0=con_salt[x];
+ x=buff[1]=salt[1];
+ Eswap1=con_salt[x]<<4;
+
+ for (i=0; i<8; i++)
+ {
+ c= *(buf++);
+ if (!c) break;
+ key[i]=(c<<1);
+ }
+ for (; i<8; i++)
+ key[i]=0;
+
+ des_set___key((des_cblock *)(key),ks);
+ body(&out[0],&out[1],ks,Eswap0,Eswap1);
+
+ ll=out[0]; l2c(ll,b);
+ ll=out[1]; l2c(ll,b);
+ y=0;
+ u=0x80;
+ bb[8]=0;
+ for (i=2; i<13; i++)
+ {
+ c=0;
+ for (j=0; j<6; j++)
+ {
+ c<<=1;
+ if (bb[y] & u) c|=1;
+ u>>=1;
+ if (!u)
+ {
+ y++;
+ u=0x80;
+ }
+ }
+ buff[i]=cov_2char[c];
+ }
+ return((char *)buff);
+ }
+
+static int body(out0,out1,ks,Eswap0,Eswap1)
+unsigned long *out0,*out1;
+des_key_schedule *ks;
+unsigned long Eswap0,Eswap1;
+ {
+ register unsigned long l,r,t,u,v;
+#ifdef ALT_ECB
+ register unsigned char *des_SP=(unsigned char *)SPtrans;
+#endif
+ register unsigned long *s;
+ register int i,j;
+ register unsigned long E0,E1;
+
+ l=0;
+ r=0;
+
+ s=(unsigned long *)ks;
+ E0=Eswap0;
+ E1=Eswap1;
+
+ for (j=0; j<25; j++)
+ {
+ for (i=0; i<(ITERATIONS*2); i+=4)
+ {
+ D_ENCRYPT(l,r, i); /* 1 */
+ D_ENCRYPT(r,l, i+2); /* 2 */
+ }
+ t=l;
+ l=r;
+ r=t;
+ }
+ t=r;
+ r=(l>>1)|(l<<31);
+ l=(t>>1)|(t<<31);
+ /* clear the top bits on machines with 8byte longs */
+ l&=0xffffffff;
+ r&=0xffffffff;
+
+ PERM_OP(r,l,t, 1,0x55555555);
+ PERM_OP(l,r,t, 8,0x00ff00ff);
+ PERM_OP(r,l,t, 2,0x33333333);
+ PERM_OP(l,r,t,16,0x0000ffff);
+ PERM_OP(r,l,t, 4,0x0f0f0f0f);
+
+ *out0=l;
+ *out1=r;
+ return(0);
+ }
+
diff --git a/eBones/des/include/des.h b/eBones/des/include/des.h
new file mode 100644
index 0000000..3cfc894
--- /dev/null
+++ b/eBones/des/include/des.h
@@ -0,0 +1,121 @@
+/* des.h */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: des.h,v 1.2 1994/07/19 19:22:17 g89r4222 Exp $
+ */
+
+#ifndef DES_DEFS
+#define DES_DEFS
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct
+ {
+ union {
+ des_cblock _;
+ /* make sure things are correct size on machines with
+ * 8 byte longs */
+ unsigned long pad[2];
+ } ks;
+#define _ ks._
+ } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#define DES_CBC_MODE 0
+#define DES_PCBC_MODE 1
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set__key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef struct des_ks_struct bit_64;
+
+extern int des_check_key; /* defaults to false */
+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
+
+/* The next line is used to disable full ANSI prototypes, if your
+ * compiler has problems with the prototypes, make sure this line always
+ * evaluates to true :-) */
+#if !defined(MSDOS) && !defined(__STDC__)
+#ifndef KERBEROS
+int des_3ecb_encrypt();
+int des_cbc_encrypt();
+int des_3cbc_encrypt();
+int des_cfb_encrypt();
+int des_ecb_encrypt();
+int des_encrypt();
+int des_enc_read();
+int des_enc_write();
+int des_ofb_encrypt();
+int des_pcbc_encrypt();
+int des_random_key();
+int des_read_password();
+int des_read_2passwords();
+int des_read_pw_string();
+int des_is_weak_key();
+int des_set__key();
+int des_key_sched();
+int des_string_to_key();
+int des_string_to_2keys();
+#endif
+char *crypt();
+unsigned long des_cbc_cksum();
+unsigned long des_quad_cksum();
+unsigned long des_cbc_cksum();
+void des_set_odd_parity();
+#else /* PROTO */
+int des_3ecb_encrypt(des_cblock *input,des_cblock *output,\
+ des_key_schedule ks1,des_key_schedule ks2,int encrypt);
+unsigned long des_cbc_cksum(des_cblock *input,des_cblock *output,\
+ long length,des_key_schedule schedule,des_cblock *ivec);
+int des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,\
+ des_key_schedule schedule,des_cblock *ivec,int encrypt);
+int des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,\
+ des_key_schedule sk1,des_key_schedule sk2,\
+ des_cblock *ivec1,des_cblock *ivec2,int encrypt);
+int des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,\
+ long length,des_key_schedule schedule,des_cblock *ivec,int encrypt);
+int des_ecb_encrypt(des_cblock *input,des_cblock *output,\
+ des_key_schedule ks,int encrypt);
+int des_encrypt(unsigned long *input,unsigned long *output,
+ des_key_schedule ks, int encrypt);
+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,\
+ des_cblock *iv);
+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,\
+ des_cblock *iv);
+char *crypt(char *buf,char *salt);
+int des_ofb_encrypt(unsigned char *in,unsigned char *out,\
+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
+int des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,\
+ des_key_schedule schedule,des_cblock *ivec,int encrypt);
+unsigned long des_quad_cksum(des_cblock *input,des_cblock *output,\
+ long length,int out_count,des_cblock *seed);
+int des_random_key(des_cblock ret);
+int des_read_password(des_cblock *key,char *prompt,int verify);
+int des_read_2passwords(des_cblock *key1,des_cblock *key2, \
+ char *prompt,int verify);
+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
+void des_set_odd_parity(des_cblock *key);
+int des_is_weak_key(des_cblock *key);
+int des_set__key(des_cblock *key,des_key_schedule schedule);
+int des_key_sched(des_cblock *key,des_key_schedule schedule);
+int des_string_to_key(char *str,des_cblock *key);
+int des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
+#endif
+#endif
diff --git a/eBones/des/include/des_locl.h b/eBones/des/include/des_locl.h
new file mode 100644
index 0000000..b35f33c
--- /dev/null
+++ b/eBones/des/include/des_locl.h
@@ -0,0 +1,186 @@
+/* des_locl.h */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: des_locl.h,v 1.2 1994/07/19 19:22:18 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include "des.h"
+
+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
+#include <string.h>
+#define bcopy(b1,b2,len) memcpy(b2, b1, (size_t)(len))
+#define bzero(b,len) memset(b, 0, (size_t)(len))
+#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len))
+#define index(s1,char) strchr(s1,char)
+#endif
+
+#ifdef MSDOS
+#define getpid() 2
+#define RAND
+extern int errno;
+#define PROTO
+#endif
+
+#ifdef __STDC__
+#define PROTO
+#endif
+
+#ifdef RAND
+#define random() rand()
+#define srandom(s) srand(s)
+#endif
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE (1024*16)
+#define BSIZE (MAXWRITE+4)
+
+#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
+ l|=((unsigned long)(*((c)++)))<< 8, \
+ l|=((unsigned long)(*((c)++)))<<16, \
+ l|=((unsigned long)(*((c)++)))<<24)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2|=((unsigned long)(*(--(c))))<<24; \
+ case 7: l2|=((unsigned long)(*(--(c))))<<16; \
+ case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
+ case 5: l2|=((unsigned long)(*(--(c)))); \
+ case 4: l1|=((unsigned long)(*(--(c))))<<24; \
+ case 3: l1|=((unsigned long)(*(--(c))))<<16; \
+ case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
+ case 1: l1|=((unsigned long)(*(--(c)))); \
+ } \
+ }
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \
+ l|=((unsigned long)(*((c)++)))<<16, \
+ l|=((unsigned long)(*((c)++)))<< 8, \
+ l|=((unsigned long)(*((c)++))))
+
+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n) { \
+ c+=n; \
+ switch (n) { \
+ case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+ case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+ case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
+ case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+ case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+ case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
+ } \
+ }
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture. gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs. */
+#ifdef ALT_ECB
+#define D_ENCRYPT(L,R,S) \
+ u=((R^s[S ])<<2); \
+ t= R^s[S+1]; \
+ t=((t>>2)+(t<<30)); \
+ L^= \
+ *(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
+ *(unsigned long *)(des_SP+ ((u )&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
+ *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
+#else /* original version */
+#ifdef MSDOS
+#define D_ENCRYPT(L,R,S) \
+ U.l=R^s[S+1]; \
+ T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \
+ T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \
+ U.l=(R^s[S ])&0x3f3f3f3f; \
+ L^= des_SPtrans[1][(T.c[0])]| \
+ des_SPtrans[3][(T.c[1])]| \
+ des_SPtrans[5][(T.c[2])]| \
+ des_SPtrans[7][(T.c[3])]| \
+ des_SPtrans[0][(U.c[0])]| \
+ des_SPtrans[2][(U.c[1])]| \
+ des_SPtrans[4][(U.c[2])]| \
+ des_SPtrans[6][(U.c[3])];
+#else
+#define D_ENCRYPT(L,R,S) \
+ u=(R^s[S ]); \
+ t=R^s[S+1]; \
+ t=((t>>4)+(t<<28)); \
+ L^= des_SPtrans[1][(t )&0x3f]| \
+ des_SPtrans[3][(t>> 8)&0x3f]| \
+ des_SPtrans[5][(t>>16)&0x3f]| \
+ des_SPtrans[7][(t>>24)&0x3f]| \
+ des_SPtrans[0][(u )&0x3f]| \
+ des_SPtrans[2][(u>> 8)&0x3f]| \
+ des_SPtrans[4][(u>>16)&0x3f]| \
+ des_SPtrans[6][(u>>24)&0x3f];
+#endif
+#endif
+
+ /* IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+
+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+
+ The output has been subject to swaps of the form
+ 0 1 -> 3 1 but the odd and even bits have been put into
+ 2 3 2 0
+ different words. The main trick is to remember that
+ t=((l>>size)^r)&(mask);
+ r^=t;
+ l^=(t<<size);
+ can be used to swap and move bits between words.
+
+ So l = 0 1 2 3 r = 16 17 18 19
+ 4 5 6 7 20 21 22 23
+ 8 9 10 11 24 25 26 27
+ 12 13 14 15 28 29 30 31
+ becomes (for size == 2 and mask == 0x3333)
+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+
+ Thanks for hints from Richard Outerbridge - he told me IP&FP
+ could be done in 15 xor, 10 shifts and 5 ands.
+ When I finally started to think of the problem in 2D
+ I first got ~42 operations without xors. When I remembered
+ how to use xors :-) I got it to its final state.
+ */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
diff --git a/eBones/des/include/podd.h b/eBones/des/include/podd.h
new file mode 100644
index 0000000..52b89d3
--- /dev/null
+++ b/eBones/des/include/podd.h
@@ -0,0 +1,24 @@
+/* podd.h */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: podd.h,v 1.2 1994/07/19 19:22:20 g89r4222 Exp $
+ */
+
+static unsigned char odd_parity[256]={
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
diff --git a/eBones/des/include/sk.h b/eBones/des/include/sk.h
new file mode 100644
index 0000000..5aaf7d8
--- /dev/null
+++ b/eBones/des/include/sk.h
@@ -0,0 +1,145 @@
+/* sk.h */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: sk.h,v 1.2 1994/07/19 19:22:22 g89r4222 Exp $
+ */
+
+static unsigned long des_skb[8][64]={
+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x00000010,0x20000000,0x20000010,
+0x00010000,0x00010010,0x20010000,0x20010010,
+0x00000800,0x00000810,0x20000800,0x20000810,
+0x00010800,0x00010810,0x20010800,0x20010810,
+0x00000020,0x00000030,0x20000020,0x20000030,
+0x00010020,0x00010030,0x20010020,0x20010030,
+0x00000820,0x00000830,0x20000820,0x20000830,
+0x00010820,0x00010830,0x20010820,0x20010830,
+0x00080000,0x00080010,0x20080000,0x20080010,
+0x00090000,0x00090010,0x20090000,0x20090010,
+0x00080800,0x00080810,0x20080800,0x20080810,
+0x00090800,0x00090810,0x20090800,0x20090810,
+0x00080020,0x00080030,0x20080020,0x20080030,
+0x00090020,0x00090030,0x20090020,0x20090030,
+0x00080820,0x00080830,0x20080820,0x20080830,
+0x00090820,0x00090830,0x20090820,0x20090830,
+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+0x00000000,0x02000000,0x00002000,0x02002000,
+0x00200000,0x02200000,0x00202000,0x02202000,
+0x00000004,0x02000004,0x00002004,0x02002004,
+0x00200004,0x02200004,0x00202004,0x02202004,
+0x00000400,0x02000400,0x00002400,0x02002400,
+0x00200400,0x02200400,0x00202400,0x02202400,
+0x00000404,0x02000404,0x00002404,0x02002404,
+0x00200404,0x02200404,0x00202404,0x02202404,
+0x10000000,0x12000000,0x10002000,0x12002000,
+0x10200000,0x12200000,0x10202000,0x12202000,
+0x10000004,0x12000004,0x10002004,0x12002004,
+0x10200004,0x12200004,0x10202004,0x12202004,
+0x10000400,0x12000400,0x10002400,0x12002400,
+0x10200400,0x12200400,0x10202400,0x12202400,
+0x10000404,0x12000404,0x10002404,0x12002404,
+0x10200404,0x12200404,0x10202404,0x12202404,
+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+0x00000000,0x00000001,0x00040000,0x00040001,
+0x01000000,0x01000001,0x01040000,0x01040001,
+0x00000002,0x00000003,0x00040002,0x00040003,
+0x01000002,0x01000003,0x01040002,0x01040003,
+0x00000200,0x00000201,0x00040200,0x00040201,
+0x01000200,0x01000201,0x01040200,0x01040201,
+0x00000202,0x00000203,0x00040202,0x00040203,
+0x01000202,0x01000203,0x01040202,0x01040203,
+0x08000000,0x08000001,0x08040000,0x08040001,
+0x09000000,0x09000001,0x09040000,0x09040001,
+0x08000002,0x08000003,0x08040002,0x08040003,
+0x09000002,0x09000003,0x09040002,0x09040003,
+0x08000200,0x08000201,0x08040200,0x08040201,
+0x09000200,0x09000201,0x09040200,0x09040201,
+0x08000202,0x08000203,0x08040202,0x08040203,
+0x09000202,0x09000203,0x09040202,0x09040203,
+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+0x00000000,0x00100000,0x00000100,0x00100100,
+0x00000008,0x00100008,0x00000108,0x00100108,
+0x00001000,0x00101000,0x00001100,0x00101100,
+0x00001008,0x00101008,0x00001108,0x00101108,
+0x04000000,0x04100000,0x04000100,0x04100100,
+0x04000008,0x04100008,0x04000108,0x04100108,
+0x04001000,0x04101000,0x04001100,0x04101100,
+0x04001008,0x04101008,0x04001108,0x04101108,
+0x00020000,0x00120000,0x00020100,0x00120100,
+0x00020008,0x00120008,0x00020108,0x00120108,
+0x00021000,0x00121000,0x00021100,0x00121100,
+0x00021008,0x00121008,0x00021108,0x00121108,
+0x04020000,0x04120000,0x04020100,0x04120100,
+0x04020008,0x04120008,0x04020108,0x04120108,
+0x04021000,0x04121000,0x04021100,0x04121100,
+0x04021008,0x04121008,0x04021108,0x04121108,
+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000,0x10000000,0x00010000,0x10010000,
+0x00000004,0x10000004,0x00010004,0x10010004,
+0x20000000,0x30000000,0x20010000,0x30010000,
+0x20000004,0x30000004,0x20010004,0x30010004,
+0x00100000,0x10100000,0x00110000,0x10110000,
+0x00100004,0x10100004,0x00110004,0x10110004,
+0x20100000,0x30100000,0x20110000,0x30110000,
+0x20100004,0x30100004,0x20110004,0x30110004,
+0x00001000,0x10001000,0x00011000,0x10011000,
+0x00001004,0x10001004,0x00011004,0x10011004,
+0x20001000,0x30001000,0x20011000,0x30011000,
+0x20001004,0x30001004,0x20011004,0x30011004,
+0x00101000,0x10101000,0x00111000,0x10111000,
+0x00101004,0x10101004,0x00111004,0x10111004,
+0x20101000,0x30101000,0x20111000,0x30111000,
+0x20101004,0x30101004,0x20111004,0x30111004,
+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+0x00000000,0x08000000,0x00000008,0x08000008,
+0x00000400,0x08000400,0x00000408,0x08000408,
+0x00020000,0x08020000,0x00020008,0x08020008,
+0x00020400,0x08020400,0x00020408,0x08020408,
+0x00000001,0x08000001,0x00000009,0x08000009,
+0x00000401,0x08000401,0x00000409,0x08000409,
+0x00020001,0x08020001,0x00020009,0x08020009,
+0x00020401,0x08020401,0x00020409,0x08020409,
+0x02000000,0x0A000000,0x02000008,0x0A000008,
+0x02000400,0x0A000400,0x02000408,0x0A000408,
+0x02020000,0x0A020000,0x02020008,0x0A020008,
+0x02020400,0x0A020400,0x02020408,0x0A020408,
+0x02000001,0x0A000001,0x02000009,0x0A000009,
+0x02000401,0x0A000401,0x02000409,0x0A000409,
+0x02020001,0x0A020001,0x02020009,0x0A020009,
+0x02020401,0x0A020401,0x02020409,0x0A020409,
+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+0x00000000,0x00000100,0x00080000,0x00080100,
+0x01000000,0x01000100,0x01080000,0x01080100,
+0x00000010,0x00000110,0x00080010,0x00080110,
+0x01000010,0x01000110,0x01080010,0x01080110,
+0x00200000,0x00200100,0x00280000,0x00280100,
+0x01200000,0x01200100,0x01280000,0x01280100,
+0x00200010,0x00200110,0x00280010,0x00280110,
+0x01200010,0x01200110,0x01280010,0x01280110,
+0x00000200,0x00000300,0x00080200,0x00080300,
+0x01000200,0x01000300,0x01080200,0x01080300,
+0x00000210,0x00000310,0x00080210,0x00080310,
+0x01000210,0x01000310,0x01080210,0x01080310,
+0x00200200,0x00200300,0x00280200,0x00280300,
+0x01200200,0x01200300,0x01280200,0x01280300,
+0x00200210,0x00200310,0x00280210,0x00280310,
+0x01200210,0x01200310,0x01280210,0x01280310,
+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+0x00000000,0x04000000,0x00040000,0x04040000,
+0x00000002,0x04000002,0x00040002,0x04040002,
+0x00002000,0x04002000,0x00042000,0x04042000,
+0x00002002,0x04002002,0x00042002,0x04042002,
+0x00000020,0x04000020,0x00040020,0x04040020,
+0x00000022,0x04000022,0x00040022,0x04040022,
+0x00002020,0x04002020,0x00042020,0x04042020,
+0x00002022,0x04002022,0x00042022,0x04042022,
+0x00000800,0x04000800,0x00040800,0x04040800,
+0x00000802,0x04000802,0x00040802,0x04040802,
+0x00002800,0x04002800,0x00042800,0x04042800,
+0x00002802,0x04002802,0x00042802,0x04042802,
+0x00000820,0x04000820,0x00040820,0x04040820,
+0x00000822,0x04000822,0x00040822,0x04040822,
+0x00002820,0x04002820,0x00042820,0x04042820,
+0x00002822,0x04002822,0x00042822,0x04042822,
+};
diff --git a/eBones/des/include/spr.h b/eBones/des/include/spr.h
new file mode 100644
index 0000000..dbe2ae1
--- /dev/null
+++ b/eBones/des/include/spr.h
@@ -0,0 +1,151 @@
+/* spr.h */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: spr.h,v 1.2 1994/07/19 19:22:23 g89r4222 Exp $
+ */
+
+static unsigned long des_SPtrans[8][64]={
+/* nibble 0 */
+0x00820200, 0x00020000, 0x80800000, 0x80820200,
+0x00800000, 0x80020200, 0x80020000, 0x80800000,
+0x80020200, 0x00820200, 0x00820000, 0x80000200,
+0x80800200, 0x00800000, 0x00000000, 0x80020000,
+0x00020000, 0x80000000, 0x00800200, 0x00020200,
+0x80820200, 0x00820000, 0x80000200, 0x00800200,
+0x80000000, 0x00000200, 0x00020200, 0x80820000,
+0x00000200, 0x80800200, 0x80820000, 0x00000000,
+0x00000000, 0x80820200, 0x00800200, 0x80020000,
+0x00820200, 0x00020000, 0x80000200, 0x00800200,
+0x80820000, 0x00000200, 0x00020200, 0x80800000,
+0x80020200, 0x80000000, 0x80800000, 0x00820000,
+0x80820200, 0x00020200, 0x00820000, 0x80800200,
+0x00800000, 0x80000200, 0x80020000, 0x00000000,
+0x00020000, 0x00800000, 0x80800200, 0x00820200,
+0x80000000, 0x80820000, 0x00000200, 0x80020200,
+
+/* nibble 1 */
+0x10042004, 0x00000000, 0x00042000, 0x10040000,
+0x10000004, 0x00002004, 0x10002000, 0x00042000,
+0x00002000, 0x10040004, 0x00000004, 0x10002000,
+0x00040004, 0x10042000, 0x10040000, 0x00000004,
+0x00040000, 0x10002004, 0x10040004, 0x00002000,
+0x00042004, 0x10000000, 0x00000000, 0x00040004,
+0x10002004, 0x00042004, 0x10042000, 0x10000004,
+0x10000000, 0x00040000, 0x00002004, 0x10042004,
+0x00040004, 0x10042000, 0x10002000, 0x00042004,
+0x10042004, 0x00040004, 0x10000004, 0x00000000,
+0x10000000, 0x00002004, 0x00040000, 0x10040004,
+0x00002000, 0x10000000, 0x00042004, 0x10002004,
+0x10042000, 0x00002000, 0x00000000, 0x10000004,
+0x00000004, 0x10042004, 0x00042000, 0x10040000,
+0x10040004, 0x00040000, 0x00002004, 0x10002000,
+0x10002004, 0x00000004, 0x10040000, 0x00042000,
+
+/* nibble 2 */
+0x41000000, 0x01010040, 0x00000040, 0x41000040,
+0x40010000, 0x01000000, 0x41000040, 0x00010040,
+0x01000040, 0x00010000, 0x01010000, 0x40000000,
+0x41010040, 0x40000040, 0x40000000, 0x41010000,
+0x00000000, 0x40010000, 0x01010040, 0x00000040,
+0x40000040, 0x41010040, 0x00010000, 0x41000000,
+0x41010000, 0x01000040, 0x40010040, 0x01010000,
+0x00010040, 0x00000000, 0x01000000, 0x40010040,
+0x01010040, 0x00000040, 0x40000000, 0x00010000,
+0x40000040, 0x40010000, 0x01010000, 0x41000040,
+0x00000000, 0x01010040, 0x00010040, 0x41010000,
+0x40010000, 0x01000000, 0x41010040, 0x40000000,
+0x40010040, 0x41000000, 0x01000000, 0x41010040,
+0x00010000, 0x01000040, 0x41000040, 0x00010040,
+0x01000040, 0x00000000, 0x41010000, 0x40000040,
+0x41000000, 0x40010040, 0x00000040, 0x01010000,
+
+/* nibble 3 */
+0x00100402, 0x04000400, 0x00000002, 0x04100402,
+0x00000000, 0x04100000, 0x04000402, 0x00100002,
+0x04100400, 0x04000002, 0x04000000, 0x00000402,
+0x04000002, 0x00100402, 0x00100000, 0x04000000,
+0x04100002, 0x00100400, 0x00000400, 0x00000002,
+0x00100400, 0x04000402, 0x04100000, 0x00000400,
+0x00000402, 0x00000000, 0x00100002, 0x04100400,
+0x04000400, 0x04100002, 0x04100402, 0x00100000,
+0x04100002, 0x00000402, 0x00100000, 0x04000002,
+0x00100400, 0x04000400, 0x00000002, 0x04100000,
+0x04000402, 0x00000000, 0x00000400, 0x00100002,
+0x00000000, 0x04100002, 0x04100400, 0x00000400,
+0x04000000, 0x04100402, 0x00100402, 0x00100000,
+0x04100402, 0x00000002, 0x04000400, 0x00100402,
+0x00100002, 0x00100400, 0x04100000, 0x04000402,
+0x00000402, 0x04000000, 0x04000002, 0x04100400,
+
+/* nibble 4 */
+0x02000000, 0x00004000, 0x00000100, 0x02004108,
+0x02004008, 0x02000100, 0x00004108, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x00004100,
+0x02000108, 0x02004008, 0x02004100, 0x00000000,
+0x00004100, 0x02000000, 0x00004008, 0x00000108,
+0x02000100, 0x00004108, 0x00000000, 0x02000008,
+0x00000008, 0x02000108, 0x02004108, 0x00004008,
+0x02004000, 0x00000100, 0x00000108, 0x02004100,
+0x02004100, 0x02000108, 0x00004008, 0x02004000,
+0x00004000, 0x00000008, 0x02000008, 0x02000100,
+0x02000000, 0x00004100, 0x02004108, 0x00000000,
+0x00004108, 0x02000000, 0x00000100, 0x00004008,
+0x02000108, 0x00000100, 0x00000000, 0x02004108,
+0x02004008, 0x02004100, 0x00000108, 0x00004000,
+0x00004100, 0x02004008, 0x02000100, 0x00000108,
+0x00000008, 0x00004108, 0x02004000, 0x02000008,
+
+/* nibble 5 */
+0x20000010, 0x00080010, 0x00000000, 0x20080800,
+0x00080010, 0x00000800, 0x20000810, 0x00080000,
+0x00000810, 0x20080810, 0x00080800, 0x20000000,
+0x20000800, 0x20000010, 0x20080000, 0x00080810,
+0x00080000, 0x20000810, 0x20080010, 0x00000000,
+0x00000800, 0x00000010, 0x20080800, 0x20080010,
+0x20080810, 0x20080000, 0x20000000, 0x00000810,
+0x00000010, 0x00080800, 0x00080810, 0x20000800,
+0x00000810, 0x20000000, 0x20000800, 0x00080810,
+0x20080800, 0x00080010, 0x00000000, 0x20000800,
+0x20000000, 0x00000800, 0x20080010, 0x00080000,
+0x00080010, 0x20080810, 0x00080800, 0x00000010,
+0x20080810, 0x00080800, 0x00080000, 0x20000810,
+0x20000010, 0x20080000, 0x00080810, 0x00000000,
+0x00000800, 0x20000010, 0x20000810, 0x20080800,
+0x20080000, 0x00000810, 0x00000010, 0x20080010,
+
+/* nibble 6 */
+0x00001000, 0x00000080, 0x00400080, 0x00400001,
+0x00401081, 0x00001001, 0x00001080, 0x00000000,
+0x00400000, 0x00400081, 0x00000081, 0x00401000,
+0x00000001, 0x00401080, 0x00401000, 0x00000081,
+0x00400081, 0x00001000, 0x00001001, 0x00401081,
+0x00000000, 0x00400080, 0x00400001, 0x00001080,
+0x00401001, 0x00001081, 0x00401080, 0x00000001,
+0x00001081, 0x00401001, 0x00000080, 0x00400000,
+0x00001081, 0x00401000, 0x00401001, 0x00000081,
+0x00001000, 0x00000080, 0x00400000, 0x00401001,
+0x00400081, 0x00001081, 0x00001080, 0x00000000,
+0x00000080, 0x00400001, 0x00000001, 0x00400080,
+0x00000000, 0x00400081, 0x00400080, 0x00001080,
+0x00000081, 0x00001000, 0x00401081, 0x00400000,
+0x00401080, 0x00000001, 0x00001001, 0x00401081,
+0x00400001, 0x00401080, 0x00401000, 0x00001001,
+
+/* nibble 7 */
+0x08200020, 0x08208000, 0x00008020, 0x00000000,
+0x08008000, 0x00200020, 0x08200000, 0x08208020,
+0x00000020, 0x08000000, 0x00208000, 0x00008020,
+0x00208020, 0x08008020, 0x08000020, 0x08200000,
+0x00008000, 0x00208020, 0x00200020, 0x08008000,
+0x08208020, 0x08000020, 0x00000000, 0x00208000,
+0x08000000, 0x00200000, 0x08008020, 0x08200020,
+0x00200000, 0x00008000, 0x08208000, 0x00000020,
+0x00200000, 0x00008000, 0x08000020, 0x08208020,
+0x00008020, 0x08000000, 0x00000000, 0x00208000,
+0x08200020, 0x08008020, 0x08008000, 0x00200020,
+0x08208000, 0x00000020, 0x00200020, 0x08008000,
+0x08208020, 0x00200000, 0x08200000, 0x08000020,
+0x00208000, 0x00008020, 0x08008020, 0x08200000,
+0x00000020, 0x08208000, 0x00208020, 0x00000000,
+0x08000000, 0x08200020, 0x00008000, 0x00208020};
diff --git a/eBones/des/ofb_enc.c b/eBones/des/ofb_enc.c
new file mode 100644
index 0000000..9a94372
--- /dev/null
+++ b/eBones/des/ofb_enc.c
@@ -0,0 +1,72 @@
+/* ofb_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: ofb_enc.c,v 1.2 1994/07/19 19:21:59 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second. The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+int des_ofb_encrypt(in,out,numbits,length,schedule,ivec)
+unsigned char *in,*out;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+ {
+ register unsigned long d0,d1,v0,v1,n=(numbits+7)/8;
+ register unsigned long mask0,mask1;
+ register long l=length;
+ register int num=numbits;
+ unsigned long ti[2];
+ unsigned char *iv;
+
+ if (num > 64) return(0);
+ if (num > 32)
+ {
+ mask0=0xffffffff;
+ if (num >= 64)
+ mask1=mask0;
+ else
+ mask1=(1L<<(num-32))-1;
+ }
+ else
+ {
+ if (num == 32)
+ mask0=0xffffffff;
+ else
+ mask0=(1L<<num)-1;
+ mask1=0x00000000;
+ }
+
+ iv=(unsigned char *)ivec;
+ c2l(iv,v0);
+ c2l(iv,v1);
+ ti[0]=v0;
+ ti[1]=v1;
+ while (l-- > 0)
+ {
+ des_encrypt((unsigned long *)ti,(unsigned long *)ti,
+ schedule,DES_ENCRYPT);
+ c2ln(in,d0,d1,n);
+ in+=n;
+ d0=(d0^ti[0])&mask0;
+ d1=(d1^ti[1])&mask1;
+ l2cn(d0,d1,out,n);
+ out+=n;
+ }
+ v0=ti[0];
+ v1=ti[1];
+ iv=(unsigned char *)ivec;
+ l2c(v0,iv);
+ l2c(v1,iv);
+ v0=v1=d0=d1=ti[0]=ti[1]=0;
+ return(0);
+ }
+
diff --git a/eBones/des/pcbc_enc.c b/eBones/des/pcbc_enc.c
new file mode 100644
index 0000000..216bdb2
--- /dev/null
+++ b/eBones/des/pcbc_enc.c
@@ -0,0 +1,78 @@
+/* pcbc_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: pcbc_enc.c,v 1.2 1994/07/19 19:22:01 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+register long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+ {
+ register unsigned long sin0,sin1,xor0,xor1,tout0,tout1;
+ unsigned long tin[2],tout[2];
+ unsigned char *in,*out,*iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (encrypt)
+ {
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (; length>0; length-=8)
+ {
+ if (length >= 8)
+ {
+ c2l(in,sin0);
+ c2l(in,sin1);
+ }
+ else
+ c2ln(in,sin0,sin1,length);
+ tin[0]=sin0^xor0;
+ tin[1]=sin1^xor1;
+ des_encrypt((unsigned long *)tin,(unsigned long *)tout,
+ schedule,encrypt);
+ tout0=tout[0];
+ tout1=tout[1];
+ xor0=sin0^tout[0];
+ xor1=sin1^tout[1];
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ }
+ else
+ {
+ c2l(iv,xor0); c2l(iv,xor1);
+ for (; length>0; length-=8)
+ {
+ c2l(in,sin0);
+ c2l(in,sin1);
+ tin[0]=sin0;
+ tin[1]=sin1;
+ des_encrypt((unsigned long *)tin,(unsigned long *)tout,
+ schedule,encrypt);
+ tout0=tout[0]^xor0;
+ tout1=tout[1]^xor1;
+ if (length >= 8)
+ {
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ else
+ l2cn(tout0,tout1,out,length);
+ xor0=tout0^sin0;
+ xor1=tout1^sin1;
+ }
+ }
+ tin[0]=tin[1]=tout[0]=tout[1]=0;
+ sin0=sin1=xor0=xor1=tout0=tout1=0;
+ return(0);
+ }
diff --git a/eBones/des/qud_cksm.c b/eBones/des/qud_cksm.c
new file mode 100644
index 0000000..eb7773f
--- /dev/null
+++ b/eBones/des/qud_cksm.c
@@ -0,0 +1,93 @@
+/* qud_cksm.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: qud_cksm.c,v 1.2 1994/07/19 19:22:02 g89r4222 Exp $
+ */
+
+/* From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer
+ * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40
+ * This module in only based on the code in this paper and is
+ * almost definitely not the same as the MIT implementation.
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define B0(a) (((unsigned long)(a)))
+#define B1(a) (((unsigned long)(a))<<8)
+#define B2(a) (((unsigned long)(a))<<16)
+#define B3(a) (((unsigned long)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE ((unsigned long)83653421)
+
+unsigned long des_quad_cksum(input,output,length,out_count,seed)
+des_cblock *input;
+des_cblock *output;
+long length;
+int out_count;
+des_cblock *seed;
+ {
+ unsigned long z0,z1,t0,t1;
+ int i;
+ long l=0;
+ unsigned char *cp;
+ unsigned char *lp;
+
+ if (out_count < 1) out_count=1;
+ lp=(unsigned char *)output;
+
+ z0=B0((*seed)[0])|B1((*seed)[1])|B2((*seed)[2])|B3((*seed)[3]);
+ z1=B0((*seed)[4])|B1((*seed)[5])|B2((*seed)[6])|B3((*seed)[7]);
+
+ for (i=0; ((i<4)&&(i<out_count)); i++)
+ {
+ cp=(unsigned char *)input;
+ l=length;
+ while (l > 0)
+ {
+ if (l > 1)
+ {
+ t0= (unsigned long)(*(cp++));
+ t0|=(unsigned long)B1(*(cp++));
+ l--;
+ }
+ else
+ t0= (unsigned long)(*(cp++));
+ l--;
+ /* add */
+ t0+=z0;
+ t0&=0xffffffff;
+ t1=z1;
+ /* square, well sort of square */
+ z0=((((t0*t0)&0xffffffff)+((t1*t1)&0xffffffff))
+ &0xffffffff)%0x7fffffff;
+ z1=((t0*((t1+NOISE)&0xffffffff))&0xffffffff)%0x7fffffff;
+ }
+ if (lp != NULL)
+ {
+ /* I believe I finally have things worked out.
+ * The MIT library assumes that the checksum
+ * is one huge number and it is returned in a
+ * host dependant byte order.
+ */
+ static unsigned long l=1;
+ static unsigned char *c=(unsigned char *)&l;
+
+ if (c[0])
+ {
+ l2c(z0,lp);
+ l2c(z1,lp);
+ }
+ else
+ {
+ lp=output[out_count-i-1];
+ l2n(z1,lp);
+ l2n(z0,lp);
+ }
+ }
+ }
+ return(z0);
+ }
+
diff --git a/eBones/des/rand_key.c b/eBones/des/rand_key.c
new file mode 100644
index 0000000..d8d2345
--- /dev/null
+++ b/eBones/des/rand_key.c
@@ -0,0 +1,45 @@
+/* rand_key.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: rand_key.c,v 1.2 1994/07/19 19:22:04 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+int des_random_key(ret)
+des_cblock ret;
+ {
+ des_key_schedule ks;
+ static unsigned long c=0;
+ static unsigned short pid=0;
+ static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+ des_cblock key;
+ unsigned char *p;
+ unsigned long t;
+
+#ifdef MSDOS
+ pid=1;
+#else
+ if (!pid) pid=getpid();
+#endif
+ p=key;
+ t=(unsigned long)time(NULL);
+ l2c(t,p);
+ t=(unsigned long)((pid)|((c++)<<16));
+ l2c(t,p);
+
+ des_set_odd_parity((des_cblock *)data);
+ des_set__key((des_cblock *)data,ks);
+ des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(key),ks,(des_cblock *)data);
+ des_set_odd_parity((des_cblock *)key);
+ des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(key),ks,(des_cblock *)data);
+
+ bcopy(key,ret,sizeof(key));
+ bzero(key,sizeof(key));
+ bzero(ks,sizeof(ks));
+ t=0;
+ return(0);
+ }
diff --git a/eBones/des/read_pwd.c b/eBones/des/read_pwd.c
new file mode 100644
index 0000000..8375f64
--- /dev/null
+++ b/eBones/des/read_pwd.c
@@ -0,0 +1,333 @@
+/* read_pwd.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+/* 06-Apr-92 Luke Brennan Support for VMS */
+
+/*-
+ * $Id: read_pwd.c,v 1.2 1994/07/19 19:22:05 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+
+#include <sys/param.h>
+
+#ifdef BSD
+#include <pwd.h>
+extern char * getpass(const char * prompt);
+#endif
+
+#ifndef VMS
+#ifndef MSDOS
+#ifndef _IRIX
+#ifdef CRAY
+#include <termio.h>
+#define sgttyb termio
+#define sg_flags c_lflag
+#else /* !CRAY */
+#include <sgtty.h>
+#endif
+#include <sys/ioctl.h>
+#else /* _IRIX */
+struct sgttyb {
+ char sg_ispeed; /* input speed */
+ char sg_ospeed; /* output speed */
+ char sg_erase; /* erase character */
+ char sg_kill; /* kill character */
+ short sg_flags; /* mode flags */
+ };
+#endif
+#else /* MSDOS */
+#define fgets(a,b,c) noecho_fgets(a,b,c)
+#ifndef NSIG
+#define NSIG 32
+#endif
+#endif
+#else /* VMS */
+#include <ssdef.h>
+#include <iodef.h>
+#include <ttdef.h>
+#include <descrip.h>
+struct IOSB {
+ short iosb$w_value;
+ short iosb$w_count;
+ long iosb$l_info;
+ };
+#endif
+
+static void read_till_nl();
+static int read_pw();
+static void recsig();
+static void pushsig();
+static void popsig();
+#ifdef MSDOS
+static int noecho_fgets();
+#endif
+
+static void (*savsig[NSIG])();
+static jmp_buf save;
+
+int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+ {
+ int ok;
+ char buf[BUFSIZ],buff[BUFSIZ];
+
+ if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+ des_string_to_key(buf,key);
+ bzero(buf,BUFSIZ);
+ bzero(buff,BUFSIZ);
+ return(ok);
+ }
+
+int des_read_2passwords(key1,key2,prompt,verify)
+des_cblock *key1;
+des_cblock *key2;
+char *prompt;
+int verify;
+ {
+ int ok;
+ char buf[BUFSIZ],buff[BUFSIZ];
+
+ if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+ des_string_to_2keys(buf,key1,key2);
+ bzero(buf,BUFSIZ);
+ bzero(buff,BUFSIZ);
+ return(ok);
+ }
+
+#if defined(BSD)
+int des_read_pw_string(buf, length, prompt, verify)
+ char *buf;
+ int length;
+ char * prompt;
+ int verify;
+{
+ int len = MIN(_PASSWORD_LEN, length);
+ char * s;
+ int ok = 0;
+
+ fflush(stdout);
+ while (!ok) {
+ s = getpass(prompt);
+ strncpy(buf, s, len);
+ if(verify) {
+ printf("\nVerifying password"); fflush(stdout);
+ if(strncmp(getpass(prompt), buf, len) != 0) {
+ printf("\nVerify failure - try again\n");
+ fflush(stdout);
+ continue;
+ }
+ }
+ ok = 1;
+ buf[len-1] = '\0';
+ }
+ return (!ok);
+}
+
+#else /* BSD */
+
+int des_read_pw_string(buf,length,prompt,verify)
+char *buf;
+int length;
+char *prompt;
+int verify;
+ {
+ char buff[BUFSIZ];
+ int ret;
+
+ ret=read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
+ bzero(buff,BUFSIZ);
+ return(ret);
+ }
+#endif
+
+static void read_till_nl(in)
+FILE *in;
+ {
+#define SIZE 4
+ char buf[SIZE+1];
+
+ do {
+ fgets(buf,SIZE,in);
+ } while (index(buf,'\n') == NULL);
+ }
+
+/* return 0 if ok, 1 (or -1) otherwise */
+static int read_pw(buf,buff,size,prompt,verify)
+char *buf,*buff;
+int size;
+char *prompt;
+int verify;
+ {
+#ifndef VMS
+#ifndef MSDOS
+ struct sgttyb tty_orig,tty_new;
+#endif /* !MSDOS */
+#else
+ struct IOSB iosb;
+ $DESCRIPTOR(terminal,"TT");
+ long tty_orig[3], tty_new[3];
+ long status;
+ unsigned short channel = 0;
+#endif
+ int ok=0;
+ char *p;
+ int ps=0;
+ FILE *tty;
+
+#ifndef MSDOS
+ if ((tty=fopen("/dev/tty","r")) == NULL)
+ tty=stdin;
+#else /* MSDOS */
+ if ((tty=fopen("con","r")) == NULL)
+ tty=stdin;
+#endif /* MSDOS */
+#ifndef VMS
+#ifdef TIOCGETP
+ if (ioctl(fileno(tty),TIOCGETP,(char *)&tty_orig) == -1)
+ return(-1);
+ bcopy(&(tty_orig),&(tty_new),sizeof(tty_orig));
+#endif
+#else /* VMS */
+ status = SYS$ASSIGN(&terminal,&channel,0,0);
+ if (status != SS$_NORMAL)
+ return(-1);
+ status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
+ if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+ return(-1);
+#endif
+
+ if (setjmp(save))
+ {
+ ok=0;
+ goto error;
+ }
+ pushsig();
+ ps=1;
+#ifndef VMS
+#ifndef MSDOS
+ tty_new.sg_flags &= ~ECHO;
+#endif /* !MSDOS */
+#ifdef TIOCSETP
+ if (ioctl(fileno(tty),TIOCSETP,(char *)&tty_new) == -1)
+ return(-1);
+#endif
+#else /* VMS */
+ tty_new[0] = tty_orig[0];
+ tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+ tty_new[2] = tty_orig[2];
+ status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
+ if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+ return(-1);
+#endif /* VMS */
+ ps=2;
+
+ fflush(stdout);
+ fflush(stderr);
+ while (!ok)
+ {
+ fputs(prompt,stderr);
+ fflush(stderr);
+
+ buf[0]='\0';
+ fgets(buf,size,tty);
+ if (feof(tty)) goto error;
+ if ((p=(char *)index(buf,'\n')) != NULL)
+ *p='\0';
+ else read_till_nl(tty);
+ if (verify)
+ {
+ fprintf(stderr,"\nVerifying password %s",prompt);
+ fflush(stderr);
+ buff[0]='\0';
+ fgets(buff,size,tty);
+ if (feof(tty)) goto error;
+ if ((p=(char *)index(buff,'\n')) != NULL)
+ *p='\0';
+ else read_till_nl(tty);
+
+ if (strcmp(buf,buff) != 0)
+ {
+ fprintf(stderr,"\nVerify failure - try again\n");
+ fflush(stderr);
+ continue;
+ }
+ }
+ ok=1;
+ }
+
+error:
+ fprintf(stderr,"\n");
+ /* What can we do if there is an error? */
+#ifndef VMS
+#ifdef TIOCSETP
+ if (ps >= 2) ioctl(fileno(tty),TIOCSETP,(char *)&tty_orig);
+#endif
+#else /* VMS */
+ if (ps >= 2)
+ status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0
+ ,tty_orig,12,0,0,0,0);
+#endif /* VMS */
+
+ if (ps >= 1) popsig();
+ if (stdin != tty) fclose(tty);
+#ifdef VMS
+ status = SYS$DASSGN(channel);
+#endif
+ return(!ok);
+ }
+
+static void pushsig()
+ {
+ int i;
+
+ for (i=0; i<NSIG; i++)
+ savsig[i]=signal(i,recsig);
+ }
+
+static void popsig()
+ {
+ int i;
+
+ for (i=0; i<NSIG; i++)
+ signal(i,savsig[i]);
+ }
+
+static void recsig()
+ {
+ longjmp(save,1);
+ }
+
+#ifdef MSDOS
+static int noecho_fgets(buf,size,tty)
+char *buf;
+int size;
+FILE *tty;
+ {
+ int i;
+ char *p;
+
+ p=buf;
+ for (;;)
+ {
+ if (size == 0)
+ {
+ *p='\0';
+ break;
+ }
+ size--;
+ i=getch();
+ if (i == '\r') i='\n';
+ *(p++)=i;
+ if (i == '\n')
+ {
+ *p='\0';
+ break;
+ }
+ }
+ }
+#endif
diff --git a/eBones/des/set_key.c b/eBones/des/set_key.c
new file mode 100644
index 0000000..f1ca3f4
--- /dev/null
+++ b/eBones/des/set_key.c
@@ -0,0 +1,190 @@
+/* set_key.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+
+/*-
+ * $Id: set_key.c,v 1.2 1994/07/19 19:22:07 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+#include "podd.h"
+#include "sk.h"
+
+static int check_parity();
+
+int des_check_key=0;
+
+void des_set_odd_parity(key)
+des_cblock *key;
+ {
+ int i;
+
+ for (i=0; i<DES_KEY_SZ; i++)
+ (*key)[i]=odd_parity[(*key)[i]];
+ }
+
+static int check_parity(key)
+des_cblock *key;
+ {
+ int i;
+
+ for (i=0; i<DES_KEY_SZ; i++)
+ {
+ if ((*key)[i] != odd_parity[(*key)[i]])
+ return(0);
+ }
+ return(1);
+ }
+
+/* Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY 16
+static des_cblock weak_keys[NUM_WEAK_KEY]={
+ /* weak keys */
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ /* semi-weak keys */
+ 0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,
+ 0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,
+ 0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1,
+ 0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E,
+ 0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,
+ 0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01,
+ 0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE,
+ 0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,
+ 0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,
+ 0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01,
+ 0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
+ 0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1};
+
+int des_is_weak_key(key)
+des_cblock *key;
+ {
+ int i;
+
+ for (i=0; i<NUM_WEAK_KEY; i++)
+ /* Added == 0 to comparision, I obviously don't run
+ * this section very often :-(, thanks to
+ * engineering@MorningStar.Com for the fix
+ * eay 93/06/29 */
+ if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
+ return(0);
+ }
+
+/* NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros.
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ * (b)^=(t),\
+ * (a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int des_set__key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+ {
+ register unsigned long c,d,t,s;
+ register unsigned char *in;
+ register unsigned long *k;
+ register int i;
+
+ if (des_check_key)
+ {
+ if (!check_parity(key))
+ return(-1);
+
+ if (des_is_weak_key(key))
+ return(-2);
+ }
+
+ k=(unsigned long *)schedule;
+ in=(unsigned char *)key;
+
+ c2l(in,c);
+ c2l(in,d);
+
+ /* do PC1 in 60 simple operations */
+/* PERM_OP(d,c,t,4,0x0f0f0f0f);
+ HPERM_OP(c,t,-2, 0xcccc0000);
+ HPERM_OP(c,t,-1, 0xaaaa0000);
+ HPERM_OP(c,t, 8, 0x00ff0000);
+ HPERM_OP(c,t,-1, 0xaaaa0000);
+ HPERM_OP(d,t,-8, 0xff000000);
+ HPERM_OP(d,t, 8, 0x00ff0000);
+ HPERM_OP(d,t, 2, 0x33330000);
+ d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55);
+ d=(d>>8)|((c&0xf0000000)>>4);
+ c&=0x0fffffff; */
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d,c,t,4,0x0f0f0f0f);
+ HPERM_OP(c,t,-2,0xcccc0000);
+ HPERM_OP(d,t,-2,0xcccc0000);
+ PERM_OP (d,c,t,1,0x55555555);
+ PERM_OP (c,d,t,8,0x00ff00ff);
+ PERM_OP (d,c,t,1,0x55555555);
+ d= (((d&0x000000ff)<<16)| (d&0x0000ff00) |
+ ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
+ c&=0x0fffffff;
+
+ for (i=0; i<ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
+ else
+ { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
+ c&=0x0fffffff;
+ d&=0x0fffffff;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s= des_skb[0][ (c )&0x3f ]|
+ des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
+ des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
+ des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
+ ((c>>22)&0x38)];
+ t= des_skb[4][ (d )&0x3f ]|
+ des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
+ des_skb[6][ (d>>15)&0x3f ]|
+ des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
+
+ /* table contained 0213 4657 */
+ *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
+ s= ((s>>16)|(t&0xffff0000));
+
+ s=(s<<4)|(s>>28);
+ *(k++)=s&0xffffffff;
+ }
+ return(0);
+ }
+
+int des_key_sched(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+ {
+ return(des_set__key(key,schedule));
+ }
diff --git a/eBones/des/str2key.c b/eBones/des/str2key.c
new file mode 100644
index 0000000..baad3c2
--- /dev/null
+++ b/eBones/des/str2key.c
@@ -0,0 +1,121 @@
+/* str2key.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: str2key.c,v 1.2 1994/07/19 19:22:08 g89r4222 Exp $
+ */
+
+#include "des_locl.h"
+
+extern int des_check_key;
+
+int des_string_to_key(str,key)
+char *str;
+des_cblock *key;
+ {
+ des_key_schedule ks;
+ int i,length;
+ register unsigned char j;
+
+ bzero(key,8);
+ length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+ for (i=0; i<length; i++)
+ (*key)[i%8]^=(str[i]<<1);
+#else /* MIT COMPATIBLE */
+ for (i=0; i<length; i++)
+ {
+ j=str[i];
+ if ((i%16) < 8)
+ (*key)[i%8]^=(j<<1);
+ else
+ {
+ /* Reverse the bit order 05/05/92 eay */
+ j=((j<<4)&0xf0)|((j>>4)&0x0f);
+ j=((j<<2)&0xcc)|((j>>2)&0x33);
+ j=((j<<1)&0xaa)|((j>>1)&0x55);
+ (*key)[7-(i%8)]^=j;
+ }
+ }
+#endif
+ des_set_odd_parity((des_cblock *)key);
+ i=des_check_key;
+ des_check_key=0;
+ des_set__key((des_cblock *)key,ks);
+ des_check_key=i;
+ des_cbc_cksum((des_cblock *)str,(des_cblock *)key,(long)length,ks,
+ (des_cblock *)key);
+ bzero(ks,sizeof(ks));
+ des_set_odd_parity((des_cblock *)key);
+ return(0);
+ }
+
+int des_string_to_2keys(str,key1,key2)
+char *str;
+des_cblock *key1,*key2;
+ {
+ des_key_schedule ks;
+ int i,length;
+ register unsigned char j;
+
+ bzero(key1,8);
+ bzero(key2,8);
+ length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+ if (length <= 8)
+ {
+ for (i=0; i<length; i++)
+ {
+ (*key2)[i]=(*key1)[i]=(str[i]<<1);
+ }
+ }
+ else
+ {
+ for (i=0; i<length; i++)
+ {
+ if ((i/8)&1)
+ (*key2)[i%8]^=(str[i]<<1);
+ else
+ (*key1)[i%8]^=(str[i]<<1);
+ }
+ }
+#else /* MIT COMPATIBLE */
+ for (i=0; i<length; i++)
+ {
+ j=str[i];
+ if ((i%32) < 16)
+ {
+ if ((i%16) < 8)
+ (*key1)[i%8]^=(j<<1);
+ else
+ (*key2)[i%8]^=(j<<1);
+ }
+ else
+ {
+ j=((j<<4)&0xf0)|((j>>4)&0x0f);
+ j=((j<<2)&0xcc)|((j>>2)&0x33);
+ j=((j<<1)&0xaa)|((j>>1)&0x55);
+ if ((i%16) < 8)
+ (*key1)[7-(i%8)]^=j;
+ else
+ (*key2)[7-(i%8)]^=j;
+ }
+ }
+ if (length <= 8) bcopy(key1,key2,8);
+#endif
+ des_set_odd_parity((des_cblock *)key1);
+ des_set_odd_parity((des_cblock *)key2);
+ i=des_check_key;
+ des_check_key=0;
+ des_set__key((des_cblock *)key1,ks);
+ des_cbc_cksum((des_cblock *)str,(des_cblock *)key1,(long)length,ks,
+ (des_cblock *)key1);
+ des_set__key((des_cblock *)key2,ks);
+ des_cbc_cksum((des_cblock *)str,(des_cblock *)key2,(long)length,ks,
+ (des_cblock *)key2);
+ des_check_key=i;
+ bzero(ks,sizeof(ks));
+ des_set_odd_parity(key1);
+ des_set_odd_parity(key2);
+ return(0);
+ }
diff --git a/eBones/des/test/Makefile b/eBones/des/test/Makefile
new file mode 100644
index 0000000..e636a3a
--- /dev/null
+++ b/eBones/des/test/Makefile
@@ -0,0 +1,9 @@
+# from: @(#)Makefile 5.4 (Berkeley) 5/11/90
+# $Id: Makefile,v 1.2 1994/07/19 19:22:28 g89r4222 Exp $
+
+PROG= destest
+CFLAGS+= -I${.CURDIR}/../include
+DPADD= ${LIBDES}
+LDADD= -ldes
+
+.include <bsd.prog.mk>
diff --git a/eBones/des/test/destest.c b/eBones/des/test/destest.c
new file mode 100644
index 0000000..bc0552c
--- /dev/null
+++ b/eBones/des/test/destest.c
@@ -0,0 +1,365 @@
+/* destest.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+#include <stdio.h>
+#include "des_locl.h" /* for des.h and bcopy macros */
+/* tisk tisk - the test keys don't all have odd parity :-( */
+
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8]={
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
+ 0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57,
+ 0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E,
+ 0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86,
+ 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
+ 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
+ 0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE,
+ 0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6,
+ 0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE,
+ 0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16,
+ 0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F,
+ 0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46,
+ 0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E,
+ 0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76,
+ 0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07,
+ 0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F,
+ 0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7,
+ 0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF,
+ 0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6,
+ 0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E,
+ 0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42,
+ 0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA,
+ 0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72,
+ 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A,
+ 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2,
+ 0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A,
+ 0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2,
+ 0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A,
+ 0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02,
+ 0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A,
+ 0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32,
+ 0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA,
+ 0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62,
+ 0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2,
+ 0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA,
+ 0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92,
+ 0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A,
+ 0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2,
+ 0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+ 0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7,
+ 0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58,
+ 0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B,
+ 0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33,
+ 0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D,
+ 0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD,
+ 0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7,
+ 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4,
+ 0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B,
+ 0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71,
+ 0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A,
+ 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A,
+ 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95,
+ 0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B,
+ 0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09,
+ 0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A,
+ 0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F,
+ 0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88,
+ 0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77,
+ 0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A,
+ 0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56,
+ 0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56,
+ 0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56,
+ 0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC,
+ 0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A,
+ 0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41,
+ 0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93,
+ 0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00,
+ 0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06,
+ 0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7,
+ 0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51,
+ 0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE,
+ 0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D,
+ 0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2};
+
+static unsigned char cbc_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc_iv[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_data[40]="7654321 Now is the time for ";
+
+static unsigned char cbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static unsigned char pcbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cksum_ok[8]={
+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[24],cfb_buf2[24],cfb_tmp[8];
+static unsigned char cfb_plain[24]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher[24]=
+ {
+ 0xf3,0x1f,0xda,0x07,0x01,0x14,
+ 0x62,0xee,0x18,0x7f,0x43,0xd8,
+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2,
+ 0x90,0xda,0x6e,0x5b,0x9a,0x87
+ };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_plain[24]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+ {
+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+ };
+
+char *malloc();
+char *pt();
+
+main()
+ {
+ int i,j;
+ des_cblock in,out,outin;
+ des_key_schedule ks;
+ unsigned char cbc_in[40],cbc_out[40];
+ unsigned long cs;
+ unsigned char qret[4][4];
+ unsigned long lqret[4];
+ char *str;
+
+ printf("Doing ecb\n");
+ for (i=0; i<NUM_TESTS; i++)
+ {
+ if ((j=key_sched((C_Block *)(key_data[i]),ks)) != 0)
+ printf("Key error %2d:%d\n",i+1,j);
+ bcopy(plain_data[i],in,8);
+ bzero(out,8);
+ bzero(outin,8);
+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
+
+ if (bcmp(out,cipher_data[i],8) != 0)
+ {
+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+ pt(out));
+ }
+ if (bcmp(in,outin,8) != 0)
+ {
+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+ }
+ }
+
+ printf("Doing cbc\n");
+ if ((j=key_sched((C_Block *)cbc_key,ks)) != 0)
+ printf("Key error %2d:%d\n",i+1,j);
+ bzero(cbc_out,40);
+ bzero(cbc_in,40);
+ des_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT);
+ if (bcmp(cbc_out,cbc_ok,32) != 0)
+ printf("cbc_encrypt encrypt error\n");
+ des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT);
+ if (bcmp(cbc_in,cbc_data,32) != 0)
+ printf("cbc_encrypt decrypt error\n");
+
+ printf("Doing pcbc\n");
+ if ((j=key_sched((C_Block *)cbc_key,ks)) != 0)
+ printf("Key error %2d:%d\n",i+1,j);
+ bzero(cbc_out,40);
+ bzero(cbc_in,40);
+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT);
+ if (bcmp(cbc_out,pcbc_ok,32) != 0)
+ printf("pcbc_encrypt encrypt error\n");
+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT);
+ if (bcmp(cbc_in,cbc_data,32) != 0)
+ printf("pcbc_encrypt decrypt error\n");
+
+ printf("Doing cfb\n");
+ key_sched((C_Block *)cfb_key,ks);
+ bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv));
+ des_cfb_encrypt(cfb_plain,cfb_buf1,8,(long)sizeof(cfb_plain),ks,
+ (C_Block *)cfb_tmp,DES_ENCRYPT);
+ if (bcmp(cfb_cipher,cfb_buf1,sizeof(cfb_buf1)) != 0)
+ printf("cfb_encrypt encrypt error\n");
+ bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv));
+ des_cfb_encrypt(cfb_buf1,cfb_buf2,8,(long)sizeof(cfb_buf1),ks,
+ (C_Block *)cfb_tmp,DES_DECRYPT);
+ if (bcmp(cfb_plain,cfb_buf2,sizeof(cfb_buf2)) != 0)
+ printf("cfb_encrypt decrypt error\n");
+
+ bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv));
+ for (i=0; i<sizeof(cfb_plain); i++)
+ des_cfb_encrypt(&(cfb_plain[i]),&(cfb_buf1[i]),
+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
+ if (bcmp(cfb_cipher,cfb_buf1,sizeof(cfb_buf1)) != 0)
+ printf("cfb_encrypt small encrypt error\n");
+
+ bcopy(cfb_iv,cfb_tmp,sizeof(cfb_iv));
+ for (i=0; i<sizeof(cfb_plain); i++)
+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
+ if (bcmp(cfb_plain,cfb_buf2,sizeof(cfb_buf2)) != 0)
+ printf("cfb_encrypt small decrypt error\n");
+
+ printf("Doing ofb\n");
+ key_sched((C_Block *)ofb_key,ks);
+ bcopy(ofb_iv,ofb_tmp,sizeof(ofb_iv));
+ des_ofb_encrypt(ofb_plain,ofb_buf1,64,(long)sizeof(cfb_plain)/8,ks,
+ (C_Block *)ofb_tmp);
+ if (bcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ printf("ofb_encrypt encrypt error\n");
+ bcopy(ofb_iv,ofb_tmp,sizeof(ofb_iv));
+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
+ (C_Block *)ofb_tmp);
+ if (bcmp(ofb_plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ printf("ofb_encrypt decrypt error\n");
+
+ printf("Doing cbc_cksum\n");
+ des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
+ if (bcmp(cbc_out,cksum_ok,8) != 0)
+ printf("cbc_cksum error\n");
+
+ printf("Doing quad_cksum\n");
+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
+ for (i=0; i<4; i++)
+ {
+ lqret[i]=0;
+ bcopy(&(qret[i][0]),&(lqret[i]),4);
+ }
+ { /* Big-endian fix */
+ static unsigned long l=1;
+ static unsigned char *c=(unsigned char *)&l;
+ unsigned long ll;
+
+ if (!c[0])
+ {
+ ll=lqret[0]^lqret[3];
+ lqret[0]^=ll;
+ lqret[3]^=ll;
+ ll=lqret[1]^lqret[2];
+ lqret[1]^=ll;
+ lqret[2]^=ll;
+ }
+ }
+ if (cs != 0x70d7a63a)
+ printf("quad_cksum error, ret %08x should be 70d7a63a\n",cs);
+ if (lqret[0] != 0x327eba8d)
+ printf("quad_cksum error, out[0] %08x is not %08x\n",
+ lqret[0],0x327eba8d);
+ if (lqret[1] != 0x201a49cc)
+ printf("quad_cksum error, out[1] %08x is not %08x\n",
+ lqret[1],0x201a49cc);
+ if (lqret[2] != 0x70d7a63a)
+ printf("quad_cksum error, out[2] %08x is not %08x\n",
+ lqret[2],0x70d7a63a);
+ if (lqret[3] != 0x501c2c26)
+ printf("quad_cksum error, out[3] %08x is not %08x\n",
+ lqret[3],0x501c2c26);
+
+ printf("input word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_cbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,
+ DES_ENCRYPT);
+ }
+ printf("\noutput word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv,
+ DES_ENCRYPT);
+ }
+ printf("\n");
+ printf("fast crypt test ");
+ str=crypt("testing","ef");
+ if (strcmp("efGnQx2725bI2",str) != 0)
+ printf("fast crypt error, %x should be efGnQx2725bI2\n",str);
+ str=crypt("bca76;23","yA");
+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+ printf("fast crypt error, %x should be yA1Rp/1hZXIJk\n",str);
+ printf("\n");
+ exit(0);
+ }
+
+char *pt(p)
+unsigned char *p;
+ {
+ char *ret;
+ int i;
+ static char *f="0123456789ABCDEF";
+
+ ret=(char *)malloc(17);
+ for (i=0; i<8; i++)
+ {
+ ret[i*2]=f[(p[i]>>4)&0xf];
+ ret[i*2+1]=f[p[i]&0xf];
+ }
+ ret[16]='\0';
+ return(ret);
+ }
+
diff --git a/eBones/ext_srvtab/Makefile b/eBones/ext_srvtab/Makefile
new file mode 100644
index 0000000..f30bbbb
--- /dev/null
+++ b/eBones/ext_srvtab/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:22:34 g89r4222 Exp $
+
+PROG= ext_srvtab
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD+= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/ext_srvtab/ext_srvtab.8 b/eBones/ext_srvtab/ext_srvtab.8
new file mode 100644
index 0000000..af980a9
--- /dev/null
+++ b/eBones/ext_srvtab/ext_srvtab.8
@@ -0,0 +1,63 @@
+.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $
+.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ext_srvtab \- extract service key files from Kerberos key distribution center database
+.SH SYNOPSIS
+ext_srvtab [
+.B \-n
+] [
+.B \-r realm
+] [
+.B hostname ...
+]
+.SH DESCRIPTION
+.I ext_srvtab
+extracts service key files from the Kerberos key distribution center
+(KDC) database.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database. If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+For each
+.I hostname
+specified on the command line,
+.I ext_srvtab
+creates the service key file
+.IR hostname -new-srvtab,
+containing all the entries in the database with an instance field of
+.I hostname.
+This new file contains all the keys registered for Kerberos-mediated
+service providing programs which use the
+.IR krb_get_phost (3)
+principal and instance conventions to run on the host
+.IR hostname .
+If the
+.B \-r
+option is specified, the realm fields in the extracted file will
+match the given realm rather than the local realm.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+.IR hostname -new-srvtab
+Service key file generated for
+.I hostname
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH SEE ALSO
+read_service_key(3), krb_get_phost(3)
diff --git a/eBones/ext_srvtab/ext_srvtab.c b/eBones/ext_srvtab/ext_srvtab.c
new file mode 100644
index 0000000..3a5dcec
--- /dev/null
+++ b/eBones/ext_srvtab/ext_srvtab.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $
+ * $Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#define TRUE 1
+#define FALSE 0
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+char progname[] = "ext_srvtab";
+char realm[REALM_SZ];
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ FILE *fout;
+ char fname[1024];
+ int fopen_errs = 0;
+ int arg;
+ Principal princs[40];
+ int more;
+ int prompt = TRUE;
+ register int n, i;
+
+ bzero(realm, sizeof(realm));
+
+ /* Parse commandline arguments */
+ if (argc < 2)
+ usage();
+ else {
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-n") == 0)
+ prompt = FALSE;
+ else if (strcmp(argv[i], "-r") == 0) {
+ if (++i >= argc)
+ usage();
+ else {
+ strcpy(realm, argv[i]);
+ /*
+ * This is to humor the broken way commandline
+ * argument parsing is done. Later, this
+ * program ignores everything that starts with -.
+ */
+ argv[i][0] = '-';
+ }
+ }
+ else if (argv[i][0] == '-')
+ usage();
+ else
+ if (!k_isinst(argv[i])) {
+ fprintf(stderr, "%s: bad instance name: %s\n",
+ progname, argv[i]);
+ usage();
+ }
+ }
+ }
+
+ if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ fflush (stderr);
+ exit(1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ exit(1);
+ }
+
+ /* For each arg, search for instances of arg, and produce */
+ /* srvtab file */
+ if (!realm[0])
+ if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ fprintf(stderr, "%s: couldn't get local realm\n", progname);
+ exit(1);
+ }
+ (void) umask(077);
+
+ for (arg = 1; arg < argc; arg++) {
+ if (argv[arg][0] == '-')
+ continue;
+ sprintf(fname, "%s-new-srvtab", argv[arg]);
+ if ((fout = fopen(fname, "w")) == NULL) {
+ fprintf(stderr, "Couldn't create file '%s'.\n", fname);
+ fopen_errs++;
+ continue;
+ }
+ printf("Generating '%s'....\n", fname);
+ n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more);
+ if (more)
+ fprintf(stderr, "More than 40 found...\n");
+ for (i = 0; i < n; i++) {
+ FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout);
+ FWrite(princs[i].instance, strlen(princs[i].instance) + 1,
+ 1, fout);
+ FWrite(realm, strlen(realm) + 1, 1, fout);
+ FWrite(&princs[i].key_version,
+ sizeof(princs[i].key_version), 1, fout);
+ bcopy(&princs[i].key_low, session_key, sizeof(long));
+ bcopy(&princs[i].key_high, session_key + sizeof(long),
+ sizeof(long));
+ kdb_encrypt_key (session_key, session_key,
+ master_key, master_key_schedule, DES_DECRYPT);
+ FWrite(session_key, sizeof session_key, 1, fout);
+ }
+ fclose(fout);
+ }
+
+ StampOutSecrets();
+
+ exit(fopen_errs); /* 0 errors if successful */
+
+}
+
+Die()
+{
+ StampOutSecrets();
+ exit(1);
+}
+
+FWrite(p, size, n, f)
+ char *p;
+ int size;
+ int n;
+ FILE *f;
+{
+ if (fwrite(p, size, n, f) != n) {
+ printf("Error writing output file. Terminating.\n");
+ Die();
+ }
+}
+
+StampOutSecrets()
+{
+ bzero(master_key, sizeof master_key);
+ bzero(session_key, sizeof session_key);
+ bzero(master_key_schedule, sizeof master_key_schedule);
+}
+
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname);
+ exit(1);
+}
diff --git a/eBones/include/ChangeLog b/eBones/include/ChangeLog
new file mode 100644
index 0000000..254b8dd
--- /dev/null
+++ b/eBones/include/ChangeLog
@@ -0,0 +1,25 @@
+# $Id: ChangeLog,v 1.2 1994/07/19 19:22:41 g89r4222 Exp $
+
+Mon Mar 21 15:48:59 MET 1994 Piero Serini
+ * 1st port to FreeBSD
+
+Tue Nov 29 11:52:51 1988 John T Kohl (jtkohl at lycus)
+
+ * osconf.h: add #ifdef's for SUN processors (bsd/m68k)
+
+ * conf-bsdm68k.h: new file for BSD unix/M68000-based unix boxes
+
+Mon Sep 12 14:33:58 1988 Bill Sommerfeld (wesommer at ra)
+
+ * des_conf.h: deleted file (superceded by conf.h)
+
+ * des.h: remove #include of des_conf.h
+
+ * des.h: remove internal details (sbox structure, bit_{32,64}) from
+interface.
+ Rename data types.
+ Add #defines, turned off if NCOMPAT, for compatibility with old
+ versions.
+
+
+
diff --git a/eBones/include/Makefile b/eBones/include/Makefile
new file mode 100644
index 0000000..8b46c65
--- /dev/null
+++ b/eBones/include/Makefile
@@ -0,0 +1,17 @@
+# from: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.3 1994/09/09 21:43:35 g89r4222 Exp $
+
+FILES= des.h kadm.h kparse.h krb.h krb_db.h
+
+# mit-copyright.h kadm_err.h krb_err.h
+
+NOOBJ= noobj
+NOMAN= noman
+
+all include clean cleandir depend lint tags:
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${FILES} ${DESTDIR}/usr/include/kerberosIV
+
+.include <bsd.prog.mk>
diff --git a/eBones/include/addr_comp.h b/eBones/include/addr_comp.h
new file mode 100644
index 0000000..8d001d3
--- /dev/null
+++ b/eBones/include/addr_comp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for address comparison macros.
+ *
+ * from: addr_comp.h,v 4.0 89/01/23 09:57:44 jtkohl Exp $
+ * $Id: addr_comp.h,v 1.2 1994/07/19 19:22:44 g89r4222 Exp $
+ */
+
+#ifndef ADDR_COMP_DEFS
+#define ADDR_COMP_DEFS
+
+/*
+** Look boys and girls, a big kludge
+** We need to compare the two internet addresses in network byte order, not
+** local byte order. This is a *really really slow way of doing that*
+** But.....
+** .....it works
+** so we run with it
+**
+** long_less_than gets fed two (u_char *)'s....
+*/
+
+#define u_char_comp(x,y) \
+ (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
+
+#define long_less_than(x,y) \
+ (u_char_comp((x)[0],(y)[0])?u_char_comp((x)[0],(y)[0]): \
+ (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+ (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \
+ (u_char_comp((x)[3],(y)[3])))))
+
+#endif /* ADDR_COMP_DEFS */
diff --git a/eBones/include/admin_server.h b/eBones/include/admin_server.h
new file mode 100644
index 0000000..db29c15
--- /dev/null
+++ b/eBones/include/admin_server.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for the Kerberos administration server.
+ *
+ * from: admin_server.h,v 4.7 89/01/11 11:59:42 steiner Exp $
+ * $Id: admin_server.h,v 1.2 1994/07/19 19:22:47 g89r4222 Exp $
+ */
+
+#ifndef ADMIN_SERVER_DEFS
+#define ADMIN_SERVER_DEFS
+
+#define PW_SRV_VERSION 2 /* version number */
+
+#define INSTALL_NEW_PW (1<<0) /*
+ * ver, cmd, name, password,
+ * old_pass, crypt_pass, uid
+ */
+
+#define ADMIN_NEW_PW (2<<1) /*
+ * ver, cmd, name, passwd,
+ * old_pass
+ * (grot), crypt_pass (grot)
+ */
+
+#define ADMIN_SET_KDC_PASSWORD (3<<1) /* ditto */
+#define ADMIN_ADD_NEW_KEY (4<<1) /* ditto */
+#define ADMIN_ADD_NEW_KEY_ATTR (5<<1) /*
+ * ver, cmd, name, passwd,
+ * inst, attr (grot)
+ */
+#define INSTALL_REPLY (1<<1) /* ver, cmd, name, password */
+#define RETRY_LIMIT 1
+#define TIME_OUT 30
+#define USER_TIMEOUT 90
+#define MAX_KPW_LEN 40
+
+#define KADM "changepw" /* service name */
+
+#endif /* ADMIN_SERVER_DEFS */
diff --git a/eBones/include/conf-bsd386i.h b/eBones/include/conf-bsd386i.h
new file mode 100644
index 0000000..0f63212
--- /dev/null
+++ b/eBones/include/conf-bsd386i.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: Sun 386i using SunOS (~BSD)
+ *
+ * from: conf-bsd386i.h,v 4.0 89/12/19 13:26:55 jtkohl Exp $
+ * $Id: conf-bsd386i.h,v 1.2 1994/07/19 19:22:48 g89r4222 Exp $
+ */
+
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+
diff --git a/eBones/include/conf-bsdapollo.h b/eBones/include/conf-bsdapollo.h
new file mode 100644
index 0000000..532d2aa
--- /dev/null
+++ b/eBones/include/conf-bsdapollo.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: conf-bsdapollo.h,v 4.1 89/01/24 14:26:22 jtkohl Exp $
+ * $Id: conf-bsdapollo.h,v 1.2 1994/07/19 19:22:50 g89r4222 Exp $
+ */
+
+#define BSDUNIX
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define DES_SHIFT_SHIFT
+/*
+ * As of SR10, the C compiler claims to be __STDC__, but doesn't support
+ * const. Sigh.
+ */
+#define const
+
+
diff --git a/eBones/include/conf-bsdibm032.h b/eBones/include/conf-bsdibm032.h
new file mode 100644
index 0000000..285fbf6
--- /dev/null
+++ b/eBones/include/conf-bsdibm032.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: IBM 032 (RT/PC)
+ *
+ * from: conf-bsdibm032.h,v 4.0 89/01/23 09:58:01 jtkohl Exp $
+ * $Id: conf-bsdibm032.h,v 1.2 1994/07/19 19:22:51 g89r4222 Exp $
+ */
+
+#define BSDUNIX
+#define IBMWS
+#define IBMWSASM
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define MUSTALIGN
diff --git a/eBones/include/conf-bsdm68k.h b/eBones/include/conf-bsdm68k.h
new file mode 100644
index 0000000..fcc2c57
--- /dev/null
+++ b/eBones/include/conf-bsdm68k.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: 68000 with BSD Unix, e.g. SUN
+ *
+ * from: conf-bsdm68k.h,v 4.0 88/11/29 11:46:58 jtkohl Exp $
+ * $Id: conf-bsdm68k.h,v 1.2 1994/07/19 19:22:53 g89r4222 Exp $
+ */
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
+
diff --git a/eBones/include/conf-bsdsparc.h b/eBones/include/conf-bsdsparc.h
new file mode 100644
index 0000000..abfa2ae
--- /dev/null
+++ b/eBones/include/conf-bsdsparc.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: SPARC with BSD Unix, e.g. SUN-4
+ *
+ * from: conf-bsdsparc.h,v 4.0 89/06/02 13:04:06 jtkohl Exp $
+ * $Id: conf-bsdsparc.h,v 1.2 1994/07/19 19:22:54 g89r4222 Exp $
+ */
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
+#define MUSTALIGN
+
diff --git a/eBones/include/conf-bsdtahoe.h b/eBones/include/conf-bsdtahoe.h
new file mode 100644
index 0000000..8095dc5
--- /dev/null
+++ b/eBones/include/conf-bsdtahoe.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1989 by the Regents of the University of California
+ *
+ * Machine Description : TAHOE.
+ *
+ * from: conf-bsdtahoe.h,v 4.0 89/08/30 11:06:53 jtkohl Exp $
+ * $Id: conf-bsdtahoe.h,v 1.2 1994/07/19 19:22:56 g89r4222 Exp $
+ */
+
+#define TAHOE
+#define BSDUNIX
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define MUSTALIGN
+#define NOASM
diff --git a/eBones/include/conf-bsdvax.h b/eBones/include/conf-bsdvax.h
new file mode 100644
index 0000000..6b82102
--- /dev/null
+++ b/eBones/include/conf-bsdvax.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: VAX
+ *
+ * from: conf-bsdvax.h,v 4.0 89/01/23 09:58:12 jtkohl Exp $
+ * $Id: conf-bsdvax.h,v 1.2 1994/07/19 19:22:57 g89r4222 Exp $
+ */
+
+#define VAX
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+
+#ifndef __STDC__
+#ifndef NOASM
+#define VAXASM
+#endif /* no assembly */
+#endif /* standard C */
diff --git a/eBones/include/conf-ibm370.h b/eBones/include/conf-ibm370.h
new file mode 100644
index 0000000..e4bccfc
--- /dev/null
+++ b/eBones/include/conf-ibm370.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: IBM 370
+ *
+ * from: conf-ibm370.h,v 4.0 89/01/23 09:58:19 jtkohl Exp $
+ * $Id: conf-ibm370.h,v 1.2 1994/07/19 19:22:59 g89r4222 Exp $
+ */
+
+/* What else? */
+#define BIG
+#define NONASCII
+#define SHORTNAMES
diff --git a/eBones/include/conf-pc.h b/eBones/include/conf-pc.h
new file mode 100644
index 0000000..25218e3
--- /dev/null
+++ b/eBones/include/conf-pc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: IBM PC 8086
+ *
+ * from: conf-pc.h,v 4.0 89/01/23 09:58:26 jtkohl Exp $
+ * $Id: conf-pc.h,v 1.2 1994/07/19 19:23:00 g89r4222 Exp $
+ *
+ */
+
+#define IBMPC
+#define BITS16
+#define CROSSMSDOS
+#define LSBFIRST
diff --git a/eBones/include/conf-pyr.h b/eBones/include/conf-pyr.h
new file mode 100644
index 0000000..e88e528
--- /dev/null
+++ b/eBones/include/conf-pyr.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: Pyramid
+ *
+ * from: conf-pyr.h,v 4.0 89/12/19 13:27:16 jtkohl Exp $
+ * $Id: conf-pyr.h,v 1.2 1994/07/19 19:23:02 g89r4222 Exp $
+ */
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
diff --git a/eBones/include/conf-ultmips2.h b/eBones/include/conf-ultmips2.h
new file mode 100644
index 0000000..7d202f5
--- /dev/null
+++ b/eBones/include/conf-ultmips2.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Machine-type definitions: DECstation 3100 (MIPS R2000)
+ *
+ * from: conf-ultmips2.h,v 4.0 89/01/23 09:58:32 jtkohl Exp $
+ * $Id: conf-ultmips2.h,v 1.2 1994/07/19 19:23:03 g89r4222 Exp $
+ */
+
+#define MIPS2
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+#define MUSTALIGN
diff --git a/eBones/include/conf.h b/eBones/include/conf.h
new file mode 100644
index 0000000..30186c5
--- /dev/null
+++ b/eBones/include/conf.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Configuration info for operating system, hardware description,
+ * language implementation, C library, etc.
+ *
+ * This file should be included in (almost) every file in the Kerberos
+ * sources, and probably should *not* be needed outside of those
+ * sources. (How do we deal with /usr/include/des.h and
+ * /usr/include/krb.h?)
+ *
+ * from: conf.h,v 4.0 89/01/23 09:58:40 jtkohl Exp $
+ * $Id: conf.h,v 1.2 1994/07/19 19:23:05 g89r4222 Exp $
+ */
+
+#ifndef _CONF_H_
+
+#include "osconf.h"
+
+#ifdef SHORTNAMES
+#include "names.h"
+#endif
+
+/*
+ * Language implementation-specific definitions
+ */
+
+/* special cases */
+#ifdef __HIGHC__
+/* broken implementation of ANSI C */
+#undef __STDC__
+#endif
+
+#ifndef __STDC__
+#define const
+#define volatile
+#define signed
+typedef char *pointer; /* pointer to generic data */
+#define PROTOTYPE(p) ()
+#else
+typedef void *pointer;
+#define PROTOTYPE(p) p
+#endif
+
+/* Does your compiler understand "void"? */
+#ifdef notdef
+#define void int
+#endif
+
+/*
+ * A few checks to see that necessary definitions are included.
+ */
+
+/* byte order */
+
+#ifndef MSBFIRST
+#ifndef LSBFIRST
+Error: byte order not defined.
+#endif
+#endif
+
+/* machine size */
+#ifndef BITS16
+#ifndef BITS32
+Error: how big is this machine anyways?
+#endif
+#endif
+
+/* end of checks */
+
+#endif /* _CONF_H_ */
diff --git a/eBones/include/des.h b/eBones/include/des.h
new file mode 100644
index 0000000..9cc2056
--- /dev/null
+++ b/eBones/include/des.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for the Data Encryption Standard library.
+ *
+ * from: des.h,v 4.11 89/01/17 16:24:57 rfrench Exp $
+ * $Id: des.h,v 1.2 1994/07/19 19:23:06 g89r4222 Exp $
+ */
+
+/* only do the whole thing once */
+#ifndef DES_DEFS
+#define DES_DEFS
+
+typedef unsigned char des_cblock[8]; /* crypto-block size */
+/* Key schedule */
+typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#ifndef NCOMPAT
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define key_sched des_key_sched
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define C_Block_print des_cblock_print
+#define quad_cksum des_quad_cksum
+typedef struct des_ks_struct bit_64;
+#endif
+
+#define des_cblock_print(x) des_cblock_print_file(x, stdout)
+
+#endif DES_DEFS
diff --git a/eBones/include/highc.h b/eBones/include/highc.h
new file mode 100644
index 0000000..be50e3f
--- /dev/null
+++ b/eBones/include/highc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Known breakage in the version of Metaware's High C compiler that
+ * we've got available....
+ *
+ * from: highc.h,v 4.0 89/01/23 09:59:15 jtkohl Exp $
+ * $Id: highc.h,v 1.2 1994/07/19 19:23:08 g89r4222 Exp $
+ */
+
+#define const
+/*#define volatile*/
+
+/*
+ * Some builtin functions we can take advantage of for inlining....
+ */
+
+#define abs _abs
+/* the _max and _min builtins accept any number of arguments */
+#undef MAX
+#define MAX(x,y) _max(x,y)
+#undef MIN
+#define MIN(x,y) _min(x,y)
+/*
+ * I'm not sure if 65535 is a limit for this builtin, but it's
+ * reasonable for a string length. Or is it?
+ */
+/*#define strlen(s) _find_char(s,65535,0)*/
+#define bzero(ptr,len) _fill_char(ptr,len,'\0')
+#define bcmp(b1,b2,len) _compare(b1,b2,len)
diff --git a/eBones/include/kadm.h b/eBones/include/kadm.h
new file mode 100644
index 0000000..a1cca81
--- /dev/null
+++ b/eBones/include/kadm.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Definitions for Kerberos administration server & client
+ *
+ * from: kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp $
+ * $Id: kadm.h,v 1.2 1994/07/19 19:23:09 g89r4222 Exp $
+ */
+
+#ifndef KADM_DEFS
+#define KADM_DEFS
+
+/*
+ * kadm.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ */
+
+/* for those broken Unixes without this defined... should be in sys/param.h */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+/* The global structures for the client and server */
+typedef struct {
+ struct sockaddr_in admin_addr;
+ struct sockaddr_in my_addr;
+ int my_addr_len;
+ int admin_fd; /* file descriptor for link to admin server */
+ char sname[ANAME_SZ]; /* the service name */
+ char sinst[INST_SZ]; /* the services instance */
+ char krbrlm[REALM_SZ];
+} Kadm_Client;
+
+typedef struct { /* status of the server, i.e the parameters */
+ int inter; /* Space for command line flags */
+ char *sysfile; /* filename of server */
+} admin_params; /* Well... it's the admin's parameters */
+
+/* Largest password length to be supported */
+#define MAX_KPW_LEN 128
+
+/* Largest packet the admin server will ever allow itself to return */
+#define KADM_RET_MAX 2048
+
+/* That's right, versions are 8 byte strings */
+#define KADM_VERSTR "KADM0.0A"
+#define KADM_ULOSE "KYOULOSE" /* sent back when server can't
+ decrypt client's msg */
+#define KADM_VERSIZE strlen(KADM_VERSTR)
+
+/* the lookups for the server instances */
+#define PWSERV_NAME "changepw"
+#define KADM_SNAME "kerberos_master"
+#define KADM_SINST "kerberos"
+
+/* Attributes fields constants and macros */
+#define ALLOC 2
+#define RESERVED 3
+#define DEALLOC 4
+#define DEACTIVATED 5
+#define ACTIVE 6
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+typedef struct {
+ u_char fields[FLDSZ]; /* The active fields in this struct */
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ unsigned long key_low;
+ unsigned long key_high;
+ unsigned long exp_date;
+ unsigned short attributes;
+ unsigned char max_life;
+} Kadm_vals; /* The basic values structure in Kadm */
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+/* Need to define fields types here */
+#define KADM_NAME 31
+#define KADM_INST 30
+#define KADM_EXPDATE 29
+#define KADM_ATTR 28
+#define KADM_MAXLIFE 27
+#define KADM_DESKEY 26
+
+/* To set a field entry f in a fields structure d */
+#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8)))
+
+/* To set a field entry f in a fields structure d */
+#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8))))
+
+/* Is field f in fields structure d */
+#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8)))
+
+/* Various return codes */
+#define KADM_SUCCESS 0
+
+#define WILDCARD_STR "*"
+
+enum acl_types {
+ADDACL,
+GETACL,
+MODACL
+};
+
+/* Various opcodes for the admin server's functions */
+#define CHANGE_PW 2
+#define ADD_ENT 3
+#define MOD_ENT 4
+#define GET_ENT 5
+
+extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
+extern long kdb_verify_master_key(); /* XXX ditto */
+
+extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
+extern void krb_set_tkt_string(); /* XXX ditto */
+
+extern unsigned long quad_cksum(); /* XXX should be in des.h */
+
+/* XXX This doesn't belong here!!! */
+char *malloc(), *realloc();
+#ifdef POSIX
+typedef void sigtype;
+#else
+typedef int sigtype;
+#endif
+
+#endif KADM_DEFS
diff --git a/eBones/include/kdc.h b/eBones/include/kdc.h
new file mode 100644
index 0000000..518e5e9
--- /dev/null
+++ b/eBones/include/kdc.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for the Kerberos Key Distribution Center.
+ *
+ * from: kdc.h,v 4.1 89/01/24 17:54:04 jon Exp $
+ * $Id: kdc.h,v 1.2 1994/07/19 19:23:11 g89r4222 Exp $
+ */
+
+#ifndef KDC_DEFS
+#define KDC_DEFS
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+#define max(a,b) (a>b ? a : b)
+#define min(a,b) (a<b ? a : b)
+
+#define TRUE 1
+#define FALSE 0
+
+#define MKEYFILE "/etc/kerberosIV/master_key"
+#define K_LOGFIL "/var/log/kpropd.log"
+#define KS_LOGFIL "/var/log/kerberos_slave.log"
+#define KRB_ACL "/etc/kerberosIV/kerberos.acl"
+#define KRB_PROG "./kerberos"
+
+#define ONE_MINUTE 60
+#define FIVE_MINUTES (5 * ONE_MINUTE)
+#define ONE_HOUR (60 * ONE_MINUTE)
+#define ONE_DAY (24 * ONE_HOUR)
+#define THREE_DAYS (3 * ONE_DAY)
+
+#endif /* KDC_DEFS */
+
diff --git a/eBones/include/klog.h b/eBones/include/klog.h
new file mode 100644
index 0000000..e8c5070
--- /dev/null
+++ b/eBones/include/klog.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This file defines the types of log messages logged by klog. Each
+ * type of message may be selectively turned on or off.
+ *
+ * from: klog.h,v 4.7 89/01/24 17:55:07 jon Exp $
+ * $Id: klog.h,v 1.2 1994/07/19 19:23:12 g89r4222 Exp $
+ */
+
+#ifndef KLOG_DEFS
+#define KLOG_DEFS
+
+#define KRBLOG "/var/log/kerberos.log" /* master server */
+#define KRBSLAVELOG "/var/log/kerberos_slave.log" /* master server */
+#define NLOGTYPE 100 /* Maximum number of log msg types */
+
+#define L_NET_ERR 1 /* Error in network code */
+#define L_NET_INFO 2 /* Info on network activity */
+#define L_KRB_PERR 3 /* Kerberos protocol errors */
+#define L_KRB_PINFO 4 /* Kerberos protocol info */
+#define L_INI_REQ 5 /* Request for initial ticket */
+#define L_NTGT_INTK 6 /* Initial request not for TGT */
+#define L_DEATH_REQ 7 /* Request for server death */
+#define L_TKT_REQ 8 /* All ticket requests using a tgt */
+#define L_ERR_SEXP 9 /* Service expired */
+#define L_ERR_MKV 10 /* Master key version incorrect */
+#define L_ERR_NKY 11 /* User's key is null */
+#define L_ERR_NUN 12 /* Principal not unique */
+#define L_ERR_UNK 13 /* Principal Unknown */
+#define L_ALL_REQ 14 /* All requests */
+#define L_APPL_REQ 15 /* Application requests (using tgt) */
+#define L_KRB_PWARN 16 /* Protocol warning messages */
+
+char *klog();
+
+#endif /* KLOG_DEFS */
diff --git a/eBones/include/kparse.h b/eBones/include/kparse.h
new file mode 100644
index 0000000..9bdc07c
--- /dev/null
+++ b/eBones/include/kparse.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for kparse routines.
+ *
+ * from: kparse.h,v 4.5 89/01/11 12:05:53 steiner Exp $
+ * $Id: kparse.h,v 1.2 1994/07/19 19:23:14 g89r4222 Exp $
+ */
+
+#ifndef KPARSE_DEFS
+#define KPARSE_DEFS
+
+/*
+ * values returned by fGetParameterSet()
+ */
+
+#define PS_BAD_KEYWORD -2 /* unknown or duplicate keyword */
+#define PS_SYNTAX -1 /* syntax error */
+#define PS_OKAY 0 /* got a complete parameter set */
+#define PS_EOF 1 /* nothing more in the file */
+
+/*
+ * values returned by fGetKeywordValue()
+ */
+
+#define KV_SYNTAX -2 /* syntax error */
+#define KV_EOF -1 /* nothing more in the file */
+#define KV_OKAY 0 /* got a keyword/value pair */
+#define KV_EOL 1 /* nothing more on this line */
+
+/*
+ * values returned by fGetToken()
+ */
+
+#define GTOK_BAD_QSTRING -1 /* newline found in quoted string */
+#define GTOK_EOF 0 /* end of file encountered */
+#define GTOK_QSTRING 1 /* quoted string */
+#define GTOK_STRING 2 /* unquoted string */
+#define GTOK_NUMBER 3 /* one or more digits */
+#define GTOK_PUNK 4 /* punks are punctuation, newline,
+ * etc. */
+#define GTOK_WHITE 5 /* one or more whitespace chars */
+
+/*
+ * extended character classification macros
+ */
+
+#define ISOCTAL(CH) ( (CH>='0') && (CH<='7') )
+#define ISQUOTE(CH) ( (CH=='\"') || (CH=='\'') || (CH=='`') )
+#define ISWHITESPACE(C) ( (C==' ') || (C=='\t') )
+#define ISLINEFEED(C) ( (C=='\n') || (C=='\r') || (C=='\f') )
+
+/*
+ * tokens consist of any printable charcacter except comma, equal, or
+ * whitespace
+ */
+
+#define ISTOKENCHAR(C) ((C>040) && (C<0177) && (C != ',') && (C != '='))
+
+/*
+ * the parameter table defines the keywords that will be recognized by
+ * fGetParameterSet, and their default values if not specified.
+ */
+
+typedef struct {
+ char *keyword;
+ char *defvalue;
+ char *value;
+} parmtable;
+
+#define PARMCOUNT(P) (sizeof(P)/sizeof(P[0]))
+
+extern int LineNbr; /* current line # in parameter file */
+
+extern char ErrorMsg[]; /*
+ * meaningful only when KV_SYNTAX,
+ * PS_SYNTAX, or PS_BAD_KEYWORD is
+ * returned by fGetKeywordValue or
+ * fGetParameterSet
+ */
+
+extern char *strsave(); /* defined in this module */
+extern char *strutol(); /* defined in this module */
+
+#endif /* KPARSE_DEFS */
diff --git a/eBones/include/krb.h b/eBones/include/krb.h
new file mode 100644
index 0000000..15e831b
--- /dev/null
+++ b/eBones/include/krb.h
@@ -0,0 +1,376 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for the Kerberos library.
+ *
+ * from: krb.h,v 4.26 89/08/08 17:55:25 jtkohl Exp $
+ * $Id: krb.h,v 1.4 1994/09/24 14:15:41 g89r4222 Exp $
+ */
+
+/* Only one time, please */
+#ifndef KRB_DEFS
+#define KRB_DEFS
+
+/* Need some defs from des.h */
+#include <kerberosIV/des.h>
+
+/* Text describing error codes */
+#define MAX_KRB_ERRORS 256
+extern char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* These are not defined for at least SunOS 3.3 and Ultrix 2.2 */
+#if defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)
+#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
+#define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n)))
+#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << (n)))
+#endif /* ULTRIX022 || SunOS */
+
+/* General definitions */
+#define KSUCCESS 0
+#define KFAILURE 255
+
+#ifdef NO_UIDGID_T
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+#endif /* NO_UIDGID_T */
+
+/*
+ * Kerberos specific definitions
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database. The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server. Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm.
+ */
+
+#ifdef notdef
+this is server - only, does not belong here;
+#define KRBLOG "/etc/kerberosIV/kerberos.log"
+are these used anyplace '?';
+#define VX_KRB_HSTFILE "/etc/krbhst"
+#define PC_KRB_HSTFILE "\\kerberos\\krbhst"
+#endif
+
+#define KRB_CONF "/etc/kerberosIV/krb.conf"
+#define KRB_RLM_TRANS "/etc/kerberosIV/krb.realms"
+#define KRB_MASTER "kerberos"
+#define KRB_HOST KRB_MASTER
+#define KRB_REALM "ATHENA.MIT.EDU"
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define ANAME_SZ 40
+#define REALM_SZ 40
+#define SNAME_SZ 40
+#define INST_SZ 40
+/* include space for '.' and '@' */
+#define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2)
+#define KKEY_SZ 100
+#define VERSION_SZ 1
+#define MSG_TYPE_SZ 1
+#define DATE_SZ 26 /* RTI date output */
+
+#define MAX_HSTNM 100
+
+#ifndef DEFAULT_TKT_LIFE /* allow compile-time override */
+#define DEFAULT_TKT_LIFE 96 /* default lifetime for krb_mk_req
+ & co., 8 hrs */
+#endif
+
+/* Definition of text structure used to pass text around */
+#define MAX_KTXT_LEN 1250
+
+struct ktext {
+ int length; /* Length of the text */
+ unsigned char dat[MAX_KTXT_LEN]; /* The data itself */
+ unsigned long mbz; /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define CLIENT_KRB_TIMEOUT 4 /* time between retries */
+#define CLIENT_KRB_RETRY 5 /* retry this many times */
+#define CLIENT_KRB_BUFLEN 512 /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define R_TKT_FIL 0
+#define W_TKT_FIL 1
+
+/* Definitions for cl_get_tgt */
+#ifdef PC
+#define CL_GTGT_INIT_FILE "\\kerberos\\k_in_tkts"
+#else
+#define CL_GTGT_INIT_FILE "/etc/k_in_tkts"
+#endif PC
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define CLOCK_SKEW 5*60
+/* Filename for readservkey */
+#define KEYFILE "/etc/kerberosIV/srvtab"
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+ unsigned char k_flags; /* Flags from ticket */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* His Instance */
+ char prealm[REALM_SZ]; /* His Realm */
+ unsigned long checksum; /* Data checksum (opt) */
+ C_Block session; /* Session Key */
+ int life; /* Life of ticket */
+ unsigned long time_sec; /* Time ticket issued */
+ unsigned long address; /* Address in ticket */
+ KTEXT_ST reply; /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+ char service[ANAME_SZ]; /* Service name */
+ char instance[INST_SZ]; /* Instance */
+ char realm[REALM_SZ]; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT_ST ticket_st; /* The ticket itself */
+ long issue_date; /* The issue time */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+ unsigned char *app_data; /* pointer to appl data */
+ unsigned long app_length; /* length of appl data */
+ unsigned long hash; /* hash to lookup replay */
+ int swap; /* swap bytes? */
+ long time_sec; /* msg timestamp seconds */
+ unsigned char time_5ms; /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+
+/* Location of ticket file for save_cred and get_cred */
+#ifdef PC
+#define TKT_FILE "\\kerberos\\ticket.ses"
+#else
+#define TKT_FILE tkt_string()
+#define TKT_ROOT "/tmp/tkt"
+#endif PC
+
+/* Error codes returned from the KDC */
+#define KDC_OK 0 /* Request OK */
+#define KDC_NAME_EXP 1 /* Principal expired */
+#define KDC_SERVICE_EXP 2 /* Service expired */
+#define KDC_AUTH_EXP 3 /* Auth expired */
+#define KDC_PKT_VER 4 /* Protocol version unknown */
+#define KDC_P_MKEY_VER 5 /* Wrong master key version */
+#define KDC_S_MKEY_VER 6 /* Wrong master key version */
+#define KDC_BYTE_ORDER 7 /* Byte order unknown */
+#define KDC_PR_UNKNOWN 8 /* Principal unknown */
+#define KDC_PR_N_UNIQUE 9 /* Principal not unique */
+#define KDC_NULL_KEY 10 /* Principal has null key */
+#define KDC_GEN_ERR 20 /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define GC_OK 0 /* Retrieve OK */
+#define RET_OK 0 /* Retrieve OK */
+#define GC_TKFIL 21 /* Can't read ticket file */
+#define RET_TKFIL 21 /* Can't read ticket file */
+#define GC_NOTKT 22 /* Can't find ticket or TGT */
+#define RET_NOTKT 22 /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req */
+#define MK_AP_OK 0 /* Success */
+#define MK_AP_TGTEXP 26 /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define RD_AP_OK 0 /* Request authentic */
+#define RD_AP_UNDEC 31 /* Can't decode authenticator */
+#define RD_AP_EXP 32 /* Ticket expired */
+#define RD_AP_NYV 33 /* Ticket not yet valid */
+#define RD_AP_REPEAT 34 /* Repeated request */
+#define RD_AP_NOT_US 35 /* The ticket isn't for us */
+#define RD_AP_INCON 36 /* Request is inconsistent */
+#define RD_AP_TIME 37 /* delta_t too big */
+#define RD_AP_BADD 38 /* Incorrect net address */
+#define RD_AP_VERSION 39 /* protocol version mismatch */
+#define RD_AP_MSG_TYPE 40 /* invalid msg type */
+#define RD_AP_MODIFIED 41 /* message stream modified */
+#define RD_AP_ORDER 42 /* message out of order */
+#define RD_AP_UNAUTHOR 43 /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define GT_PW_OK 0 /* Got password changing tkt */
+#define GT_PW_NULL 51 /* Current PW is null */
+#define GT_PW_BADPW 52 /* Incorrect current password */
+#define GT_PW_PROT 53 /* Protocol Error */
+#define GT_PW_KDCERR 54 /* Error returned by KDC */
+#define GT_PW_NULLTKT 55 /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define SKDC_OK 0 /* Response received */
+#define SKDC_RETRY 56 /* Retry count exceeded */
+#define SKDC_CANT 57 /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define INTK_OK 0 /* Ticket obtained */
+#define INTK_W_NOTALL 61 /* Not ALL tickets returned */
+#define INTK_BADPW 62 /* Incorrect password */
+#define INTK_PROT 63 /* Protocol Error */
+#define INTK_ERR 70 /* Other error */
+
+/* Values returned by get_adtkt */
+#define AD_OK 0 /* Ticket Obtained */
+#define AD_NOTGT 71 /* Don't have tgt */
+
+/* Error codes returned by ticket file utilities */
+#define NO_TKT_FIL 76 /* No ticket file found */
+#define TKT_FIL_ACC 77 /* Couldn't access tkt file */
+#define TKT_FIL_LCK 78 /* Couldn't lock ticket file */
+#define TKT_FIL_FMT 79 /* Bad ticket file format */
+#define TKT_FIL_INI 80 /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define KNAME_FMT 81 /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define SAFE_PRIV_ERROR -1 /* syscall error */
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad 0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_long 0-->3, 1-->2, 2-->1, 3-->0
+ * u_short 0-->1, 1-->0
+ */
+
+#define swap_u_16(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(((char *) x) +0, ((char *) _krb_swap_tmp) +14 ,2); \
+ swab(((char *) x) +2, ((char *) _krb_swap_tmp) +12 ,2); \
+ swab(((char *) x) +4, ((char *) _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +6, ((char *) _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +8, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +10,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +12,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +14,((char *) _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,16);\
+ }
+
+#define swap_u_12(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) x, ((char *) _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +2, ((char *) _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +4, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +6, ((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +8, ((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +10,((char *) _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,12);\
+ }
+
+#define swap_C_Block(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) x, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +2,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +4,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +6,((char *) _krb_swap_tmp) ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,8);\
+ }
+#define swap_u_quad(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) &x, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) &x) +2,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) &x) +4,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +6,((char *) _krb_swap_tmp) ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)&x,8);\
+ }
+
+#define swap_u_long(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab((char *) &x, ((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +2,((char *) _krb_swap_tmp),2); \
+ x = _krb_swap_tmp[0]; \
+ }
+
+#define swap_u_short(x) {\
+ unsigned short _krb_swap_sh_tmp; \
+ swab((char *) &x, ( &_krb_swap_sh_tmp) ,2); \
+ x = (unsigned short) _krb_swap_sh_tmp; \
+ }
+
+/* Kerberos ticket flag field bit definitions */
+#define K_FLAG_ORDER 0 /* bit 0 --> lsb */
+#define K_FLAG_1 /* reserved */
+#define K_FLAG_2 /* reserved */
+#define K_FLAG_3 /* reserved */
+#define K_FLAG_4 /* reserved */
+#define K_FLAG_5 /* reserved */
+#define K_FLAG_6 /* reserved */
+#define K_FLAG_7 /* reserved, bit 7 --> msb */
+
+#ifndef PC
+char *tkt_string();
+#endif PC
+
+#ifdef OLDNAMES
+#define krb_mk_req mk_ap_req
+#define krb_rd_req rd_ap_req
+#define krb_kntoln an_to_ln
+#define krb_set_key set_serv_key
+#define krb_get_cred get_credentials
+#define krb_mk_priv mk_private_msg
+#define krb_rd_priv rd_private_msg
+#define krb_mk_safe mk_safe_msg
+#define krb_rd_safe rd_safe_msg
+#define krb_mk_err mk_appl_err_msg
+#define krb_rd_err rd_appl_err_msg
+#define krb_ck_repl check_replay
+#define krb_get_pw_in_tkt get_in_tkt
+#define krb_get_svc_in_tkt get_svc_in_tkt
+#define krb_get_pw_tkt get_pw_tkt
+#define krb_realmofhost krb_getrealm
+#define krb_get_phost get_phost
+#define krb_get_krbhst get_krbhst
+#define krb_get_lrealm get_krbrlm
+#endif OLDNAMES
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define KOPT_DO_MUTUAL 0x00000002 /* do mutual auth */
+
+#define KOPT_DONT_CANON 0x00000004 /*
+ * don't canonicalize inst as
+ * a hostname
+ */
+
+#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
+
+#ifdef ATHENA_COMPAT
+#define KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */
+#endif ATHENA_COMPAT
+
+#endif KRB_DEFS
diff --git a/eBones/include/krb_conf.h b/eBones/include/krb_conf.h
new file mode 100644
index 0000000..824d5fe
--- /dev/null
+++ b/eBones/include/krb_conf.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This file contains configuration information for the Kerberos library
+ * which is machine specific; currently, this file contains
+ * configuration information for the vax, the "ibm032" (RT), and the
+ * "PC8086" (IBM PC).
+ *
+ * Note: cross-compiled targets must appear BEFORE their corresponding
+ * cross-compiler host. Otherwise, both will be defined when running
+ * the native compiler on the programs that construct cross-compiled
+ * sources.
+ *
+ * from: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp $
+ * $Id: krb_conf.h,v 1.2 1994/07/19 19:23:18 g89r4222 Exp $
+ */
+
+#ifndef KRB_CONF_DEFS
+#define KRB_CONF_DEFS
+
+/* Byte ordering */
+extern int krbONE;
+#define HOST_BYTE_ORDER (* (char *) &krbONE)
+#define MSB_FIRST 0 /* 68000, IBM RT/PC */
+#define LSB_FIRST 1 /* Vax, PC8086 */
+
+#endif KRB_CONF_DEFS
diff --git a/eBones/include/krb_db.h b/eBones/include/krb_db.h
new file mode 100644
index 0000000..cbe00b9
--- /dev/null
+++ b/eBones/include/krb_db.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * spm Project Athena 8/85
+ *
+ * This file defines data structures for the kerberos
+ * authentication/authorization database.
+ *
+ * They MUST correspond to those defined in *.rel
+ *
+ * from: krb_db.h,v 4.9 89/01/24 17:55:39 jon Exp $
+ * $Id: krb_db.h,v 1.2 1994/07/19 19:23:19 g89r4222 Exp $
+ */
+
+#ifndef KRB_DB_DEFS
+#define KRB_DB_DEFS
+
+#define KERB_M_NAME "K" /* Kerberos */
+#define KERB_M_INST "M" /* Master */
+#define KERB_DEFAULT_NAME "default"
+#define KERB_DEFAULT_INST ""
+#define DBM_FILE "/etc/kerberosIV/principal"
+
+/* this also defines the number of queue headers */
+#define KERB_DB_HASH_MODULO 64
+
+
+/* Arguments to kerb_dbl_lock() */
+
+#define KERB_DBL_EXCLUSIVE 1
+#define KERB_DBL_SHARED 0
+
+/* arguments to kerb_db_set_lockmode() */
+
+#define KERB_DBL_BLOCKING 0
+#define KERB_DBL_NONBLOCKING 1
+
+/* Principal defines the structure of a principal's name */
+
+typedef struct {
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+
+ unsigned long key_low;
+ unsigned long key_high;
+ unsigned long exp_date;
+ char exp_date_txt[DATE_SZ];
+ unsigned long mod_date;
+ char mod_date_txt[DATE_SZ];
+ unsigned short attributes;
+ unsigned char max_life;
+ unsigned char kdc_key_ver;
+ unsigned char key_version;
+
+ char mod_name[ANAME_SZ];
+ char mod_instance[INST_SZ];
+ char *old; /* cast to (Principal *); not in db,
+ * ptr to old vals */
+}
+ Principal;
+
+typedef struct {
+ long cpu;
+ long elapsed;
+ long dio;
+ long pfault;
+ long t_stamp;
+ long n_retrieve;
+ long n_replace;
+ long n_append;
+ long n_get_stat;
+ long n_put_stat;
+}
+ DB_stat;
+
+/* Dba defines the structure of a database administrator */
+
+typedef struct {
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ unsigned short attributes;
+ unsigned long exp_date;
+ char exp_date_txt[DATE_SZ];
+ char *old; /*
+ * cast to (Dba *); not in db, ptr to
+ * old vals
+ */
+}
+ Dba;
+
+extern int kerb_get_principal();
+extern int kerb_put_principal();
+extern int kerb_db_get_stat();
+extern int kerb_db_put_stat();
+extern int kerb_get_dba();
+extern int kerb_db_get_dba();
+
+#endif /* KRB_DB_DEFS */
diff --git a/eBones/include/lsb_addr_comp.h b/eBones/include/lsb_addr_comp.h
new file mode 100644
index 0000000..fe7dc94
--- /dev/null
+++ b/eBones/include/lsb_addr_comp.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Comparison macros to emulate LSBFIRST comparison results of network
+ * byte-order quantities
+ *
+ * from: lsb_addr_comp.h,v 4.0 89/01/23 15:44:46 jtkohl Exp $
+ * $Id: lsb_addr_comp.h,v 1.2 1994/07/19 19:23:21 g89r4222 Exp $
+ */
+
+#ifndef LSB_ADDR_COMP_DEFS
+#define LSB_ADDR_COMP_DEFS
+
+#include "osconf.h"
+
+#ifdef LSBFIRST
+#define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#else
+/* MSBFIRST */
+#define u_char_comp(x,y) \
+ (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
+/* This is gross, but... */
+#define lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y)
+#define lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y)
+
+#define long_less_than(x,y) \
+ (u_char_comp((x)[3],(y)[3])?u_char_comp((x)[3],(y)[3]): \
+ (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \
+ (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+ (u_char_comp((x)[0],(y)[0])))))
+#define short_less_than(x,y) \
+ (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+ (u_char_comp((x)[0],(y)[0])))
+
+#endif /* LSBFIRST */
+
+#endif /* LSB_ADDR_COMP_DEFS */
diff --git a/eBones/include/osconf.h b/eBones/include/osconf.h
new file mode 100644
index 0000000..d3d4861
--- /dev/null
+++ b/eBones/include/osconf.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Athena configuration.
+ *
+ * from: osconf.h,v 4.4 89/12/19 13:26:27 jtkohl Exp $
+ * $Id: osconf.h,v 1.2 1994/07/19 19:23:22 g89r4222 Exp $
+ */
+
+#ifdef tahoe
+#include "conf-bsdtahoe.h"
+#else /* !tahoe */
+#ifdef vax
+#include "conf-bsdvax.h"
+#else /* !vax */
+#if defined(mips) && defined(ultrix)
+#include "conf-ultmips2.h"
+#else /* !Ultrix MIPS-2 */
+#ifdef ibm032
+#include "conf-bsdibm032.h"
+#else /* !ibm032 */
+#ifdef apollo
+#include "conf-bsdapollo.h"
+#else /* !apollo */
+#ifdef sun
+#ifdef sparc
+#include "conf-bsdsparc.h"
+#else /* sun but not sparc */
+#ifdef i386
+#include "conf-bsd386i.h"
+#else /* sun but not (sparc or 386i) */
+#include "conf-bsdm68k.h"
+#endif /* i386 */
+#endif /* sparc */
+#else /* !sun */
+#ifdef pyr
+#include "conf-pyr.h"
+#endif /* pyr */
+#endif /* sun */
+#endif /* apollo */
+#endif /* ibm032 */
+#endif /* mips */
+#endif /* vax */
+#endif /* tahoe */
+
+#if defined(__FreeBSD__) && defined(i386)
+#include "conf-bsd386i.h"
+#endif
+
diff --git a/eBones/include/passwd_server.h b/eBones/include/passwd_server.h
new file mode 100644
index 0000000..cb8eb08
--- /dev/null
+++ b/eBones/include/passwd_server.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for password server
+ *
+ * from: passwd_server.h,v 4.6 89/01/11 15:12:22 steiner Exp $
+ * $Id: passwd_server.h,v 1.2 1994/07/19 19:23:24 g89r4222 Exp $
+ */
+
+#ifndef PASSWD_SERVER_DEFS
+#define PASSWD_SERVER_DEFS
+
+#define PW_SRV_VERSION 2 /* version number */
+#define RETRY_LIMIT 1
+#define TIME_OUT 30
+#define USER_TIMEOUT 90
+#define MAX_KPW_LEN 40 /* hey, seems like a good number */
+
+#define INSTALL_NEW_PW (1<<0) /*
+ * ver, cmd, name, password, old_pass,
+ * crypt_pass, uid
+ */
+
+#define INSTALL_REPLY (1<<1) /* ver, cmd, name, password */
+
+#endif /* PASSWD_SERVER_DEFS */
diff --git a/eBones/include/principal.h b/eBones/include/principal.h
new file mode 100644
index 0000000..4590116
--- /dev/null
+++ b/eBones/include/principal.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Definitions for principal names.
+ *
+ * from: principal.h,v 4.5 89/01/11 15:15:01 steiner Exp $
+ * $Id: principal.h,v 1.2 1994/07/19 19:23:25 g89r4222 Exp $
+ */
+
+#ifndef PRINCIPAL_DEFS
+#define PRINCIPAL_DEFS
+
+#define NAME_LEN 39
+#define INSTANCE_LEN 39
+
+#endif /* PRINCIPAL_DEFS */
diff --git a/eBones/include/prot.h b/eBones/include/prot.h
new file mode 100644
index 0000000..7865607
--- /dev/null
+++ b/eBones/include/prot.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file with authentication protocol information.
+ *
+ * from: prot.h,v 4.13 89/01/24 14:27:22 jtkohl Exp $
+ * $Id: prot.h,v 1.2 1994/07/19 19:23:27 g89r4222 Exp $
+ */
+
+#include <krb_conf.h>
+
+#ifndef PROT_DEFS
+#define PROT_DEFS
+
+#define KRB_PORT 750 /* PC's don't have
+ * /etc/services */
+#define KRB_PROT_VERSION 4
+#define MAX_PKT_LEN 1000
+#define MAX_TXT_LEN 1000
+#define TICKET_GRANTING_TICKET "krbtgt"
+
+/* Macro's to obtain various fields from a packet */
+
+#define pkt_version(packet) (unsigned int) *(packet->dat)
+#define pkt_msg_type(packet) (unsigned int) *(packet->dat+1)
+#define pkt_a_name(packet) (packet->dat+2)
+#define pkt_a_inst(packet) \
+ (packet->dat+3+strlen((char *)pkt_a_name(packet)))
+#define pkt_a_realm(packet) \
+ (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet)))
+
+/* Macro to obtain realm from application request */
+#define apreq_realm(auth) (auth->dat + 3)
+
+#define pkt_time_ws(packet) (char *) \
+ (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \
+ strlen((char *)pkt_a_inst(packet)) + \
+ strlen((char *)pkt_a_realm(packet)))
+
+#define pkt_no_req(packet) (unsigned short) \
+ *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+ strlen((char *)pkt_a_inst(packet)) + \
+ strlen((char *)pkt_a_realm(packet)))
+#define pkt_x_date(packet) (char *) \
+ (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \
+ strlen((char *)pkt_a_inst(packet)) + \
+ strlen((char *)pkt_a_realm(packet)))
+#define pkt_err_code(packet) ( (char *) \
+ (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+ strlen((char *)pkt_a_inst(packet)) + \
+ strlen((char *)pkt_a_realm(packet))))
+#define pkt_err_text(packet) \
+ (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \
+ strlen((char *)pkt_a_inst(packet)) + \
+ strlen((char *)pkt_a_realm(packet)))
+
+/* Routines to create and read packets may be found in prot.c */
+
+KTEXT create_auth_reply();
+KTEXT create_death_packet();
+KTEXT pkt_cipher();
+
+/* Message types , always leave lsb for byte order */
+
+#define AUTH_MSG_KDC_REQUEST 1<<1
+#define AUTH_MSG_KDC_REPLY 2<<1
+#define AUTH_MSG_APPL_REQUEST 3<<1
+#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1
+#define AUTH_MSG_ERR_REPLY 5<<1
+#define AUTH_MSG_PRIVATE 6<<1
+#define AUTH_MSG_SAFE 7<<1
+#define AUTH_MSG_APPL_ERR 8<<1
+#define AUTH_MSG_DIE 63<<1
+
+/* values for kerb error codes */
+
+#define KERB_ERR_OK 0
+#define KERB_ERR_NAME_EXP 1
+#define KERB_ERR_SERVICE_EXP 2
+#define KERB_ERR_AUTH_EXP 3
+#define KERB_ERR_PKT_VER 4
+#define KERB_ERR_NAME_MAST_KEY_VER 5
+#define KERB_ERR_SERV_MAST_KEY_VER 6
+#define KERB_ERR_BYTE_ORDER 7
+#define KERB_ERR_PRINCIPAL_UNKNOWN 8
+#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
+#define KERB_ERR_NULL_KEY 10
+
+#endif /* PROT_DEFS */
diff --git a/eBones/kadmin/kadmin.8 b/eBones/kadmin/kadmin.8
new file mode 100644
index 0000000..6e15015
--- /dev/null
+++ b/eBones/kadmin/kadmin.8
@@ -0,0 +1,158 @@
+.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $
+.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmin \- network utility for Kerberos database administration
+.SH SYNOPSIS
+.B kadmin [-u user] [-r default_realm] [-m]
+.SH DESCRIPTION
+This utility provides a unified administration interface to
+the
+Kerberos
+master database.
+Kerberos
+administrators
+use
+.I kadmin
+to register new users and services to the master database,
+and to change information about existing database entries.
+For instance, an administrator can use
+.I kadmin
+to change a user's
+Kerberos
+password.
+A Kerberos administrator is a user with an ``admin'' instance
+whose name appears on one of the Kerberos administration access control
+lists. If the \-u option is used,
+.I user
+will be used as the administrator instead of the local user.
+If the \-r option is used,
+.I default_realm
+will be used as the default realm for transactions. Otherwise,
+the local realm will be used by default.
+If the \-m option is used, multiple requests will be permitted
+on only one entry of the admin password. Some sites won't
+support this option.
+
+The
+.I kadmin
+program communicates over the network with the
+.I kadmind
+program, which runs on the machine housing the Kerberos master
+database.
+The
+.I kadmind
+creates new entries and makes modifications to the database.
+
+When you enter the
+.I kadmin
+command,
+the program displays a message that welcomes you and explains
+how to ask for help.
+Then
+.I kadmin
+waits for you to enter commands (which are described below).
+It then asks you for your
+.I admin
+password before accessing the database.
+
+Use the
+.I add_new_key
+(or
+.I ank
+for short)
+command to register a new principal
+with the master database.
+The command requires one argument,
+the principal's name. The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's
+new password. If no realm is specified,
+the local realm is used unless another was
+given on the commandline with the \-r flag.
+If no instance is
+specified, a null instance is used. If
+a realm other than the default realm is specified,
+you will need to supply your admin password for
+the other realm.
+
+Use the
+.I change_password (cpw)
+to change a principal's
+Kerberos
+password.
+The command requires one argument,
+the principal's
+name.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's new password.
+The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+
+Use the
+.I change_admin_password (cap)
+to change your
+.I admin
+instance password.
+This command requires no arguments.
+It prompts you for your old
+.I admin
+password, then prompts you twice to enter the new
+.I admin
+password. If this is your first command,
+the default realm is used. Otherwise, the realm
+used in the last command is used.
+
+Use the
+.I destroy_tickets (dest)
+command to destroy your admin tickets explicitly.
+
+Use the
+.I list_requests (lr)
+command to get a list of possible commands.
+
+Use the
+.I help
+command to display
+.IR kadmin's
+various help messages.
+If entered without an argument,
+.I help
+displays a general help message.
+You can get detailed information on specific
+.I kadmin
+commands
+by entering
+.I help
+.IR command_name .
+
+To quit the program, type
+.IR quit .
+
+.SH BUGS
+The user interface is primitive, and the command names could be better.
+
+.SH "SEE ALSO"
+kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8)
+.br
+``A Subsystem Utilities Package for UNIX'' by Ken Raeburn
+.SH AUTHORS
+Jeffrey I. Schiller, MIT Project Athena
+.br
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/kadmind/kadmind.8 b/eBones/kadmind/kadmind.8
new file mode 100644
index 0000000..59075ee
--- /dev/null
+++ b/eBones/kadmind/kadmind.8
@@ -0,0 +1,117 @@
+.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $
+.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmind \- network daemon for Kerberos database administration
+.SH SYNOPSIS
+.B kadmind
+[
+.B \-n
+] [
+.B \-h
+] [
+.B \-r realm
+] [
+.B \-f filename
+] [
+.B \-d dbname
+] [
+.B \-a acldir
+]
+.SH DESCRIPTION
+.I kadmind
+is the network database server for the Kerberos password-changing and
+administration tools.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.
+.PP
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+If the
+.B \-r
+.I realm
+option is specified, the admin server will pretend that its
+local realm is
+.I realm
+instead of the actual local realm of the host it is running on.
+This makes it possible to run a server for a foreign kerberos
+realm.
+.PP
+If the
+.B \-f
+.I filename
+option is specified, then that file is used to hold the log information
+instead of the default.
+.PP
+If the
+.B \-d
+.I dbname
+option is specified, then that file is used as the database name instead
+of the default.
+.PP
+If the
+.B \-a
+.I acldir
+option is specified, then
+.I acldir
+is used as the directory in which to search for access control lists
+instead of the default.
+.PP
+If the
+.B \-h
+option is specified,
+.I kadmind
+prints out a short summary of the permissible control arguments, and
+then exits.
+.PP
+When performing requests on behalf of clients,
+.I kadmind
+checks access control lists (ACLs) to determine the authorization of the client
+to perform the requested action.
+Currently three distinct access types are supported:
+.TP 1i
+Addition
+(.add ACL file). If a principal is on this list, it may add new
+principals to the database.
+.TP
+Retrieval
+(.get ACL file). If a principal is on this list, it may retrieve
+database entries. NOTE: A principal's private key is never returned by
+the get functions.
+.TP
+Modification
+(.mod ACL file). If a principal is on this list, it may modify entries
+in the database.
+.PP
+A principal is always granted authorization to change its own password.
+.SH FILES
+.TP 20n
+/kerberos/admin_server.syslog
+Default log file.
+.TP
+/kerberos
+Default access control list directory.
+.TP
+admin_acl.{add,get,mod}
+Access control list files (within the directory)
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+Default DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH "SEE ALSO"
+kerberos(1), kpasswd(1), kadmin(8), acl_check(3)
+.SH AUTHORS
+Douglas A. Church, MIT Project Athena
+.br
+John T. Kohl, Project Athena/Digital Equipment Corporation
diff --git a/eBones/kdb/Makefile b/eBones/kdb/Makefile
new file mode 100644
index 0000000..b69c0d9
--- /dev/null
+++ b/eBones/kdb/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.3 1994/09/09 21:43:41 g89r4222 Exp $
+
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+
+LIB= kdb
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c
+
+.include <bsd.lib.mk>
diff --git a/eBones/kdb/krb_cache.c b/eBones/kdb/krb_cache.c
new file mode 100644
index 0000000..4d8c594
--- /dev/null
+++ b/eBones/kdb/krb_cache.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This is where a cache would be implemented, if it were necessary.
+ *
+ * from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $
+ * $Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+extern char *strncpy();
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+#endif
+static init = 0;
+
+/*
+ * initialization routine for cache
+ */
+
+int
+kerb_cache_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * look up a principal in the cache returns number of principals found
+ */
+
+int
+kerb_cache_get_principal(serv, inst, principal, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+ u_long i;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "cache_get_principal for %s %s max = %d\n",
+ serv, inst, max);
+#endif DEBUG
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+ serv, inst, principal->name, principal->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv,
+ inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a principal in the cache returns number of principals
+ * inserted
+ */
+
+int
+kerb_cache_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* max number of principal structs to
+ * insert */
+
+{
+ int found = 0;
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_principal max = %d",
+ max);
+ }
+#endif
+
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ principal->name, principal->instance);
+#endif
+ /* DO IT */
+ count++;
+ principal++;
+ }
+ return count;
+}
+
+/*
+ * look up a dba in the cache returns number of dbas found
+ */
+
+int
+kerb_cache_get_dba(serv, inst, dba, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+ u_long i;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "cache_get_dba for %s %s max = %d\n",
+ serv, inst, max);
+#endif
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+ serv, inst, dba->name, dba->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv, inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a dba in the cache returns number of dbas inserted
+ */
+
+int
+kerb_cache_put_dba(dba, max)
+ Dba *dba;
+ unsigned int max; /* max number of dba structs to insert */
+
+{
+ int found = 0;
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_dba max = %d", max);
+ }
+#endif
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ dba->name, dba->instance);
+#endif
+ /* DO IT */
+ count++;
+ dba++;
+ }
+ return count;
+}
+
diff --git a/eBones/kdb/krb_dbl.c b/eBones/kdb/krb_dbl.c
new file mode 100644
index 0000000..7776298
--- /dev/null
+++ b/eBones/kdb/krb_dbl.c
@@ -0,0 +1 @@
+This file is now obsolete.
diff --git a/eBones/kdb/krb_dbm.c b/eBones/kdb/krb_dbm.c
new file mode 100644
index 0000000..754dd68
--- /dev/null
+++ b/eBones/kdb/krb_dbm.c
@@ -0,0 +1,741 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $
+ * $Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $";
+#endif lint
+
+#if defined(__FreeBSD__)
+#define NDBM
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/errno.h>
+#include <strings.h>
+#include <des.h>
+#include <sys/file.h>
+#ifdef NDBM
+#include <ndbm.h>
+#else /*NDBM*/
+#include <dbm.h>
+#endif /*NDBM*/
+/* before krb_db.h */
+#include <krb.h>
+#include <krb_db.h>
+
+#define KERB_DB_MAX_RETRY 5
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+extern char *progname;
+#endif
+extern char *malloc();
+extern int errno;
+
+static init = 0;
+static char default_db_name[] = DBM_FILE;
+static char *current_db_name = default_db_name;
+static void encode_princ_key(), decode_princ_key();
+static void encode_princ_contents(), decode_princ_contents();
+static void kerb_dbl_fini();
+static int kerb_dbl_lock();
+static void kerb_dbl_unlock();
+
+static struct timeval timestamp;/* current time of request */
+static int non_blocking = 0;
+
+/*
+ * This module contains all of the code which directly interfaces to
+ * the underlying representation of the Kerberos database; this
+ * implementation uses a DBM or NDBM indexed "file" (actually
+ * implemented as two separate files) to store the relations, plus a
+ * third file as a semaphore to allow the database to be replaced out
+ * from underneath the KDC server.
+ */
+
+/*
+ * Locking:
+ *
+ * There are two distinct locking protocols used. One is designed to
+ * lock against processes (the admin_server, for one) which make
+ * incremental changes to the database; the other is designed to lock
+ * against utilities (kdb_util, kpropd) which replace the entire
+ * database in one fell swoop.
+ *
+ * The first locking protocol is implemented using flock() in the
+ * krb_dbl_lock() and krb_dbl_unlock routines.
+ *
+ * The second locking protocol is necessary because DBM "files" are
+ * actually implemented as two separate files, and it is impossible to
+ * atomically rename two files simultaneously. It assumes that the
+ * database is replaced only very infrequently in comparison to the time
+ * needed to do a database read operation.
+ *
+ * A third file is used as a "version" semaphore; the modification
+ * time of this file is the "version number" of the database.
+ * At the start of a read operation, the reader checks the version
+ * number; at the end of the read operation, it checks again. If the
+ * version number changed, or if the semaphore was nonexistant at
+ * either time, the reader sleeps for a second to let things
+ * stabilize, and then tries again; if it does not succeed after
+ * KERB_DB_MAX_RETRY attempts, it gives up.
+ *
+ * On update, the semaphore file is deleted (if it exists) before any
+ * update takes place; at the end of the update, it is replaced, with
+ * a version number strictly greater than the version number which
+ * existed at the start of the update.
+ *
+ * If the system crashes in the middle of an update, the semaphore
+ * file is not automatically created on reboot; this is a feature, not
+ * a bug, since the database may be inconsistant. Note that the
+ * absence of a semaphore file does not prevent another _update_ from
+ * taking place later. Database replacements take place automatically
+ * only on slave servers; a crash in the middle of an update will be
+ * fixed by the next slave propagation. A crash in the middle of an
+ * update on the master would be somewhat more serious, but this would
+ * likely be noticed by an administrator, who could fix the problem and
+ * retry the operation.
+ */
+
+/* Macros to convert ndbm names to dbm names.
+ * Note that dbm_nextkey() cannot be simply converted using a macro, since
+ * it is invoked giving the database, and nextkey() needs the previous key.
+ *
+ * Instead, all routines call "dbm_next" instead.
+ */
+
+#ifndef NDBM
+typedef char DBM;
+
+#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0))
+#define dbm_fetch(db, key) fetch(key)
+#define dbm_store(db, key, content, flag) store(key, content)
+#define dbm_firstkey(db) firstkey()
+#define dbm_next(db,key) nextkey(key)
+#define dbm_close(db) dbmclose()
+#else
+#define dbm_next(db,key) dbm_nextkey(db)
+#endif
+
+/*
+ * Utility routine: generate name of database file.
+ */
+
+static char *gen_dbsuffix(db_name, sfx)
+ char *db_name;
+ char *sfx;
+{
+ char *dbsuffix;
+
+ if (sfx == NULL)
+ sfx = ".ok";
+
+ dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
+ strcpy(dbsuffix, db_name);
+ strcat(dbsuffix, sfx);
+ return dbsuffix;
+}
+
+/*
+ * initialization for data base routines.
+ */
+
+kerb_db_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * gracefully shut down database--must be called by ANY program that does
+ * a kerb_db_init
+ */
+
+kerb_db_fini()
+{
+}
+
+/*
+ * Set the "name" of the current database to some alternate value.
+ *
+ * Passing a null pointer as "name" will set back to the default.
+ * If the alternate database doesn't exist, nothing is changed.
+ */
+
+kerb_db_set_name(name)
+ char *name;
+{
+ DBM *db;
+
+ if (name == NULL)
+ name = default_db_name;
+ db = dbm_open(name, 0, 0);
+ if (db == NULL)
+ return errno;
+ dbm_close(db);
+ kerb_dbl_fini();
+ current_db_name = name;
+ return 0;
+}
+
+/*
+ * Return the last modification time of the database.
+ */
+
+long kerb_get_db_age()
+{
+ struct stat st;
+ char *okname;
+ long age;
+
+ okname = gen_dbsuffix(current_db_name, ".ok");
+
+ if (stat (okname, &st) < 0)
+ age = 0;
+ else
+ age = st.st_mtime;
+
+ free (okname);
+ return age;
+}
+
+/*
+ * Remove the semaphore file; indicates that database is currently
+ * under renovation.
+ *
+ * This is only for use when moving the database out from underneath
+ * the server (for example, during slave updates).
+ */
+
+static long kerb_start_update(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ long age = kerb_get_db_age();
+
+ if (unlink(okname) < 0
+ && errno != ENOENT) {
+ age = -1;
+ }
+ free (okname);
+ return age;
+}
+
+static long kerb_end_update(db_name, age)
+ char *db_name;
+ long age;
+{
+ int fd;
+ int retval = 0;
+ char *new_okname = gen_dbsuffix(db_name, ".ok#");
+ char *okname = gen_dbsuffix(db_name, ".ok");
+
+ fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ retval = errno;
+ else {
+ struct stat st;
+ struct timeval tv[2];
+ /* make sure that semaphore is "after" previous value. */
+ if (fstat (fd, &st) == 0
+ && st.st_mtime <= age) {
+ tv[0].tv_sec = st.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = age;
+ tv[1].tv_usec = 0;
+ /* set times.. */
+ utimes (new_okname, tv);
+ fsync(fd);
+ }
+ close(fd);
+ if (rename (new_okname, okname) < 0)
+ retval = errno;
+ }
+
+ free (new_okname);
+ free (okname);
+
+ return retval;
+}
+
+static long kerb_start_read()
+{
+ return kerb_get_db_age();
+}
+
+static long kerb_end_read(age)
+ u_long age;
+{
+ if (kerb_get_db_age() != age || age == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Create the database, assuming it's not there.
+ */
+
+kerb_db_create(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ int fd;
+ register int ret = 0;
+#ifdef NDBM
+ DBM *db;
+
+ db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (db == NULL)
+ ret = errno;
+ else
+ dbm_close(db);
+#else
+ char *dirname = gen_dbsuffix(db_name, ".dir");
+ char *pagname = gen_dbsuffix(db_name, ".pag");
+
+ fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else {
+ close(fd);
+ fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else
+ close(fd);
+ }
+ if (dbminit(db_name) < 0)
+ ret = errno;
+#endif
+ if (ret == 0) {
+ fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ ret = errno;
+ close(fd);
+ }
+ return ret;
+}
+
+/*
+ * "Atomically" rename the database in a way that locks out read
+ * access in the middle of the rename.
+ *
+ * Not perfect; if we crash in the middle of an update, we don't
+ * necessarily know to complete the transaction the rename, but...
+ */
+
+kerb_db_rename(from, to)
+ char *from;
+ char *to;
+{
+ char *fromdir = gen_dbsuffix (from, ".dir");
+ char *todir = gen_dbsuffix (to, ".dir");
+ char *frompag = gen_dbsuffix (from , ".pag");
+ char *topag = gen_dbsuffix (to, ".pag");
+ char *fromok = gen_dbsuffix(from, ".ok");
+ long trans = kerb_start_update(to);
+ int ok;
+
+ if ((rename (fromdir, todir) == 0)
+ && (rename (frompag, topag) == 0)) {
+ (void) unlink (fromok);
+ ok = 1;
+ }
+
+ free (fromok);
+ free (fromdir);
+ free (todir);
+ free (frompag);
+ free (topag);
+ if (ok)
+ return kerb_end_update(to, trans);
+ else
+ return -1;
+}
+
+/*
+ * look up a principal in the data base returns number of principals
+ * found , and whether there were more than requested.
+ */
+
+kerb_db_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ int found = 0, code;
+ extern int errorproc();
+ int wildp, wildi;
+ datum key, contents;
+ char testname[ANAME_SZ], testinst[INST_SZ];
+ u_long trans;
+ int try;
+ DBM *db;
+
+ if (!init)
+ kerb_db_init(); /* initialize database routines */
+
+ for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
+ trans = kerb_start_read();
+
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return -1;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ *more = 0;
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr,
+ "%s: db_get_principal for %s %s max = %d",
+ progname, name, inst, max);
+#endif
+
+ wildp = !strcmp(name, "*");
+ wildi = !strcmp(inst, "*");
+
+ if (!wildi && !wildp) { /* nothing's wild */
+ encode_princ_key(&key, name, inst);
+ contents = dbm_fetch(db, key);
+ if (contents.dptr == NULL) {
+ found = 0;
+ goto done;
+ }
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ found = 1;
+ goto done;
+ }
+ /* process wild cards by looping through entire database */
+
+ for (key = dbm_firstkey(db); key.dptr != NULL;
+ key = dbm_next(db, key)) {
+ decode_princ_key(&key, testname, testinst);
+ if ((wildp || !strcmp(testname, name)) &&
+ (wildi || !strcmp(testinst, inst))) { /* have a match */
+ if (found >= max) {
+ *more = 1;
+ goto done;
+ } else {
+ found++;
+ contents = dbm_fetch(db, key);
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr,
+ "\tfound %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ principal++; /* point to next */
+ }
+ }
+ }
+
+ done:
+ kerb_dbl_unlock(); /* unlock read lock */
+ dbm_close(db);
+ if (kerb_end_read(trans) == 0)
+ break;
+ found = -1;
+ if (!non_blocking)
+ sleep(1);
+ }
+ return (found);
+}
+
+/*
+ * Update a name in the data base. Returns number of names
+ * successfully updated.
+ */
+
+kerb_db_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* number of principal structs to
+ * update */
+
+{
+ int found = 0, code;
+ u_long i;
+ extern int errorproc();
+ datum key, contents;
+ DBM *db;
+
+ gettimeofday(&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);
+}
+
+static void
+encode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ static char keystring[ANAME_SZ + INST_SZ];
+
+ bzero(keystring, ANAME_SZ + INST_SZ);
+ strncpy(keystring, name, ANAME_SZ);
+ strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
+ key->dptr = keystring;
+ key->dsize = ANAME_SZ + INST_SZ;
+}
+
+static void
+decode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ strncpy(name, key->dptr, ANAME_SZ);
+ strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
+ name[ANAME_SZ - 1] = '\0';
+ instance[INST_SZ - 1] = '\0';
+}
+
+static void
+encode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ contents->dsize = sizeof(*principal);
+ contents->dptr = (char *) principal;
+}
+
+static void
+decode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ bcopy(contents->dptr, (char *) principal, sizeof(*principal));
+}
+
+kerb_db_get_stat(s)
+ DB_stat *s;
+{
+ gettimeofday(&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 */
+}
+
+kerb_db_put_stat(s)
+ DB_stat *s;
+{
+}
+
+delta_stat(a, b, c)
+ DB_stat *a, *b, *c;
+{
+ /* c = a - b then b = a for the next time */
+
+ c->cpu = a->cpu - b->cpu;
+ c->elapsed = a->elapsed - b->elapsed;
+ c->dio = a->dio - b->dio;
+ c->pfault = a->pfault - b->pfault;
+ c->t_stamp = a->t_stamp - b->t_stamp;
+ c->n_retrieve = a->n_retrieve - b->n_retrieve;
+ c->n_replace = a->n_replace - b->n_replace;
+ c->n_append = a->n_append - b->n_append;
+ c->n_get_stat = a->n_get_stat - b->n_get_stat;
+ c->n_put_stat = a->n_put_stat - b->n_put_stat;
+
+ bcopy(a, b, sizeof(DB_stat));
+ return;
+}
+
+/*
+ * look up a dba in the data base returns number of dbas found , and
+ * whether there were more than requested.
+ */
+
+kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
+ char *dba_name; /* could have wild card */
+ char *dba_inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ *more = 0;
+ return (0);
+}
+
+kerb_db_iterate (func, arg)
+ int (*func)();
+ char *arg; /* void *, really */
+{
+ datum key, contents;
+ Principal *principal;
+ int code;
+ DBM *db;
+
+ kerb_db_init(); /* initialize and open the database */
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return code;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
+ contents = dbm_fetch (db, key);
+ /* XXX may not be properly aligned */
+ principal = (Principal *) contents.dptr;
+ if ((code = (*func)(arg, principal)) != 0)
+ return code;
+ }
+ dbm_close(db);
+ kerb_dbl_unlock();
+ return 0;
+}
+
+static int dblfd = -1;
+static int mylock = 0;
+static int inited = 0;
+
+static kerb_dbl_init()
+{
+ if (!inited) {
+ char *filename = gen_dbsuffix (current_db_name, ".ok");
+ if ((dblfd = open(filename, 0)) < 0) {
+ fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
+ fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+ free(filename);
+ inited++;
+ }
+ return (0);
+}
+
+static void kerb_dbl_fini()
+{
+ close(dblfd);
+ dblfd = -1;
+ inited = 0;
+ mylock = 0;
+}
+
+static int kerb_dbl_lock(mode)
+ int mode;
+{
+ int flock_mode;
+
+ if (!inited)
+ kerb_dbl_init();
+ if (mylock) { /* Detect lock call when lock already
+ * locked */
+ fprintf(stderr, "Kerberos locking error (mylock)\n");
+ fflush(stderr);
+ exit(1);
+ }
+ switch (mode) {
+ case KERB_DBL_EXCLUSIVE:
+ flock_mode = LOCK_EX;
+ break;
+ case KERB_DBL_SHARED:
+ flock_mode = LOCK_SH;
+ break;
+ default:
+ fprintf(stderr, "invalid lock mode %d\n", mode);
+ abort();
+ }
+ if (non_blocking)
+ flock_mode |= LOCK_NB;
+
+ if (flock(dblfd, flock_mode) < 0)
+ return errno;
+ mylock++;
+ return 0;
+}
+
+static void kerb_dbl_unlock()
+{
+ if (!mylock) { /* lock already unlocked */
+ fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
+ fflush(stderr);
+ exit(1);
+ }
+ if (flock(dblfd, LOCK_UN) < 0) {
+ fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
+ fflush(stderr);
+ perror("flock");
+ exit(1);
+ }
+ mylock = 0;
+}
+
+int kerb_db_set_lockmode(mode)
+ int mode;
+{
+ int old = non_blocking;
+ non_blocking = mode;
+ return old;
+}
diff --git a/eBones/kdb/krb_kdb_utils.c b/eBones/kdb/krb_kdb_utils.c
new file mode 100644
index 0000000..5fccc53
--- /dev/null
+++ b/eBones/kdb/krb_kdb_utils.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Utility routines for Kerberos programs which directly access
+ * the database. This code was duplicated in too many places
+ * before I gathered it here.
+ *
+ * Jon Rochlis, MIT Telecom, March 1988
+ *
+ * from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $
+ * $Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $";
+#endif lint
+
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <kdc.h>
+#include <stdio.h>
+#include <sys/file.h>
+
+long kdb_get_master_key(prompt, master_key, master_key_sched)
+ int prompt;
+ C_Block master_key;
+ Key_schedule master_key_sched;
+{
+ int kfile;
+
+ if (prompt) {
+#ifdef NOENCRYPTION
+ placebo_read_password(master_key,
+ "\nEnter Kerberos master key: ", 0);
+#else
+ des_read_password(master_key,
+ "\nEnter Kerberos master key: ", 0);
+#endif
+ printf ("\n");
+ }
+ else {
+ kfile = open(MKEYFILE, O_RDONLY, 0600);
+ if (kfile < 0) {
+ /* oh, for com_err_ */
+ return (-1);
+ }
+ if (read(kfile, (char *) master_key, 8) != 8) {
+ return (-1);
+ }
+ close(kfile);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(master_key,master_key_sched);
+#endif
+ return (0);
+}
+
+/* The caller is reasponsible for cleaning up the master key and sched,
+ even if we can't verify the master key */
+
+/* Returns master key version if successful, otherwise -1 */
+
+long kdb_verify_master_key (master_key, master_key_sched, out)
+ C_Block master_key;
+ Key_schedule master_key_sched;
+ FILE *out; /* setting this to non-null be do output */
+{
+ C_Block key_from_db;
+ Principal principal_data[1];
+ int n, more = 0;
+ long master_key_version;
+
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ if (out != (FILE *) NULL)
+ fprintf(out,
+ "verify_master_key: %s, %d found.\n",
+ "Kerberos error on master key version lookup",
+ n);
+ return (-1);
+ }
+
+ master_key_version = (long) principal_data[0].key_version;
+
+ /* set up the master key */
+ if (out != (FILE *) NULL) /* should we punt this? */
+ fprintf(out, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt the key in the db, had better
+ * be the same!
+ */
+ bcopy(&principal_data[0].key_low, key_from_db, 4);
+ bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
+ kdb_encrypt_key (key_from_db, key_from_db,
+ master_key, master_key_sched, DECRYPT);
+
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ /* this used to zero the master key here! */
+ bzero(key_from_db, sizeof(key_from_db));
+ bzero(principal_data, sizeof (principal_data));
+
+ if (n && (out != (FILE *) NULL)) {
+ fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
+ fprintf(out, "does not match database.\n");
+ return (-1);
+ }
+ if (out != (FILE *) NULL) {
+ fprintf(out, "\nMaster key entered. BEWARE!\07\07\n");
+ fflush(out);
+ }
+
+ return (master_key_version);
+}
+
+/* The old algorithm used the key schedule as the initial vector which
+ was byte order depedent ... */
+
+kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
+ C_Block in, out, master_key;
+ Key_schedule master_key_sched;
+ int e_d_flag;
+{
+
+#ifdef NOENCRYPTION
+ bcopy(in, out, sizeof(C_Block));
+#else
+ pcbc_encrypt(in,out,(long)sizeof(C_Block),master_key_sched,master_key,
+ e_d_flag);
+#endif
+}
diff --git a/eBones/kdb/krb_lib.c b/eBones/kdb/krb_lib.c
new file mode 100644
index 0000000..f0f1f6f
--- /dev/null
+++ b/eBones/kdb/krb_lib.c
@@ -0,0 +1,242 @@
+/*
+ * $Source: /home/CVS/src/eBones/kdb/krb_lib.c,v $
+ * $Author: g89r4222 $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_lib.c,v 1.2 1994/07/19 19:23:39 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#ifdef DEBUG
+extern int debug;
+extern char *progname;
+long kerb_debug;
+#endif
+
+extern char *strncpy();
+extern char *ctime();
+extern char *getenv();
+
+static init = 0;
+
+/*
+ * initialization routine for data base
+ */
+
+int
+kerb_init()
+{
+#ifdef DEBUG
+ if (!init) {
+ char *dbg = getenv("KERB_DBG");
+ if (dbg)
+ sscanf(dbg, "%d", &kerb_debug);
+ init = 1;
+ }
+#endif
+ kerb_db_init();
+
+#ifdef CACHE
+ kerb_cache_init();
+#endif
+
+ /* successful init, return 0, else errcode */
+ return (0);
+}
+
+/*
+ * finalization routine for database -- NOTE: MUST be called by any
+ * program using kerb_init. ALSO will have to be modified to finalize
+ * caches, if they're ever really implemented.
+ */
+
+int
+kerb_fini()
+{
+ kerb_db_fini();
+}
+
+/*
+ * look up a principal in the cache or data base returns number of
+ * principals found
+ */
+
+int
+kerb_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the principal area */
+ bzero((char *) principal, max * sizeof(Principal));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_principal(name, inst, principal, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_principal(name, inst, principal, max, more);
+ /* try to insert principal(s) into cache if it was found */
+#ifdef CACHE
+ if (found) {
+ kerb_cache_put_principal(principal, found);
+ }
+#endif
+ return (found);
+}
+
+/* principals */
+kerb_put_principal(principal, n)
+ Principal *principal;
+ unsigned int n; /* number of principal structs to write */
+{
+ long time();
+ struct tm *tp, *localtime();
+
+ /* set mod date */
+ principal->mod_date = time((long *)0);
+ /* and mod date string */
+
+ tp = localtime(&principal->mod_date);
+ (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ int i;
+ fprintf(stderr, "\nkerb_put_principal...");
+ for (i = 0; i < n; i++) {
+ krb_print_principal(&principal[i]);
+ }
+ }
+#endif
+ /* write database */
+ if (kerb_db_put_principal(principal, n) < 0) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_db_put_principal err", progname);
+ /* watch out for cache */
+#endif
+ return -1;
+ }
+#ifdef CACHE
+ /* write cache */
+ if (!kerb_cache_put_principal(principal, n)) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname);
+#endif
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int
+kerb_get_dba(name, inst, dba, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the dba area */
+ bzero((char *) dba, max * sizeof(Dba));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_dba(name, inst, dba, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_dba(name, inst, dba, max, more);
+#ifdef CACHE
+ /* try to insert dba(s) into cache if it was found */
+ if (found) {
+ kerb_cache_put_dba(dba, found);
+ }
+#endif
+ return (found);
+}
diff --git a/eBones/kdb/print_princ.c b/eBones/kdb/print_princ.c
new file mode 100644
index 0000000..730cfb7
--- /dev/null
+++ b/eBones/kdb/print_princ.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: $Header: /home/CVS/src/eBones/kdb/print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $
+ * $Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <strings.h>
+#include <krb.h>
+#include <krb_db.h>
+
+extern int debug;
+extern char *strncpy();
+extern char *ctime();
+extern struct tm *localtime();
+struct tm *time_p;
+
+long kerb_debug;
+
+krb_print_principal(a_n)
+ Principal *a_n;
+{
+ /* run-time database does not contain string versions */
+ time_p = localtime(&(a_n->exp_date));
+
+ fprintf(stderr,
+ "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x",
+ a_n->name, a_n->instance,
+ time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900,
+ time_p->tm_mon + 1, time_p->tm_mday,
+ time_p->tm_hour, time_p->tm_min,
+ a_n->max_life, 5 * a_n->max_life, a_n->attributes);
+
+ fprintf(stderr,
+ "\n\tkey_ver %d k_low 0x%08x k_high 0x%08x akv %d exists %d\n",
+ a_n->key_version, a_n->key_low, a_n->key_high,
+ a_n->kdc_key_ver, a_n->old);
+
+ fflush(stderr);
+}
diff --git a/eBones/kdb_destroy/Makefile b/eBones/kdb_destroy/Makefile
new file mode 100644
index 0000000..a48805b
--- /dev/null
+++ b/eBones/kdb_destroy/Makefile
@@ -0,0 +1,8 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:23:46 g89r4222 Exp $
+
+PROG= kdb_destroy
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kdb_destroy/kdb_destroy.8 b/eBones/kdb_destroy/kdb_destroy.8
new file mode 100644
index 0000000..93db466
--- /dev/null
+++ b/eBones/kdb_destroy/kdb_destroy.8
@@ -0,0 +1,33 @@
+.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $
+.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_destroy \- destroy Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_destroy
+.SH DESCRIPTION
+.I kdb_destroy
+deletes a Kerberos key distribution center database.
+.PP
+The user is prompted to verify that the database should be destroyed. A
+response beginning with `y' or `Y' confirms deletion.
+Any other response aborts deletion.
+.SH DIAGNOSTICS
+.TP 20n
+"Database cannot be deleted at /kerberos/principal"
+The attempt to delete the database failed (probably due to a system or
+access permission error).
+.TP
+"Database not deleted."
+The user aborted the deletion.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.SH SEE ALSO
+kdb_init(8)
diff --git a/eBones/kdb_destroy/kdb_destroy.c b/eBones/kdb_destroy/kdb_destroy.c
new file mode 100644
index 0000000..0c45896
--- /dev/null
+++ b/eBones/kdb_destroy/kdb_destroy.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $
+ * $Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $";
+#endif lint
+
+#include <strings.h>
+#include <stdio.h>
+#include "krb.h"
+#include "krb_db.h"
+
+main()
+{
+ char answer[10]; /* user input */
+ char dbm[256]; /* database path and name */
+ char dbm1[256]; /* database path and name */
+ char *file1, *file2; /* database file names */
+
+ strcpy(dbm, DBM_FILE);
+ strcpy(dbm1, DBM_FILE);
+ file1 = strcat(dbm, ".dir");
+ file2 = strcat(dbm1, ".pag");
+
+ printf("You are about to destroy the Kerberos database ");
+ printf("on this machine.\n");
+ printf("Are you sure you want to do this (y/n)? ");
+ fgets(answer, sizeof(answer), stdin);
+
+ if (answer[0] == 'y' || answer[0] == 'Y') {
+ if (unlink(file1) == 0 && unlink(file2) == 0)
+ fprintf(stderr, "Database deleted at %s\n", DBM_FILE);
+ else
+ fprintf(stderr, "Database cannot be deleted at %s\n",
+ DBM_FILE);
+ } else
+ fprintf(stderr, "Database not deleted.\n");
+}
diff --git a/eBones/kdb_edit/Makefile b/eBones/kdb_edit/Makefile
new file mode 100644
index 0000000..65a5e5a
--- /dev/null
+++ b/eBones/kdb_edit/Makefile
@@ -0,0 +1,12 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $
+
+PROG= kdb_edit
+CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include
+SRCS= kdb_edit.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kdb_edit/kdb_edit.8 b/eBones/kdb_edit/kdb_edit.8
new file mode 100644
index 0000000..1cfd6ed
--- /dev/null
+++ b/eBones/kdb_edit/kdb_edit.8
@@ -0,0 +1,55 @@
+.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $
+.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_edit \- Kerberos key distribution center database editing utility
+.SH SYNOPSIS
+kdb_edit [
+.B \-n
+]
+.SH DESCRIPTION
+.I kdb_edit
+is used to create or change principals stored in the Kerberos key
+distribution center (KDC) database.
+.PP
+When executed,
+.I kdb_edit
+prompts for the master key string and verifies that it matches the
+master key stored in the database.
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+Once the master key has been verified,
+.I kdb_edit
+begins a prompt loop. The user is prompted for the principal and
+instance to be modified. If the entry is not found the user may create
+it.
+Once an entry is found or created, the user may set the password,
+expiration date, maximum ticket lifetime, and attributes.
+Default expiration dates, maximum ticket lifetimes, and attributes are
+presented in brackets; if the user presses return the default is selected.
+There is no default password.
+The password RANDOM is interpreted specially, and if entered
+the user may have the program select a random DES key for the
+principal.
+.PP
+Upon successfully creating or changing the entry, ``Edit O.K.'' is
+printed.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/kdb_edit/kdb_edit.c b/eBones/kdb_edit/kdb_edit.c
new file mode 100644
index 0000000..4c02db6
--- /dev/null
+++ b/eBones/kdb_edit/kdb_edit.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services.
+ *
+ * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
+ * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $
+ */
+
+/*
+ * exit returns 0 ==> success -1 ==> error
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include "time.h"
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+/* MKEYFILE is now defined in kdc.h */
+#include <kdc.h>
+
+extern char *errmsg();
+extern int errno;
+extern char *strcpy();
+
+void sig_exit();
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+char prog[32];
+char *progname = prog;
+int nflag = 0;
+int cflag;
+int lflag;
+int uflag;
+int debug;
+extern kerb_debug;
+
+Key_schedule KS;
+C_Block new_key;
+unsigned char *input;
+
+unsigned char *ivec;
+int i, j;
+int more;
+
+char *in_ptr;
+char input_name[ANAME_SZ];
+char input_instance[INST_SZ];
+char input_string[ANAME_SZ];
+
+#define MAX_PRINCIPAL 10
+Principal principal_data[MAX_PRINCIPAL];
+
+static Principal old_principal;
+static Principal default_princ;
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+static char pw_str[255];
+static long master_key_version;
+
+/*
+ * gets replacement
+ */
+static char * s_gets(char * str, int len)
+{
+ int i;
+ char *s;
+
+ if((s = fgets(str, len, stdin)) == NULL)
+ return(s);
+ if(str[i = (strlen(str)-1)] == '\n')
+ str[i] = '\0';
+ return(s);
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ /* Local Declarations */
+
+ long n;
+
+ prog[sizeof prog - 1] = '\0'; /* make sure terminated */
+ strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
+ * program */
+
+ /* Assume a long is four bytes */
+ if (sizeof(long) != 4) {
+ fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
+ exit(-1);
+ }
+ /* Assume <=32 signals */
+ if (NSIG > 32) {
+ fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
+ exit(-1);
+ }
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i = 1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ debug = 1;
+ continue;
+
+ /* debug flag */
+ case 'l':
+ kerb_debug |= 1;
+ continue;
+
+ case 'n': /* read MKEYFILE for master key */
+ nflag = 1;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: illegal flag \"%c\"\n",
+ progname, argv[0][i]);
+ Usage(); /* Give message and die */
+ }
+ };
+
+ fprintf(stdout, "Opening database...\n");
+ fflush(stdout);
+ kerb_init();
+ if (argc > 0) {
+ if (kerb_db_set_name(*argv) != 0) {
+ fprintf(stderr, "Could not open altername database name\n");
+ exit(1);
+ }
+ }
+
+#ifdef notdef
+ no_core_dumps(); /* diddle signals to avoid core dumps! */
+
+ /* ignore whatever is reasonable */
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+
+#endif
+
+ if (kdb_get_master_key ((nflag == 0),
+ master_key, master_key_schedule) != 0) {
+ fprintf (stdout, "Couldn't read master key.\n");
+ fflush (stdout);
+ exit (-1);
+ }
+
+ if ((master_key_version = kdb_verify_master_key(master_key,
+ master_key_schedule,
+ stdout)) < 0)
+ exit (-1);
+
+ /* lookup the default values */
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (n != 1) {
+ fprintf(stderr,
+ "%s: Kerberos error on default value lookup, %d found.\n",
+ progname, n);
+ exit(-1);
+ }
+ fprintf(stdout, "Previous or default values are in [brackets] ,\n");
+ fprintf(stdout, "enter return to leave the same, or new value.\n");
+
+ while (change_principal()) {
+ }
+
+ cleanup();
+}
+
+change_principal()
+{
+ static char temp[255];
+ int creating = 0;
+ int editpw = 0;
+ int changed = 0;
+ long temp_long;
+ int n;
+ struct tm *tp, edate, *localtime();
+ long maketime();
+
+ fprintf(stdout, "\nPrincipal name: ");
+ fflush(stdout);
+ if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0')
+ return 0;
+ fprintf(stdout, "Instance: ");
+ fflush(stdout);
+ /* instance can be null */
+ s_gets(input_instance, INST_SZ-1);
+ j = kerb_get_principal(input_name, input_instance, principal_data,
+ MAX_PRINCIPAL, &more);
+ if (!j) {
+ fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
+ s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */
+ if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
+ return -1;
+ /* make a new principal, fill in defaults */
+ j = 1;
+ creating = 1;
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+ principal_data[0].exp_date = default_princ.exp_date;
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
+ principal_data[0].key_version = 0; /* bumped up later */
+ }
+ tp = localtime(&principal_data[0].exp_date);
+ (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+ for (i = 0; i < j; i++) {
+ for (;;) {
+ fprintf(stdout,
+ "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
+ principal_data[i].name, principal_data[i].instance,
+ principal_data[i].kdc_key_ver);
+ editpw = 1;
+ changed = 0;
+ if (!creating) {
+ /*
+ * copy the existing data so we can use the old values
+ * for the qualifier clause of the replace
+ */
+ principal_data[i].old = (char *) &old_principal;
+ bcopy(&principal_data[i], &old_principal,
+ sizeof(old_principal));
+ printf("\nChange password [n] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (strcmp("y", temp) && strcmp("Y", temp))
+ editpw = 0;
+ }
+ /* password */
+ if (editpw) {
+#ifdef NOENCRYPTION
+ placebo_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#else
+ des_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#endif
+ if (!strcmp(pw_str, "RANDOM")) {
+ printf("\nRandom password [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "RANDOM" */
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+ } else if (!strcmp(pw_str, "NULL")) {
+ printf("\nNull Key [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "NULL" */
+ } else {
+
+ principal_data[i].key_low = 0;
+ principal_data[i].key_high = 0;
+ goto null_key;
+ }
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str,new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+
+ /* seal it under the kerberos master key */
+ kdb_encrypt_key (new_key, new_key,
+ master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal_data[i].key_low, 4);
+ bcopy(((long *) new_key) + 1,
+ &principal_data[i].key_high, 4);
+ bzero(new_key, sizeof(new_key));
+ null_key:
+ /* set master key version */
+ principal_data[i].kdc_key_ver =
+ (unsigned char) master_key_version;
+ /* bump key version # */
+ principal_data[i].key_version++;
+ fprintf(stdout,
+ "\nPrincipal's new key version = %d\n",
+ principal_data[i].key_version);
+ fflush(stdout);
+ changed = 1;
+ }
+ /* expiration date */
+ fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) >
+ sizeof(principal_data[0].exp_date_txt))) {
+ bad_date:
+ fprintf(stdout, "\07\07Date Invalid\n");
+ fprintf(stdout,
+ "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ }
+
+ if (*temp) {
+ if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
+ &edate.tm_mon, &edate.tm_mday) != 3)
+ goto bad_date;
+ (void) strcpy(principal_data[i].exp_date_txt, temp);
+ edate.tm_mon--; /* January is 0, not 1 */
+ edate.tm_hour = 23; /* nearly midnight at the end of the */
+ edate.tm_min = 59; /* specified day */
+ if (!(principal_data[i].exp_date = maketime(&edate, 1)))
+ goto bad_date;
+ changed = 1;
+ }
+
+ /* maximum lifetime */
+ fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_life;
+ if (temp_long > 255 || (temp_long < 0)) {
+ bad_life:
+ fprintf(stdout, "\07\07Invalid, choose 0-255\n");
+ fprintf(stdout,
+ "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].max_life = (unsigned short) temp_long;
+ break;
+ }
+
+ /* attributes */
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_att;
+ if (temp_long > 65535 || (temp_long < 0)) {
+ bad_att:
+ fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].attributes =
+ (unsigned short) temp_long;
+ break;
+ }
+
+ /*
+ * remaining fields -- key versions and mod info, should
+ * not be directly manipulated
+ */
+ if (changed) {
+ if (kerb_put_principal(&principal_data[i], 1)) {
+ fprintf(stdout,
+ "\nError updating Kerberos database");
+ } else {
+ fprintf(stdout, "Edit O.K.");
+ }
+ } else {
+ fprintf(stdout, "Unchanged");
+ }
+
+
+ bzero(&principal_data[i].key_low, 4);
+ bzero(&principal_data[i].key_high, 4);
+ fflush(stdout);
+ break;
+ }
+ }
+ if (more) {
+ fprintf(stdout, "\nThere were more tuples found ");
+ fprintf(stdout, "than there were space for");
+ }
+ return 1;
+}
+
+
+no_core_dumps()
+{
+
+ signal(SIGQUIT, sig_exit);
+ signal(SIGILL, sig_exit);
+ signal(SIGTRAP, sig_exit);
+ signal(SIGIOT, sig_exit);
+ signal(SIGEMT, sig_exit);
+ signal(SIGFPE, sig_exit);
+ signal(SIGBUS, sig_exit);
+ signal(SIGSEGV, sig_exit);
+ signal(SIGSYS, sig_exit);
+}
+
+void
+sig_exit(sig, code, scp)
+ int sig, code;
+ struct sigcontext *scp;
+{
+ cleanup();
+ fprintf(stderr,
+ "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
+ sig, code, scp->sc_pc);
+ exit(-1);
+}
+
+
+cleanup()
+{
+
+ bzero(master_key, sizeof(master_key));
+ bzero(session_key, sizeof(session_key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(principal_data, sizeof(principal_data));
+ bzero(new_key, sizeof(new_key));
+ bzero(pw_str, sizeof(pw_str));
+}
+Usage()
+{
+ fprintf(stderr, "Usage: %s [-n]\n", progname);
+ exit(1);
+}
diff --git a/eBones/kdb_edit/maketime.c b/eBones/kdb_edit/maketime.c
new file mode 100644
index 0000000..057ecc3
--- /dev/null
+++ b/eBones/kdb_edit/maketime.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Convert a struct tm * to a UNIX time.
+ *
+ * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $
+ * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp ";
+#endif lint
+
+#include <sys/time.h>
+
+#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define SECSPERDAY 24*60*60
+#define SECSPERHOUR 60*60
+#define SECSPERMIN 60
+
+static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+ 365};
+
+static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+long
+maketime(tp, local)
+register struct tm *tp;
+int local;
+{
+ register long retval;
+ int foo;
+ int *marray;
+
+ if (tp->tm_mon < 0 || tp->tm_mon > 11 ||
+ tp->tm_hour < 0 || tp->tm_hour > 23 ||
+ tp->tm_min < 0 || tp->tm_min > 59 ||
+ tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */
+ return 0;
+
+ retval = 0;
+ if (tp->tm_year < 1900)
+ foo = tp->tm_year + 1900;
+ else
+ foo = tp->tm_year;
+
+ if (foo < 1901 || foo > 2038) /* year is too small/large */
+ return 0;
+
+ if (daysinyear(foo) == 366) {
+ if (tp->tm_mon > 1)
+ retval+= SECSPERDAY; /* add leap day */
+ marray = leapyear;
+ } else
+ marray = nonleapyear;
+
+ if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon])
+ return 0; /* out of range */
+
+ while (--foo >= 1970)
+ retval += daysinyear(foo) * SECSPERDAY;
+
+ retval += cumdays[tp->tm_mon] * SECSPERDAY;
+ retval += (tp->tm_mday-1) * SECSPERDAY;
+ retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec;
+
+ if (local) {
+ /* need to use local time, so we retrieve timezone info */
+ struct timezone tz;
+ struct timeval tv;
+ if (gettimeofday(&tv, &tz) < 0) {
+ /* some error--give up? */
+ return(retval);
+ }
+ retval += tz.tz_minuteswest * SECSPERMIN;
+ }
+ return(retval);
+}
diff --git a/eBones/kdb_edit/time.h b/eBones/kdb_edit/time.h
new file mode 100644
index 0000000..ed128d8
--- /dev/null
+++ b/eBones/kdb_edit/time.h
@@ -0,0 +1,45 @@
+/* Structure for use by time manipulating subroutines.
+ * The following library routines use it:
+ * libc: ctime, localtime, gmtime, asctime
+ * libcx: partime, maketime (may not be installed yet)
+ */
+
+/*
+ * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $
+ * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $
+ */
+
+struct tm { /* See defines below for allowable ranges */
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ int tm_zon; /* NEW: mins westward of Greenwich */
+ int tm_ampm; /* NEW: 1 if AM, 2 if PM */
+};
+
+#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/
+#define TMNULL (-1) /* Items not specified are given this value
+ * in order to distinguish null specs from zero
+ * specs. This is only used by partime and
+ * maketime. */
+
+ /* Indices into TM structure */
+#define TM_SEC 0 /* 0-59 */
+#define TM_MIN 1 /* 0-59 */
+#define TM_HOUR 2 /* 0-23 */
+#define TM_MDAY 3 /* 1-31 day of month */
+#define TM_DAY TM_MDAY /* " synonym */
+#define TM_MON 4 /* 0-11 */
+#define TM_YEAR 5 /* (year-1900) (year) */
+#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */
+#define TM_YDAY 7 /* 0-365 day of year */
+#define TM_ISDST 8 /* 0 Std, 1 DST */
+ /* New stuff */
+#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */
+#define TM_AMPM 10 /* 1 AM, 2 PM */
diff --git a/eBones/kdb_init/Makefile b/eBones/kdb_init/Makefile
new file mode 100644
index 0000000..ce51a9f
--- /dev/null
+++ b/eBones/kdb_init/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:03 g89r4222 Exp $
+
+PROG= kdb_init
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kdb_init/kdb_init.8 b/eBones/kdb_init/kdb_init.8
new file mode 100644
index 0000000..54537ad
--- /dev/null
+++ b/eBones/kdb_init/kdb_init.8
@@ -0,0 +1,41 @@
+.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $
+.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_init \- Initialize Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_init [
+.B realm
+]
+.SH DESCRIPTION
+.I kdb_init
+initializes a Kerberos key distribution center database, creating the
+necessary principals.
+.PP
+If the optional
+.I realm
+argument is not present,
+.I kdb_init
+prompts for a realm name (defaulting to the definition in /usr/include/krb.h).
+After determining the realm to be created, it prompts for
+a master key password. The master key password is used to encrypt
+every encryption key stored in the database.
+.SH DIAGNOSTICS
+.TP 20n
+"/kerberos/principal: File exists"
+An attempt was made to create a database on a machine which already had
+an existing database.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/usr/include/krb.h
+Include file defining default realm
+.SH SEE ALSO
+kdb_destroy(8)
diff --git a/eBones/kdb_init/kdb_init.c b/eBones/kdb_init/kdb_init.c
new file mode 100644
index 0000000..dc7055e
--- /dev/null
+++ b/eBones/kdb_init/kdb_init.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * program to initialize the database, reports error if database file
+ * already exists.
+ *
+ * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $
+ * $Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <string.h>
+
+#define TRUE 1
+
+enum ap_op {
+ NULL_KEY, /* setup null keys */
+ MASTER_KEY, /* use master key as new key */
+ RANDOM_KEY, /* choose a random key */
+};
+
+int debug = 0;
+char *progname, *rindex();
+C_Block master_key;
+Key_schedule master_key_schedule;
+
+main(argc, argv)
+ char *argv[];
+{
+ char realm[REALM_SZ];
+ char *cp;
+ int code;
+ char *database;
+
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ if (argc > 3) {
+ fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
+ exit(1);
+ }
+ if (argc == 3) {
+ database = argv[2];
+ --argc;
+ } else
+ database = DBM_FILE;
+
+ /* Do this first, it'll fail if the database exists */
+ if ((code = kerb_db_create(database)) != 0) {
+ fprintf(stderr, "Couldn't create database: %s\n",
+ sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(database);
+
+ if (argc == 2)
+ strncpy(realm, argv[1], REALM_SZ);
+ else {
+ fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM);
+ if (fgets(realm, sizeof(realm), stdin) == NULL) {
+ fprintf(stderr, "\nEOF reading realm\n");
+ exit(1);
+ }
+ if (cp = index(realm, '\n'))
+ *cp = '\0';
+ if (!*realm) /* no realm given */
+ strcpy(realm, KRB_REALM);
+ }
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n",
+ progname, realm);
+ exit(1);
+ }
+ printf("You will be prompted for the database Master Password.\n");
+ printf("It is important that you NOT FORGET this password.\n");
+ fflush(stdout);
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ exit (-1);
+ }
+
+ if (
+ add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) ||
+ add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) ||
+ add_principal("krbtgt", realm, RANDOM_KEY) ||
+ add_principal("changepw", KRB_MASTER, RANDOM_KEY)
+ ) {
+ fprintf(stderr, "\n%s: couldn't initialize database.\n",
+ progname);
+ exit(1);
+ }
+
+ /* play it safe */
+ bzero (master_key, sizeof (C_Block));
+ bzero (master_key_schedule, sizeof (Key_schedule));
+ exit(0);
+}
+
+/* use a return code to indicate success or failure. check the return */
+/* values of the routines called by this routine. */
+
+add_principal(name, instance, aap_op)
+ char *name, *instance;
+ enum ap_op aap_op;
+{
+ Principal principal;
+ char datestring[50];
+ char pw_str[255];
+ void read_pw_string();
+ void string_to_key();
+ void random_key();
+ struct tm *tm, *localtime();
+ C_Block new_key;
+
+ bzero(&principal, sizeof(principal));
+ strncpy(principal.name, name, ANAME_SZ);
+ strncpy(principal.instance, instance, INST_SZ);
+ switch (aap_op) {
+ case NULL_KEY:
+ principal.key_low = 0;
+ principal.key_high = 0;
+ break;
+ case RANDOM_KEY:
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ case MASTER_KEY:
+ bcopy (master_key, new_key, sizeof (C_Block));
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ }
+ principal.exp_date = 946702799; /* Happy new century */
+ strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ);
+ principal.mod_date = time(0);
+
+ tm = localtime(&principal.mod_date);
+ principal.attributes = 0;
+ principal.max_life = 255;
+
+ principal.kdc_key_ver = 1;
+ principal.key_version = 1;
+
+ strncpy(principal.mod_name, "db_creation", ANAME_SZ);
+ strncpy(principal.mod_instance, "", INST_SZ);
+ principal.old = 0;
+
+ kerb_db_put_principal(&principal, 1);
+
+ /* let's play it safe */
+ bzero (new_key, sizeof (C_Block));
+ bzero (&principal.key_low, 4);
+ bzero (&principal.key_high, 4);
+ return 0;
+}
diff --git a/eBones/kdb_util/Makefile b/eBones/kdb_util/Makefile
new file mode 100644
index 0000000..b3513d6
--- /dev/null
+++ b/eBones/kdb_util/Makefile
@@ -0,0 +1,13 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.2 1994/07/19 19:24:09 g89r4222 Exp $
+
+PROG= kdb_util
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../kdb_edit \
+ -I${.CURDIR}/../include
+SRCS= kdb_util.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kdb_util/kdb_util.8 b/eBones/kdb_util/kdb_util.8
new file mode 100644
index 0000000..30a3b9f
--- /dev/null
+++ b/eBones/kdb_util/kdb_util.8
@@ -0,0 +1,64 @@
+.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $
+.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_util \- Kerberos key distribution center database utility
+.SH SYNOPSIS
+kdb_util
+.B operation filename
+.SH DESCRIPTION
+.I kdb_util
+allows the Kerberos key distribution center (KDC) database administrator to
+perform utility functions on the database.
+.PP
+.I Operation
+must be one of the following:
+.TP 10n
+.I load
+initializes the KDC database with the records described by the
+text contained in the file
+.IR filename .
+Any existing database is overwritten.
+.TP
+.I dump
+dumps the KDC database into a text representation in the file
+.IR filename .
+.TP
+.I slave_dump
+performs a database dump like the
+.I dump
+operation, and additionally creates a semaphore file signalling the
+propagation software that an update is available for distribution to
+slave KDC databases.
+.TP
+.I new_master_key
+prompts for the old and new master key strings, and then dumps the KDC
+database into a text representation in the file
+.IR filename .
+The keys in the text representation are encrypted in the new master key.
+.TP
+.I convert_old_db
+prompts for the master key string, and then dumps the KDC database into
+a text representation in the file
+.IR filename .
+The existing database is assumed to be encrypted using the old format
+(encrypted by the key schedule of the master key); the dumped database
+is encrypted using the new format (encrypted directly with master key).
+.PP
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+.IR filename .ok
+semaphore file created by
+.IR slave_dump.
diff --git a/eBones/kdb_util/kdb_util.c b/eBones/kdb_util/kdb_util.c
new file mode 100644
index 0000000..8465b5b
--- /dev/null
+++ b/eBones/kdb_util/kdb_util.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Kerberos database manipulation utility. This program allows you to
+ * dump a kerberos database to an ascii readable file and load this
+ * file into the database. Read locking of the database is done during a
+ * dump operation. NO LOCKING is done during a load operation. Loads
+ * should happen with other processes shutdown.
+ *
+ * Written July 9, 1987 by Jeffrey I. Schiller
+ *
+ * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $
+ * $Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "time.h"
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <krb_db.h>
+
+#define TRUE 1
+
+Principal aprinc;
+
+static des_cblock master_key, new_master_key;
+static des_key_schedule master_key_schedule, new_master_key_schedule;
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+extern long kdb_get_master_key(), kdb_verify_master_key();
+extern char *malloc();
+extern int errno;
+
+char * progname;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *file;
+ enum {
+ OP_LOAD,
+ OP_DUMP,
+ OP_SLAVE_DUMP,
+ OP_NEW_MASTER,
+ OP_CONVERT_OLD_DB,
+ } op;
+ char *file_name;
+ char *prog = argv[0];
+ char *db_name;
+
+ progname = prog;
+
+ if (argc != 3 && argc != 4) {
+ fprintf(stderr, "Usage: %s operation file-name [database name].\n",
+ argv[0]);
+ exit(1);
+ }
+ if (argc == 3)
+ db_name = DBM_FILE;
+ else
+ db_name = argv[3];
+
+ if (kerb_db_set_name (db_name) != 0) {
+ perror("Can't open database");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "load"))
+ op = OP_LOAD;
+ else if (!strcmp(argv[1], "dump"))
+ op = OP_DUMP;
+ else if (!strcmp(argv[1], "slave_dump"))
+ op = OP_SLAVE_DUMP;
+ else if (!strcmp(argv[1], "new_master_key"))
+ op = OP_NEW_MASTER;
+ else if (!strcmp(argv[1], "convert_old_db"))
+ op = OP_CONVERT_OLD_DB;
+ else {
+ fprintf(stderr,
+ "%s: %s is an invalid operation.\n", prog, argv[1]);
+ fprintf(stderr,
+ "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);
+ fprintf(stderr,
+ "\"load\", \"new_master_key\", and \"convert_old_db\".\n");
+ exit(1);
+ }
+
+ file_name = argv[2];
+ file = fopen(file_name, op == OP_LOAD ? "r" : "w");
+ if (file == NULL) {
+ fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);
+ (void) fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+
+ switch (op) {
+ case OP_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ break;
+ case OP_SLAVE_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ update_ok_file (file_name);
+ break;
+ case OP_LOAD:
+ load_db (db_name, file);
+ break;
+ case OP_NEW_MASTER:
+ convert_new_master_key (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ case OP_CONVERT_OLD_DB:
+ convert_old_format_db (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ }
+ exit(0);
+ }
+
+clear_secrets ()
+{
+ bzero((char *)master_key, sizeof (des_cblock));
+ bzero((char *)master_key_schedule, sizeof (Key_schedule));
+ bzero((char *)new_master_key, sizeof (des_cblock));
+ bzero((char *)new_master_key_schedule, sizeof (Key_schedule));
+}
+
+/* cv_key is a procedure which takes a principle and changes its key,
+ either for a new method of encrypting the keys, or a new master key.
+ if cv_key is null no transformation of key is done (other than net byte
+ order). */
+
+struct callback_args {
+ void (*cv_key)();
+ FILE *output_file;
+};
+
+static int dump_db_1(arg, principal)
+ char *arg;
+ Principal *principal;
+{ /* replace null strings with "*" */
+ struct callback_args *a = (struct callback_args *)arg;
+
+ if (principal->instance[0] == '\0') {
+ principal->instance[0] = '*';
+ principal->instance[1] = '\0';
+ }
+ if (principal->mod_name[0] == '\0') {
+ principal->mod_name[0] = '*';
+ principal->mod_name[1] = '\0';
+ }
+ if (principal->mod_instance[0] == '\0') {
+ principal->mod_instance[0] = '*';
+ principal->mod_instance[1] = '\0';
+ }
+ if (a->cv_key != NULL) {
+ (*a->cv_key) (principal);
+ }
+ fprintf(a->output_file, "%s %s %d %d %d %d %x %x",
+ principal->name,
+ principal->instance,
+ principal->max_life,
+ principal->kdc_key_ver,
+ principal->key_version,
+ principal->attributes,
+ htonl (principal->key_low),
+ htonl (principal->key_high));
+ print_time(a->output_file, principal->exp_date);
+ print_time(a->output_file, principal->mod_date);
+ fprintf(a->output_file, " %s %s\n",
+ principal->mod_name,
+ principal->mod_instance);
+ return 0;
+}
+
+dump_db (db_file, output_file, cv_key)
+ char *db_file;
+ FILE *output_file;
+ void (*cv_key)();
+{
+ struct callback_args a;
+
+ a.cv_key = cv_key;
+ a.output_file = output_file;
+
+ kerb_db_iterate (dump_db_1, (char *)&a);
+ return fflush(output_file);
+}
+
+load_db (db_file, input_file)
+ char *db_file;
+ FILE *input_file;
+{
+ char exp_date_str[50];
+ char mod_date_str[50];
+ int temp1, temp2, temp3;
+ long time_explode();
+ int code;
+ char *temp_db_file;
+ temp1 = strlen(db_file+2);
+ temp_db_file = malloc (temp1);
+ strcpy(temp_db_file, db_file);
+ strcat(temp_db_file, "~");
+
+ /* Create the database */
+ if ((code = kerb_db_create(temp_db_file)) != 0) {
+ fprintf(stderr, "Couldn't create temp database %s: %s\n",
+ temp_db_file, sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(temp_db_file);
+ for (;;) { /* explicit break on eof from fscanf */
+ bzero((char *)&aprinc, sizeof(aprinc));
+ if (fscanf(input_file,
+ "%s %s %d %d %d %hd %x %x %s %s %s %s\n",
+ aprinc.name,
+ aprinc.instance,
+ &temp1,
+ &temp2,
+ &temp3,
+ &aprinc.attributes,
+ &aprinc.key_low,
+ &aprinc.key_high,
+ exp_date_str,
+ mod_date_str,
+ aprinc.mod_name,
+ aprinc.mod_instance) == EOF)
+ break;
+ aprinc.key_low = ntohl (aprinc.key_low);
+ aprinc.key_high = ntohl (aprinc.key_high);
+ aprinc.max_life = (unsigned char) temp1;
+ aprinc.kdc_key_ver = (unsigned char) temp2;
+ aprinc.key_version = (unsigned char) temp3;
+ aprinc.exp_date = time_explode(exp_date_str);
+ aprinc.mod_date = time_explode(mod_date_str);
+ if (aprinc.instance[0] == '*')
+ aprinc.instance[0] = '\0';
+ if (aprinc.mod_name[0] == '*')
+ aprinc.mod_name[0] = '\0';
+ if (aprinc.mod_instance[0] == '*')
+ aprinc.mod_instance[0] = '\0';
+ if (kerb_db_put_principal(&aprinc, 1) != 1) {
+ fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",
+ aprinc.name, aprinc.instance,
+ sys_errlist[errno]);
+ exit(1);
+ };
+ }
+ if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
+ perror("database rename failed");
+ (void) fclose(input_file);
+ free(temp_db_file);
+}
+
+print_time(file, timeval)
+ FILE *file;
+ unsigned long timeval;
+{
+ struct tm *tm;
+ struct tm *gmtime();
+ tm = gmtime((long *)&timeval);
+ fprintf(file, " %04d%02d%02d%02d%02d",
+ tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min);
+}
+
+/*ARGSUSED*/
+update_ok_file (file_name)
+ char *file_name;
+{
+ /* handle slave locking/failure stuff */
+ char *file_ok;
+ int fd;
+ static char ok[]=".dump_ok";
+
+ if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
+ == NULL) {
+ fprintf(stderr, "kdb_util: out of memory.\n");
+ (void) fflush (stderr);
+ perror ("malloc");
+ exit (1);
+ }
+ strcpy(file_ok, file_name);
+ strcat(file_ok, ok);
+ if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {
+ fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);
+ perror("");
+ (void) fflush (stderr);
+ exit (1);
+ }
+ free(file_ok);
+ close(fd);
+}
+
+void
+convert_key_new_master (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ /* move current key to des_cblock for encryption, special case master key
+ since that's changing */
+ if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
+ (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
+ bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));
+ (p->key_version)++;
+ } else {
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT);
+ }
+
+ kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+
+ (p->kdc_key_ver)++;
+}
+
+convert_new_master_key (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+
+ printf ("\n\nEnter the CURRENT master key.");
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't get master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets ();
+ exit (-1);
+ }
+
+ printf ("\n\nNow enter the NEW master key. Do not forget it!!");
+ if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't get new master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ dump_db (db_file, out, convert_key_new_master);
+}
+
+void
+convert_key_old_db (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);
+
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(des_cblock),master_key_schedule,
+ (des_cblock *)master_key_schedule,DECRYPT);
+#endif
+
+ /* make new key, new style */
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+}
+
+convert_old_format_db (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+ des_cblock key_from_db;
+ Principal principal_data[1];
+ int n, more;
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) {
+ fprintf (stderr, "%s: Couldn't get master key.\n");
+ clear_secrets();
+ exit (-1);
+ }
+
+ /* can't call kdb_verify_master_key because this is an old style db */
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ fprintf(stderr, "verify_master_key: ",
+ "Kerberos error on master key lookup, %d found.\n",
+ n);
+ exit (-1);
+ }
+
+ /* set up the master key */
+ fprintf(stderr, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt (old style) the key in the db, had better
+ * be the same!
+ */
+ bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);
+ bcopy((char *)&principal_data[0].key_high,
+ (char *)(((long *) key_from_db) + 1), 4);
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt(key_from_db,key_from_db,(long)sizeof(key_from_db),
+ master_key_schedule,(des_cblock *)master_key_schedule,DECRYPT);
+#endif
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ bzero((char *)key_from_db, sizeof(key_from_db));
+
+ if (n) {
+ fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, ");
+ fprintf(stderr, "does not match database.\n");
+ exit (-1);
+ }
+
+ fprintf(stderr, "Master key verified.\n");
+ (void) fflush(stderr);
+
+ dump_db (db_file, out, convert_key_old_db);
+}
+
+long
+time_explode(cp)
+register char *cp;
+{
+ char wbuf[5];
+ struct tm tp;
+ long maketime();
+ int local;
+
+ zaptime(&tp); /* clear out the struct */
+
+ if (strlen(cp) > 10) { /* new format */
+ (void) strncpy(wbuf, cp, 4);
+ wbuf[4] = 0;
+ tp.tm_year = atoi(wbuf);
+ cp += 4; /* step over the year */
+ local = 0; /* GMT */
+ } else { /* old format: local time,
+ year is 2 digits, assuming 19xx */
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_year = 1900 + atoi(wbuf);
+ local = 1; /* local */
+ }
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_mon = atoi(wbuf)-1;
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_mday = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_hour = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_min = atoi(wbuf);
+
+
+ return(maketime(&tp, local));
+}
diff --git a/eBones/kdestroy/Makefile b/eBones/kdestroy/Makefile
new file mode 100644
index 0000000..5947028
--- /dev/null
+++ b/eBones/kdestroy/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:15 g89r4222 Exp $
+
+PROG= kdestroy
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kdestroy/kdestroy.1 b/eBones/kdestroy/kdestroy.1
new file mode 100644
index 0000000..7099353
--- /dev/null
+++ b/eBones/kdestroy/kdestroy.1
@@ -0,0 +1,81 @@
+.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $
+.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdestroy \- destroy Kerberos tickets
+.SH SYNOPSIS
+.B kdestroy
+[
+.B \-f
+]
+[
+.B \-q
+]
+.SH DESCRIPTION
+The
+.I kdestroy
+utility destroys the user's active
+Kerberos
+authorization tickets by writing zeros to the file that contains them.
+If the ticket file does not exist,
+.I kdestroy
+displays a message to that effect.
+.PP
+After overwriting the file,
+.I kdestroy
+removes the file from the system.
+The utility
+displays a message indicating the success or failure of the
+operation.
+If
+.I kdestroy
+is unable to destroy the ticket file,
+the utility will warn you by making your terminal beep.
+.PP
+In the Athena workstation environment,
+the
+.I toehold
+service automatically destroys your tickets when you
+end a workstation session.
+If your site does not provide a similar ticket-destroying mechanism,
+you can place the
+.I kdestroy
+command in your
+.I .logout
+file so that your tickets are destroyed automatically
+when you logout.
+.PP
+The options to
+.I kdestroy
+are as follows:
+.TP 7
+.B \-f
+.I kdestroy
+runs without displaying the status message.
+.TP
+.B \-q
+.I kdestroy
+will not make your terminal beep if it fails to destroy the tickets.
+.SH FILES
+KRBTKFILE environment variable if set, otherwise
+.br
+/tmp/tkt[uid]
+.SH SEE ALSO
+kerberos(1), kinit(1), klist(1)
+.SH BUGS
+.PP
+Only the tickets in the user's current ticket file are destroyed.
+Separate ticket files are used to hold root instance and password
+changing tickets. These files should probably be destroyed too, or
+all of a user's tickets kept in a single ticket file.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+.br
+Bill Sommerfeld, MIT Project Athena
diff --git a/eBones/kdestroy/kdestroy.c b/eBones/kdestroy/kdestroy.c
new file mode 100644
index 0000000..f010fcd
--- /dev/null
+++ b/eBones/kdestroy/kdestroy.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This program causes Kerberos tickets to be destroyed.
+ * Options are:
+ *
+ * -q[uiet] - no bell even if tickets not destroyed
+ * -f[orce] - no message printed at all
+ *
+ * from: kdestroy.c,v 4.5 88/03/18 15:16:02 steiner Exp $
+ * $Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <krb.h>
+#ifdef BSD42
+#include <strings.h>
+#endif BSD42
+
+
+static char *pname;
+
+static usage()
+{
+ fprintf(stderr, "Usage: %s [-f] [-q]\n", pname);
+ exit(1);
+}
+
+main(argc, argv)
+ char *argv[];
+{
+ int fflag=0, qflag=0, k_errno;
+ register char *cp;
+
+ cp = rindex (argv[0], '/');
+ if (cp == NULL)
+ pname = argv[0];
+ else
+ pname = cp+1;
+
+ if (argc > 2)
+ usage();
+ else if (argc == 2) {
+ if (!strcmp(argv[1], "-f"))
+ ++fflag;
+ else if (!strcmp(argv[1], "-q"))
+ ++qflag;
+ else usage();
+ }
+
+ k_errno = dest_tkt();
+
+ if (fflag) {
+ if (k_errno != 0 && k_errno != RET_TKFIL)
+ exit(1);
+ else
+ exit(0);
+ } else {
+ if (k_errno == 0)
+ printf("Tickets destroyed.\n");
+ else if (k_errno == RET_TKFIL)
+ fprintf(stderr, "No tickets to destroy.\n");
+ else {
+ fprintf(stderr, "Tickets NOT destroyed.\n");
+ if (!qflag)
+ fprintf(stderr, "\007");
+ exit(1);
+ }
+ }
+ exit(0);
+}
diff --git a/eBones/kerberos/Makefile b/eBones/kerberos/Makefile
new file mode 100644
index 0000000..7f36cf7
--- /dev/null
+++ b/eBones/kerberos/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:22 g89r4222 Exp $
+
+PROG= kerberos
+SRCS= kerberos.c cr_err_reply.c
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kerberos/cr_err_reply.c b/eBones/kerberos/cr_err_reply.c
new file mode 100644
index 0000000..585fd03
--- /dev/null
+++ b/eBones/kerberos/cr_err_reply.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $
+ * $Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+extern int req_act_vno; /* this is defined in the kerberos
+ * server code */
+
+/*
+ * This routine is used by the Kerberos authentication server to
+ * create an error reply packet to send back to its client.
+ *
+ * It takes a pointer to the packet to be built, the name, instance,
+ * and realm of the principal, the client's timestamp, an error code
+ * and an error string as arguments. Its return value is undefined.
+ *
+ * The packet is built in the following format:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char req_ack_vno protocol version number
+ *
+ * unsigned char AUTH_MSG_ERR_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned long e error code
+ *
+ * string e_string error text
+ */
+
+void
+cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
+ KTEXT pkt;
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ u_long time_ws; /* Workstation time */
+ u_long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *v = (u_char *) pkt->dat; /* Prot vers number */
+ u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) req_act_vno; /* KRB_PROT_VERSION; */
+ *t = (unsigned char) AUTH_MSG_ERR_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2),pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *)(pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *)(pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* ws timestamp */
+ bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err code */
+ bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err text */
+ (void) strcpy((char *)(pkt->dat+pkt->length),e_string);
+ pkt->length += 1 + strlen(e_string);
+
+ /* And return */
+ return;
+}
diff --git a/eBones/kerberos/kerberos.c b/eBones/kerberos/kerberos.c
new file mode 100644
index 0000000..b980577
--- /dev/null
+++ b/eBones/kerberos/kerberos.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $
+ * $Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <ctype.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+extern int errno;
+
+struct sockaddr_in s_in = {AF_INET};
+int f;
+
+/* XXX several files in libkdb know about this */
+char *progname;
+
+static Key_schedule master_key_schedule;
+static C_Block master_key;
+
+static struct timeval kerb_time;
+static Principal a_name_data; /* for requesting user */
+static Principal s_name_data; /* for services requested */
+static C_Block session_key;
+static C_Block user_key;
+static C_Block service_key;
+static u_char master_key_version;
+static char k_instance[INST_SZ];
+static char log_text[128];
+static char *lt;
+static int more;
+
+static int mflag; /* Are we invoked manually? */
+static int lflag; /* Have we set an alterate log file? */
+static char *log_file; /* name of alt. log file */
+static int nflag; /* don't check max age */
+static int rflag; /* alternate realm specified */
+
+/* fields within the received request packet */
+static u_char req_msg_type;
+static u_char req_version;
+static char *req_name_ptr;
+static char *req_inst_ptr;
+static char *req_realm_ptr;
+static u_char req_no_req;
+static u_long req_time_ws;
+
+int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */
+
+static char local_realm[REALM_SZ];
+
+/* statistics */
+static long q_bytes; /* current bytes remaining in queue */
+static long q_n; /* how many consecutive non-zero
+ * q_bytes */
+static long max_q_bytes;
+static long max_q_n;
+static long n_auth_req;
+static long n_appl_req;
+static long n_packets;
+static long n_user;
+static long n_server;
+
+static long max_age = -1;
+static long pause_int = -1;
+
+static void check_db_age();
+static void hang();
+
+/*
+ * Print usage message and exit.
+ */
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname,
+ " [-a max_age] [-l log_file] [-r realm]"
+ ," [database_pathname]"
+ );
+ exit(1);
+}
+
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ register int n;
+ int on = 1;
+ int child;
+ struct servent *sp;
+ int fromlen;
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ Principal *p;
+ int more, kerror;
+ C_Block key;
+ int c;
+ extern char *optarg;
+ extern int optind;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) {
+ switch(c) {
+ case 's':
+ /*
+ * Set parameters to slave server defaults.
+ */
+ if (max_age == -1 && !nflag)
+ max_age = ONE_DAY; /* 24 hours */
+ if (pause_int == -1)
+ pause_int = FIVE_MINUTES; /* 5 minutes */
+ if (lflag == 0) {
+ log_file = KRBSLAVELOG;
+ lflag++;
+ }
+ break;
+ case 'n':
+ max_age = -1; /* don't check max age. */
+ nflag++;
+ break;
+ case 'm':
+ mflag++; /* running manually; prompt for master key */
+ break;
+ case 'p':
+ /* Set pause interval. */
+ if (!isdigit(optarg[0]))
+ usage();
+ pause_int = atoi(optarg);
+ if ((pause_int < 5) || (pause_int > ONE_HOUR)) {
+ fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n");
+ usage();
+ }
+ break;
+ case 'a':
+ /* Set max age. */
+ if (!isdigit(optarg[0]))
+ usage();
+ max_age = atoi(optarg);
+ if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) {
+ fprintf(stderr, "max_age must be between one hour and three days, in seconds\n");
+ usage();
+ }
+ break;
+ case 'l':
+ /* Set alternate log file */
+ lflag++;
+ log_file = optarg;
+ break;
+ case 'r':
+ /* Set realm name */
+ rflag++;
+ strcpy(local_realm, optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind == (argc-1)) {
+ if (kerb_db_set_name(argv[optind]) != 0) {
+ fprintf(stderr, "Could not set alternate database name\n");
+ exit(1);
+ }
+ optind++;
+ }
+
+ if (optind != argc)
+ usage();
+
+ printf("Kerberos server starting\n");
+
+ if ((!nflag) && (max_age != -1))
+ printf("\tMaximum database age: %d seconds\n", max_age);
+ if (pause_int != -1)
+ printf("\tSleep for %d seconds on error\n", pause_int);
+ else
+ printf("\tSleep forever on error\n");
+ if (mflag)
+ printf("\tMaster key will be entered manually\n");
+
+ printf("\tLog file is %s\n", lflag ? log_file : KRBLOG);
+
+ if (lflag)
+ kset_logfile(log_file);
+
+ /* find our hostname, and use it as the instance */
+ if (gethostname(k_instance, INST_SZ)) {
+ fprintf(stderr, "%s: gethostname error\n", progname);
+ exit(1);
+ }
+
+ if ((sp = getservbyname("kerberos", "udp")) == 0) {
+ fprintf(stderr, "%s: udp/kerberos unknown service\n", progname);
+ exit(1);
+ }
+ s_in.sin_port = sp->s_port;
+
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "%s: Can't open socket\n", progname);
+ exit(1);
+ }
+ if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+ fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname);
+
+ if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) {
+ fprintf(stderr, "%s: Can't bind socket\n", progname);
+ exit(1);
+ }
+ /* do all the database and cache inits */
+ if (n = kerb_init()) {
+ if (mflag) {
+ printf("Kerberos db and cache init ");
+ printf("failed = %d ...exiting\n", n);
+ exit(-1);
+ } else {
+ klog(L_KRB_PERR,
+ "Kerberos db and cache init failed = %d ...exiting", n);
+ hang();
+ }
+ }
+
+ /* Make sure database isn't stale */
+ check_db_age();
+
+ /* setup master key */
+ if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) {
+ klog (L_KRB_PERR, "kerberos: couldn't get master key.\n");
+ exit (-1);
+ }
+ kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout);
+ if (kerror < 0) {
+ klog (L_KRB_PERR, "Can't verify master key.");
+ bzero (master_key, sizeof (master_key));
+ bzero (master_key_schedule, sizeof (master_key_schedule));
+ exit (-1);
+ }
+
+ master_key_version = (u_char) kerror;
+
+ fprintf(stdout, "\nCurrent Kerberos master key version is %d\n",
+ master_key_version);
+
+ if (!rflag) {
+ /* Look up our local realm */
+ krb_get_lrealm(local_realm, 1);
+ }
+ fprintf(stdout, "Local realm: %s\n", local_realm);
+ fflush(stdout);
+
+ if (set_tgtkey(local_realm)) {
+ /* Ticket granting service unknown */
+ klog(L_KRB_PERR, "Ticket granting ticket service unknown");
+ fprintf(stderr, "Ticket granting ticket service unknown\n");
+ exit(1);
+ }
+ if (mflag) {
+ if ((child = fork()) != 0) {
+ printf("Kerberos started, PID=%d\n", child);
+ exit(0);
+ }
+ setup_disc();
+ }
+ /* receive loop */
+ for (;;) {
+ fromlen = S_AD_SZ;
+ n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from,
+ &fromlen);
+ if (n > 0) {
+ pkt->length = n;
+ pkt->mbz = 0; /* force zeros to catch runaway strings */
+ /* see what is left in the input queue */
+ ioctl(f, FIONREAD, &q_bytes);
+ gettimeofday(&kerb_time, NULL);
+ q_n++;
+ max_q_n = max(max_q_n, q_n);
+ n_packets++;
+ klog(L_NET_INFO,
+ "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d",
+ q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0);
+ max_q_bytes = max(max_q_bytes, q_bytes);
+ if (!q_bytes)
+ q_n = 0; /* reset consecutive packets */
+ kerberos(&from, pkt);
+ } else
+ klog(L_NET_ERR,
+ "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0);
+ }
+}
+
+
+kerberos(client, pkt)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+{
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st;
+ static KTEXT_ST ciph_st;
+ KTEXT ciph = &ciph_st;
+ static KTEXT_ST tk_st;
+ KTEXT tk = &tk_st;
+ static KTEXT_ST auth_st;
+ KTEXT auth = &auth_st;
+ AUTH_DAT ad_st;
+ AUTH_DAT *ad = &ad_st;
+
+
+ static struct in_addr client_host;
+ static int msg_byte_order;
+ static int swap_bytes;
+ static u_char k_flags;
+ char *p_name, *instance;
+ u_long lifetime;
+ int i;
+ C_Block key;
+ Key_schedule key_s;
+ char *ptr;
+
+
+
+ ciph->length = 0;
+
+ client_host = client->sin_addr;
+
+ /* eval macros and correct the byte order and alignment as needed */
+ req_version = pkt_version(pkt); /* 1 byte, version */
+ req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */
+
+ req_act_vno = req_version;
+
+ /* check packet version */
+ if (req_version != KRB_PROT_VERSION) {
+ lt = klog(L_KRB_PERR,
+ "KRB prot version mismatch: KRB =%d request = %d",
+ KRB_PROT_VERSION, req_version, 0);
+ /* send an error reply */
+ kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+ return;
+ }
+ msg_byte_order = req_msg_type & 1;
+
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+ klog(L_KRB_PINFO,
+ "Prot version: %d, Byte order: %d, Message type: %d",
+ req_version, msg_byte_order, req_msg_type);
+
+ switch (req_msg_type & ~1) {
+
+ case AUTH_MSG_KDC_REQUEST:
+ {
+ u_long time_ws; /* Workstation time */
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ int kerno; /* Kerberos error number */
+ n_auth_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+
+ /* set up and correct for byte order and alignment */
+ req_name_ptr = (char *) pkt_a_name(pkt);
+ req_inst_ptr = (char *) pkt_a_inst(pkt);
+ req_realm_ptr = (char *) pkt_a_realm(pkt);
+ bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws));
+ /* time has to be diddled */
+ if (swap_bytes) {
+ swap_u_long(req_time_ws);
+ }
+ ptr = (char *) pkt_time_ws(pkt) + 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ rpkt = &rpkt_st;
+ klog(L_INI_REQ,
+ "Initial ticket request Host: %s User: \"%s\" \"%s\"",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+
+ if (i = check_princ(req_name_ptr, req_inst_ptr, 0,
+ &a_name_data)) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ tk->length = 0; /* init */
+ if (strcmp(service, "krbtgt"))
+ klog(L_NTGT_INTK,
+ "INITIAL request from %s.%s for %s.%s",
+ req_name_ptr, req_inst_ptr, service, instance, 0);
+ /* this does all the checking */
+ if (i = check_princ(service, instance, lifetime,
+ &s_name_data)) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life, ((u_long) s_name_data.max_life));
+ lifetime = min(lifetime, ((u_long) a_name_data.max_life));
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+ krb_create_ticket(tk, k_flags, a_name_data.name,
+ a_name_data.instance, local_realm,
+ client_host.s_addr, session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance, key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ /*
+ * get the user's key, unseal it from the server's key, and
+ * use it to seal the cipher
+ */
+
+ /* a_name_data.key_low a_name_data.key_high */
+ bcopy(&a_name_data.key_low, key, 4);
+ bcopy(&a_name_data.key_high, ((long *) key) + 1, 4);
+
+ /* unseal the a_name key from the master key */
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+
+ create_ciph(ciph, session_key, s_name_data.name,
+ s_name_data.instance, local_realm, lifetime,
+ s_name_data.key_version, tk, kerb_time.tv_sec, key);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(key, sizeof(key));
+
+
+
+ /* always send a reply packet */
+ rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
+ req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
+ a_name_data.key_version, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&a_name_data, sizeof(a_name_data));
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+ case AUTH_MSG_APPL_REQUEST:
+ {
+ u_long time_ws; /* Workstation time */
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ int kerno; /* Kerberos error number */
+ char tktrlm[REALM_SZ];
+
+ n_appl_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+ auth->length = 4 + strlen(pkt->dat + 3);
+ auth->length += (int) *(pkt->dat + auth->length) +
+ (int) *(pkt->dat + auth->length + 1) + 2;
+
+ bcopy(pkt->dat, auth->dat, auth->length);
+
+ strncpy(tktrlm, auth->dat + 3, REALM_SZ);
+ if (set_tgtkey(tktrlm)) {
+ lt = klog(L_ERR_UNK,
+ "FAILED realm %s unknown. Host: %s ",
+ tktrlm, inet_ntoa(client_host));
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr,
+ ad, 0);
+
+ if (kerno) {
+ klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
+ inet_ntoa(client_host), krb_err_txt[kerno]);
+ kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+ return;
+ }
+ ptr = (char *) pkt->dat + auth->length;
+
+ bcopy(ptr, &time_ws, 4);
+ ptr += 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
+ ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host),
+ service, instance, 0);
+
+ if (strcmp(ad->prealm, tktrlm)) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't hop realms");
+ return;
+ }
+ if (!strcmp(service, "changepw")) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't authorize password changed based on TGT");
+ return;
+ }
+ kerno = check_princ(service, instance, req_life,
+ &s_name_data);
+ if (kerno) {
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life,
+ (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300)));
+ lifetime = min(lifetime, ((u_long) s_name_data.max_life));
+
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+
+ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
+ ad->prealm, client_host,
+ session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance,
+ key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ create_ciph(ciph, session_key, service, instance,
+ local_realm,
+ lifetime, s_name_data.key_version, tk,
+ kerb_time.tv_sec, ad->session);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(ad->session, sizeof(ad->session));
+
+ rpkt = create_auth_reply(ad->pname, ad->pinst,
+ ad->prealm, time_ws,
+ 0, 0, 0, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+
+
+#ifdef notdef_DIE
+ case AUTH_MSG_DIE:
+ {
+ lt = klog(L_DEATH_REQ,
+ "Host: %s User: \"%s\" \"%s\" Kerberos killed",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+ exit(0);
+ }
+#endif notdef_DIE
+
+ default:
+ {
+ lt = klog(L_KRB_PERR,
+ "Unknown message type: %d from %s port %u",
+ req_msg_type, inet_ntoa(client_host),
+ ntohs(client->sin_port));
+ break;
+ }
+ }
+}
+
+
+/*
+ * setup_disc
+ *
+ * disconnect all descriptors, remove ourself from the process
+ * group that spawned us.
+ */
+
+setup_disc()
+{
+
+ int s;
+
+ for (s = 0; s < 3; s++) {
+ (void) close(s);
+ }
+
+ (void) open("/dev/null", 0);
+ (void) dup2(0, 1);
+ (void) dup2(0, 2);
+
+ s = open("/dev/tty", 2);
+
+ if (s >= 0) {
+ ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
+ (void) close(s);
+ }
+ (void) chdir("/tmp");
+ return;
+}
+
+
+/*
+ * kerb_er_reply creates an error reply packet and sends it to the
+ * client.
+ */
+
+kerb_err_reply(client, pkt, err, string)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+ long err;
+ char *string;
+
+{
+ static KTEXT_ST e_pkt_st;
+ KTEXT e_pkt = &e_pkt_st;
+ static char e_msg[128];
+
+ strcpy(e_msg, "\nKerberos error -- ");
+ strcat(e_msg, string);
+ cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
+ req_time_ws, err, e_msg);
+ sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+
+}
+
+/*
+ * Make sure that database isn't stale.
+ *
+ * Exit if it is; we don't want to tell lies.
+ */
+
+static void check_db_age()
+{
+ long age;
+
+ if (max_age != -1) {
+ /* Requires existance of kerb_get_db_age() */
+ gettimeofday(&kerb_time, 0);
+ age = kerb_get_db_age();
+ if (age == 0) {
+ klog(L_KRB_PERR, "Database currently being updated!");
+ hang();
+ }
+ if ((age + max_age) < kerb_time.tv_sec) {
+ klog(L_KRB_PERR, "Database out of date!");
+ hang();
+ /* NOTREACHED */
+ }
+ }
+}
+
+check_princ(p_name, instance, lifetime, p)
+ char *p_name;
+ char *instance;
+ unsigned lifetime;
+
+ Principal *p;
+{
+ static int n;
+ static int more;
+ long trans;
+
+ n = kerb_get_principal(p_name, instance, p, 1, &more);
+ klog(L_ALL_REQ,
+ "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
+ p_name, instance, lifetime, n, 0);
+
+ if (n < 0) {
+ lt = klog(L_KRB_PERR, "Database unavailable!");
+ hang();
+ }
+
+ /*
+ * if more than one p_name, pick one, randomly create a session key,
+ * compute maximum lifetime, lookup authorizations if applicable,
+ * and stuff into cipher.
+ */
+ if (n == 0) {
+ /* service unknown, log error, skip to next request */
+ lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_PRINCIPAL_UNKNOWN;
+ }
+ if (more) {
+ /* not unique, log error */
+ lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
+ p_name, instance, 0);
+ return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
+ }
+ /* If the user's key is null, we want to return an error */
+ if ((p->key_low == 0) && (p->key_high == 0)) {
+ /* User has a null key */
+ lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_NULL_KEY;
+ }
+ if (master_key_version != p->kdc_key_ver) {
+ /* log error reply */
+ lt = klog(L_ERR_MKV,
+ "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d",
+ master_key_version, p->name, p->instance, p->kdc_key_ver,
+ 0);
+ return KERB_ERR_NAME_MAST_KEY_VER;
+ }
+ /* make sure the service hasn't expired */
+ if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) {
+ /* service did expire, log it */
+ lt = klog(L_ERR_SEXP,
+ "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance,
+ stime(&(p->exp_date)), 0);
+ return KERB_ERR_NAME_EXP;
+ }
+ /* ok is zero */
+ return 0;
+}
+
+
+/* Set the key for krb_rd_req so we can check tgt */
+set_tgtkey(r)
+ char *r; /* Realm for desired key */
+{
+ int n;
+ static char lastrealm[REALM_SZ];
+ Principal p_st;
+ Principal *p = &p_st;
+ C_Block key;
+
+ if (!strcmp(lastrealm, r))
+ return (KSUCCESS);
+
+ log("Getting key for %s", r);
+
+ n = kerb_get_principal("krbtgt", r, p, 1, &more);
+ if (n == 0)
+ return (KFAILURE);
+
+ /* unseal tgt key from master key */
+ bcopy(&p->key_low, key, 4);
+ bcopy(&p->key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ krb_set_key(key, 0);
+ strcpy(lastrealm, r);
+ return (KSUCCESS);
+}
+
+static void
+hang()
+{
+ if (pause_int == -1) {
+ klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
+ for (;;)
+ pause();
+ } else {
+ char buf[256];
+ sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int);
+ klog(L_KRB_PERR, buf);
+ sleep(pause_int);
+ klog(L_KRB_PERR, "Do svedania....\n");
+ exit(1);
+ }
+}
diff --git a/eBones/kinit/Makefile b/eBones/kinit/Makefile
new file mode 100644
index 0000000..e616f42
--- /dev/null
+++ b/eBones/kinit/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:31 g89r4222 Exp $
+
+PROG= kinit
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kinit/kinit.1 b/eBones/kinit/kinit.1
new file mode 100644
index 0000000..f9a97a7
--- /dev/null
+++ b/eBones/kinit/kinit.1
@@ -0,0 +1,133 @@
+.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $
+.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kinit \- Kerberos login utility
+.SH SYNOPSIS
+.B kinit
+[
+.B \-irvl
+]
+.SH DESCRIPTION
+The
+.I kinit
+command is used to login to the
+Kerberos
+authentication and authorization system.
+Note that only registered
+Kerberos
+users can use the
+Kerberos
+system.
+For information about registering as a
+Kerberos
+user,
+see the
+.I kerberos(1)
+manual page.
+.PP
+If you are logged in to a workstation that is running the
+.I toehold
+service,
+you do not have to use
+.I kinit.
+The
+.I toehold
+login procedure will log you into
+Kerberos
+automatically.
+You will need to use
+.I kinit
+only in those situations in which
+your original tickets have expired.
+(Tickets expire in about a day.)
+Note as well that
+.I toehold
+will automatically destroy your tickets when you logout from the workstation.
+.PP
+When you use
+.I kinit
+without options,
+the utility
+prompts for your username and Kerberos password,
+and tries to authenticate your login with the local
+Kerberos
+server.
+.PP
+If
+Kerberos
+authenticates the login attempt,
+.I kinit
+retrieves your initial ticket and puts it in the ticket file specified by
+your KRBTKFILE environment variable.
+If this variable is undefined,
+your ticket will be stored in the
+.IR /tmp
+directory,
+in the file
+.I tktuid ,
+where
+.I uid
+specifies your user identification number.
+.PP
+If you have logged in to
+Kerberos
+without the benefit of the workstation
+.I toehold
+system,
+make sure you use the
+.I kdestroy
+command to destroy any active tickets before you end your login session.
+You may want to put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+.PP
+The options to
+.I kinit
+are as follows:
+.TP 7
+.B \-i
+.I kinit
+prompts you for a
+Kerberos
+instance.
+.TP
+.B \-r
+.I kinit
+prompts you for a
+Kerberos
+realm.
+This option lets you authenticate yourself with a remote
+Kerberos
+server.
+.TP
+.B \-v
+Verbose mode.
+.I kinit
+prints the name of the ticket file used, and
+a status message indicating the success or failure of
+your login attempt.
+.TP
+.B \-l
+.I kinit
+prompts you for a ticket lifetime in minutes. Due to protocol
+restrictions in Kerberos Version 4, this value must be between 5 and
+1275 minutes.
+.SH SEE ALSO
+.PP
+kerberos(1), kdestroy(1), klist(1), toehold(1)
+.SH BUGS
+The
+.B \-r
+option has not been fully implemented.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
diff --git a/eBones/kinit/kinit.c b/eBones/kinit/kinit.c
new file mode 100644
index 0000000..94ce0fe
--- /dev/null
+++ b/eBones/kinit/kinit.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Routine to initialize user to Kerberos. Prompts optionally for
+ * user, instance and realm. Authenticates user and gets a ticket
+ * for the Kerberos ticket-granting service for future use.
+ *
+ * Options are:
+ *
+ * -i[instance]
+ * -r[realm]
+ * -v[erbose]
+ * -l[ifetime]
+ *
+ * from: kinit.c,v 4.12 90/03/20 16:11:15 jon Exp $
+ * $Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <pwd.h>
+#include <krb.h>
+
+#ifndef ORGANIZATION
+#define ORGANIZATION "MIT Project Athena"
+#endif /*ORGANIZATION*/
+
+#ifdef PC
+#define LEN 64 /* just guessing */
+#endif PC
+
+#if defined(BSD42) || defined(__FreeBSD__)
+#include <strings.h>
+#include <sys/param.h>
+#if defined(ultrix) || defined(sun)
+#define LEN 64
+#else
+#define LEN MAXHOSTNAMELEN
+#endif /* defined(ultrix) || defined(sun) */
+#endif /* BSD42 */
+
+#define LIFE 96 /* lifetime of ticket in 5-minute units */
+
+char *progname;
+
+void
+get_input(s, size, stream)
+char *s;
+int size;
+FILE *stream;
+{
+ char *p;
+
+ if (fgets(s, size, stream) == NULL)
+ exit(1);
+ if ((p = index(s, '\n')) != NULL)
+ *p = '\0';
+}
+
+main(argc, argv)
+ char *argv[];
+{
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char buf[LEN];
+ char *username = NULL;
+ int iflag, rflag, vflag, lflag, lifetime, k_errno;
+ register char *cp;
+ register i;
+
+ *inst = *realm = '\0';
+ iflag = rflag = vflag = lflag = 0;
+ lifetime = LIFE;
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (--argc) {
+ if ((*++argv)[0] != '-') {
+ if (username)
+ usage();
+ username = *argv;
+ continue;
+ }
+ for (i = 1; (*argv)[i] != '\0'; i++)
+ switch ((*argv)[i]) {
+ case 'i': /* Instance */
+ ++iflag;
+ continue;
+ case 'r': /* Realm */
+ ++rflag;
+ continue;
+ case 'v': /* Verbose */
+ ++vflag;
+ continue;
+ case 'l':
+ ++lflag;
+ continue;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ if (username &&
+ (k_errno = kname_parse(aname, inst, realm, username))
+ != KSUCCESS) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ iflag = rflag = 1;
+ username = NULL;
+ }
+ if (k_gethostname(buf, LEN)) {
+ fprintf(stderr, "%s: k_gethostname failed\n", progname);
+ exit(1);
+ }
+ printf("%s (%s)\n", ORGANIZATION, buf);
+ if (username) {
+ printf("Kerberos Initialization for \"%s", aname);
+ if (*inst)
+ printf(".%s", inst);
+ if (*realm)
+ printf("@%s", realm);
+ printf("\"\n");
+ } else {
+ if (iflag) {
+ printf("Kerberos Initialization\n");
+ printf("Kerberos name: ");
+ get_input(aname, sizeof(aname), stdin);
+ } else {
+ int uid = getuid();
+ char *getenv();
+ struct passwd *pwd;
+
+ /* default to current user name unless running as root */
+ if (uid == 0 && (username = getenv("USER")) &&
+ strcmp(username, "root") != 0) {
+ strncpy(aname, username, sizeof(aname));
+ strncpy(inst, "root", sizeof(inst));
+ } else {
+ pwd = getpwuid(uid);
+
+ if (pwd == (struct passwd *) NULL) {
+ fprintf(stderr, "Unknown name for your uid\n");
+ printf("Kerberos name: ");
+ gets(aname);
+ } else
+ strncpy(aname, pwd->pw_name, sizeof(aname));
+ }
+ }
+
+ if (!*aname)
+ exit(0);
+ if (!k_isname(aname)) {
+ fprintf(stderr, "%s: bad Kerberos name format\n",
+ progname);
+ exit(1);
+ }
+ }
+ /* optional instance */
+ if (iflag) {
+ printf("Kerberos instance: ");
+ get_input(inst, sizeof(inst), stdin);
+ if (!k_isinst(inst)) {
+ fprintf(stderr, "%s: bad Kerberos instance format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (rflag) {
+ printf("Kerberos realm: ");
+ get_input(realm, sizeof(realm), stdin);
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: bad Kerberos realm format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (lflag) {
+ printf("Kerberos ticket lifetime (minutes): ");
+ get_input(buf, sizeof(buf), stdin);
+ lifetime = atoi(buf);
+ if (lifetime < 5)
+ lifetime = 1;
+ else
+ lifetime /= 5;
+ /* This should be changed if the maximum ticket lifetime */
+ /* changes */
+ if (lifetime > 255)
+ lifetime = 255;
+ }
+ if (!*realm && krb_get_lrealm(realm, 1)) {
+ fprintf(stderr, "%s: krb_get_lrealm failed\n", progname);
+ exit(1);
+ }
+ k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm,
+ lifetime, 0);
+ if (vflag) {
+ printf("Kerberos realm %s:\n", realm);
+ printf("%s\n", krb_err_txt[k_errno]);
+ } else if (k_errno) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ exit(1);
+ }
+}
+
+usage()
+{
+ fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname);
+ exit(1);
+}
diff --git a/eBones/klist/Makefile b/eBones/klist/Makefile
new file mode 100644
index 0000000..aa0d720
--- /dev/null
+++ b/eBones/klist/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:37 g89r4222 Exp $
+
+PROG= klist
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/klist/klist.1 b/eBones/klist/klist.1
new file mode 100644
index 0000000..a66e668
--- /dev/null
+++ b/eBones/klist/klist.1
@@ -0,0 +1,84 @@
+.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $
+.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+klist \- list currently held Kerberos tickets
+.SH SYNOPSIS
+.B klist
+[
+\fB\-s \fR|\fB \-t\fR
+] [
+.B \-file
+name ] [
+.B \-srvtab
+]
+.br
+.SH DESCRIPTION
+.I klist
+prints the name of the tickets file and the
+identity of the principal the tickets are for (as listed in the
+tickets file), and
+lists the principal names of all Kerberos tickets currently held by
+the user, along with the issue and expire time for each authenticator.
+Principal names are listed in the form
+.I name.instance@realm,
+with the '.' omitted if the instance is null,
+and the '@' omitted if the realm is null.
+
+If given the
+.B \-s
+option,
+.I klist
+does not print the issue and expire times, the name of the tickets file,
+or the identity of the principal.
+
+If given the
+.B \-t
+option,
+.B klist
+checks for the existence of a non-expired ticket-granting-ticket in the
+ticket file. If one is present, it exits with status 0, else it exits
+with status 1. No output is generated when this option is specified.
+
+If given the
+.B \-file
+option, the following argument is used as the ticket file.
+Otherwise, if the
+.B KRBTKFILE
+environment variable is set, it is used.
+If this environment variable
+is not set, the file
+.B /tmp/tkt[uid]
+is used, where
+.B uid
+is the current user-id of the user.
+
+If given the
+.B \-srvtab
+option, the file is treated as a service key file, and the names of the
+keys contained therein are printed. If no file is
+specified with a
+.B \-file
+option, the default is
+.IR /etc/srvtab .
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm
+.TP
+/tmp/tkt[uid]
+as the default ticket file ([uid] is the decimal UID of the user).
+.TP
+/etc/srvtab
+as the default service key file
+.SH SEE ALSO
+.PP
+kerberos(1), kinit(1), kdestroy(1)
+.SH BUGS
+When reading a file as a service key file, very little sanity or error
+checking is performed.
diff --git a/eBones/klist/klist.c b/eBones/klist/klist.c
new file mode 100644
index 0000000..4a95bc0
--- /dev/null
+++ b/eBones/klist/klist.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Lists your current Kerberos tickets.
+ * Written by Bill Sommerfeld, MIT Project Athena.
+ *
+ * from: klist.c,v 4.15 89/08/30 11:19:16 jtkohl Exp $
+ * $Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <krb.h>
+#include <prot.h>
+
+char *tkt_string();
+char *short_date();
+char *whoami; /* What was I invoked as?? */
+char *getenv();
+
+extern char *krb_err_txt[];
+
+/* ARGSUSED */
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int long_form = 1;
+ int tgt_test = 0;
+ int do_srvtab = 0;
+ char *tkt_file = NULL;
+ char *cp;
+
+ whoami = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (*(++argv)) {
+ if (!strcmp(*argv, "-s")) {
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-t")) {
+ tgt_test = 1;
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-l")) { /* now default */
+ continue;
+ }
+ if (!strcmp(*argv, "-file")) {
+ if (*(++argv)) {
+ tkt_file = *argv;
+ continue;
+ } else
+ usage();
+ }
+ if (!strcmp(*argv, "-srvtab")) {
+ if (tkt_file == NULL) /* if no other file spec'ed,
+ set file to default srvtab */
+ tkt_file = KEYFILE;
+ do_srvtab = 1;
+ continue;
+ }
+ usage();
+ }
+
+ if (do_srvtab)
+ display_srvtab(tkt_file);
+ else
+ display_tktfile(tkt_file, tgt_test, long_form);
+ exit(0);
+}
+
+
+display_tktfile(file, tgt_test, long_form)
+char *file;
+int tgt_test, long_form;
+{
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ char buf1[20], buf2[20];
+ int k_errno;
+ CREDENTIALS c;
+ int header = 1;
+
+ if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL))
+ file = TKT_FILE;
+
+ if (long_form)
+ printf("Ticket file: %s\n", file);
+
+ /*
+ * Since krb_get_tf_realm will return a ticket_file error,
+ * we will call tf_init and tf_close first to filter out
+ * things like no ticket file. Otherwise, the error that
+ * the user would see would be
+ * klist: can't find realm of ticket file: No ticket file (tf_util)
+ * instead of
+ * klist: No ticket file (tf_util)
+ */
+
+ /* Open ticket file */
+ if (k_errno = tf_init(file, R_TKT_FIL)) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Close ticket file */
+ (void) tf_close();
+
+ /*
+ * We must find the realm of the ticket file here before calling
+ * tf_init because since the realm of the ticket file is not
+ * really stored in the principal section of the file, the
+ * routine we use must itself call tf_init and tf_close.
+ */
+ if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: can't find realm of ticket file: %s\n",
+ whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /* Open ticket file */
+ if (k_errno = tf_init(file, R_TKT_FIL)) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Get principal name and instance */
+ if ((k_errno = tf_get_pname(pname)) ||
+ (k_errno = tf_get_pinst(pinst))) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /*
+ * You may think that this is the obvious place to get the
+ * realm of the ticket file, but it can't be done here as the
+ * routine to do this must open the ticket file. This is why
+ * it was done before tf_init.
+ */
+
+ if (!tgt_test && long_form)
+ printf("Principal:\t%s%s%s%s%s\n\n", pname,
+ (pinst[0] ? "." : ""), pinst,
+ (prealm[0] ? "@" : ""), prealm);
+ while ((k_errno = tf_get_cred(&c)) == KSUCCESS) {
+ if (!tgt_test && long_form && header) {
+ printf("%-15s %-15s %s\n",
+ " Issued", " Expires", " Principal");
+ header = 0;
+ }
+ if (tgt_test) {
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ if (!strcmp(c.service, TICKET_GRANTING_TICKET) &&
+ !strcmp(c.instance, prealm)) {
+ if (time(0) < c.issue_date)
+ exit(0); /* tgt hasn't expired */
+ else
+ exit(1); /* has expired */
+ }
+ continue; /* not a tgt */
+ }
+ if (long_form) {
+ (void) strcpy(buf1, short_date(&c.issue_date));
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ (void) strcpy(buf2, short_date(&c.issue_date));
+ printf("%s %s ", buf1, buf2);
+ }
+ printf("%s%s%s%s%s\n",
+ c.service, (c.instance[0] ? "." : ""), c.instance,
+ (c.realm[0] ? "@" : ""), c.realm);
+ }
+ if (tgt_test)
+ exit(1); /* no tgt found */
+ if (header && long_form && k_errno == EOF) {
+ printf("No tickets in file.\n");
+ }
+}
+
+char *
+short_date(dp)
+ long *dp;
+{
+ register char *cp;
+ extern char *ctime();
+ cp = ctime(dp) + 4;
+ cp[15] = '\0';
+ return (cp);
+}
+
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami);
+ exit(1);
+}
+
+display_srvtab(file)
+char *file;
+{
+ int stab;
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char key[8];
+ unsigned char vno;
+ int count;
+
+ printf("Server key file: %s\n", file);
+
+ if ((stab = open(file, O_RDONLY, 0400)) < 0) {
+ perror(file);
+ exit(1);
+ }
+ printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm",
+ "Key Version");
+ printf("------------------------------------------------------\n");
+
+ /* argh. getst doesn't return error codes, it silently fails */
+ while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
+ && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
+ && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
+ if (((count = read(stab,(char *) &vno,1)) != 1) ||
+ ((count = read(stab,(char *) key,8)) != 8)) {
+ if (count < 0)
+ perror("reading from key file");
+ else
+ fprintf(stderr, "key file truncated\n");
+ exit(1);
+ }
+ printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno);
+ }
+ if (count < 0)
+ perror(file);
+ (void) close(stab);
+}
+
+/* adapted from getst() in librkb */
+/*
+ * ok_getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. ok_getst() returns the number of characters read, including
+ * the null terminator.
+ *
+ * If there is a read error, it returns -1 (like the read(2) system call)
+ */
+
+ok_getst(fd, s, n)
+ int fd;
+ register char *s;
+{
+ register count = n;
+ int err;
+ while ((err = read(fd, s, 1)) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ if (err < 0)
+ return(-1);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/krb/Makefile b/eBones/krb/Makefile
new file mode 100644
index 0000000..8336132
--- /dev/null
+++ b/eBones/krb/Makefile
@@ -0,0 +1,31 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1994/09/07 16:10:17 g89r4222 Exp $
+
+LIB= krb
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42
+SRCS= create_auth_reply.c create_ciph.c \
+ create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
+ des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \
+ get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \
+ get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \
+ get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \
+ k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \
+ krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \
+ mk_priv.c mk_req.c mk_safe.c month_sname.c \
+ netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \
+ rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \
+ save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \
+ tkt_string.c util.c
+
+TDIR= ${.CURDIR}/..
+krb_err.et.c: ${COMPILE_ET}
+ (cd ${TDIR}/compile_et; make)
+ ${COMPILE_ET} ${.CURDIR}/krb_err.et -n
+
+beforedepend: krb_err.et.c
+
+CLEANFILES+= krb_err.et.c krb_err.h
+
+.include <bsd.lib.mk>
diff --git a/eBones/krb/add_ticket.c b/eBones/krb/add_ticket.c
new file mode 100644
index 0000000..cb79a18
--- /dev/null
+++ b/eBones/krb/add_ticket.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $
+ * $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is now obsolete. It used to be possible to request
+ * more than one ticket at a time from the authentication server, and
+ * it looks like this routine was used by the server to package the
+ * tickets to be returned to the client.
+ */
+
+/*
+ * This routine adds a new ticket to the ciphertext to be returned to
+ * the client. The routine takes the ciphertext (which doesn't get
+ * encrypted till later), the number of the ticket (i.e. 1st, 2nd,
+ * etc) the session key which goes in the ticket and is sent back to
+ * the user, the lifetime for the ticket, the service name, the
+ * instance, the realm, the key version number, and the ticket itself.
+ *
+ * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on
+ * failure. On failure, which occurs when there isn't enough room
+ * for the ticket, a 0 length ticket is added.
+ *
+ * Notes: This routine must be called with successive values of n.
+ * i.e. the ticket must be added in order. The corresponding routine
+ * on the client side is extract ticket.
+ */
+
+/* XXX they aren't all used; to avoid incompatible changes we will
+ * fool lint for the moment */
+/*ARGSUSED */
+add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket)
+ KTEXT cipher; /* Ciphertext info for ticket */
+ char *sname; /* Service name */
+ char *instance; /* Instance */
+ int n; /* Relative position of this ticket */
+ char *session; /* Session key for this tkt */
+ int lifetime; /* Lifetime of this ticket */
+ char *realm; /* Realm in which ticket is valid */
+ int kvno; /* Key version number of service key */
+ KTEXT ticket; /* The ticket itself */
+{
+
+ /* Note, the 42 is a temporary hack; it will have to be changed. */
+
+ /* Begin check of ticket length */
+ if ((cipher->length + ticket->length + 4 + 42 +
+ (*(cipher->dat)+1-n)*(11+strlen(realm))) >
+ MAX_KTXT_LEN) {
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ *(cipher->dat+n) = 0;
+ return(KFAILURE);
+ }
+ /* End check of ticket length */
+
+ /* Add the session key, lifetime, kvno, ticket to the ciphertext */
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length),
+ ticket->length);
+ cipher->length += ticket->length;
+
+ /* Set the ticket length at beginning of ciphertext */
+ *(cipher->dat+n) = ticket->length;
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/create_auth_reply.c b/eBones/krb/create_auth_reply.c
new file mode 100644
index 0000000..e47d4df
--- /dev/null
+++ b/eBones/krb/create_auth_reply.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $
+ * $Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is called by the Kerberos authentication server
+ * to create a reply to an authentication request. The routine
+ * takes the user's name, instance, and realm, the client's
+ * timestamp, the number of tickets, the user's key version
+ * number and the ciphertext containing the tickets themselves.
+ * It constructs a packet and returns a pointer to it.
+ *
+ * Notes: The packet returned by this routine is static. Thus, if you
+ * intend to keep the result beyond the next call to this routine, you
+ * must copy it elsewhere.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_KDC_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned char n number of tickets
+ *
+ * unsigned long x_date expiration date
+ *
+ * unsigned char kvno master key version
+ *
+ * short w_1 cipher length
+ *
+ * --- cipher->dat cipher data
+ */
+
+KTEXT
+create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long time_ws; /* Workstation time */
+ int n; /* Number of tickets */
+ unsigned long x_date; /* Principal's expiration date */
+ int kvno; /* Principal's key version number */
+ KTEXT cipher; /* Cipher text with tickets and
+ * session keys */
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ unsigned char *v = pkt->dat; /* Prot vers number */
+ unsigned char *t = (pkt->dat+1); /* Prot message type */
+ short w_l; /* Cipher length */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ if (n != 0)
+ *v = 3;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2), pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* Workstation timestamp */
+ bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+ /* Expiration date */
+ bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+
+ /* Now send the ciphertext and info to help decode it */
+ *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
+ w_l = (short) cipher->length;
+ bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
+ pkt->length += 2;
+ bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
+ cipher->length);
+ pkt->length += cipher->length;
+
+ /* And return the packet */
+ return pkt;
+}
diff --git a/eBones/krb/create_ciph.c b/eBones/krb/create_ciph.c
new file mode 100644
index 0000000..c3bc0db
--- /dev/null
+++ b/eBones/krb/create_ciph.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $
+ * $Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <strings.h>
+
+/*
+ * This routine is used by the authentication server to create
+ * a packet for its client, containing a ticket for the requested
+ * service (given in "tkt"), and some information about the ticket,
+ *
+ * Returns KSUCCESS no matter what.
+ *
+ * The length of the cipher is stored in c->length; the format of
+ * c->dat is as follows:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ *
+ * 8 bytes session session key for client, service
+ *
+ * string service service name
+ *
+ * string instance service instance
+ *
+ * string realm KDC realm
+ *
+ * unsigned char life ticket lifetime
+ *
+ * unsigned char kvno service key version number
+ *
+ * unsigned char tkt->length length of following ticket
+ *
+ * data tkt->dat ticket for service
+ *
+ * 4 bytes kdc_time KDC's timestamp
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+create_ciph(c, session, service, instance, realm, life, kvno, tkt,
+ kdc_time, key)
+ KTEXT c; /* Text block to hold ciphertext */
+ C_Block session; /* Session key to send to user */
+ char *service; /* Service name on ticket */
+ char *instance; /* Instance name on ticket */
+ char *realm; /* Realm of this KDC */
+ unsigned long life; /* Lifetime of the ticket */
+ int kvno; /* Key version number for service */
+ KTEXT tkt; /* The ticket for the service */
+ unsigned long kdc_time; /* KDC time */
+ C_Block key; /* Key to encrypt ciphertext with */
+{
+ char *ptr;
+ Key_schedule key_s;
+
+ ptr = (char *) c->dat;
+
+ bcopy((char *) session, ptr, 8);
+ ptr += 8;
+
+ (void) strcpy(ptr,service);
+ ptr += strlen(service) + 1;
+
+ (void) strcpy(ptr,instance);
+ ptr += strlen(instance) + 1;
+
+ (void) strcpy(ptr,realm);
+ ptr += strlen(realm) + 1;
+
+ *(ptr++) = (unsigned char) life;
+ *(ptr++) = (unsigned char) kvno;
+ *(ptr++) = (unsigned char) tkt->length;
+
+ bcopy((char *)(tkt->dat),ptr,tkt->length);
+ ptr += tkt->length;
+
+ bcopy((char *) &kdc_time,ptr,4);
+ ptr += 4;
+
+ /* guarantee null padded encrypted data to multiple of 8 bytes */
+ bzero(ptr, 7);
+
+ c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s,
+ key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/create_death_packet.c b/eBones/krb/create_death_packet.c
new file mode 100644
index 0000000..f747d6b
--- /dev/null
+++ b/eBones/krb/create_death_packet.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $
+ * $Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a packet to type AUTH_MSG_DIE which is sent to
+ * the Kerberos server to make it shut down. It is used only in the
+ * development environment.
+ *
+ * It takes a string "a_name" which is sent in the packet. A pointer
+ * to the packet is returned.
+ *
+ * The format of the killer packet is:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_DIE message type
+ *
+ * [least significant HOST_BYTE_ORDER byte order of sender
+ * bit of above field]
+ *
+ * string a_name presumably, name of
+ * principal sending killer
+ * packet
+ */
+
+#ifdef DEBUG
+KTEXT
+krb_create_death_packet(a_name)
+ char *a_name;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+
+ unsigned char *v = pkt->dat;
+ unsigned char *t = (pkt->dat+1);
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_DIE;
+ *t |= HOST_BYTE_ORDER;
+ (void) strcpy((char *) (pkt->dat+2),a_name);
+ pkt->length = 3 + strlen(a_name);
+ return pkt;
+}
+#endif /* DEBUG */
diff --git a/eBones/krb/create_ticket.c b/eBones/krb/create_ticket.c
new file mode 100644
index 0000000..984d8e9
--- /dev/null
+++ b/eBones/krb/create_ticket.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $
+ * $Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed. It then constructs a ticket and returns, leaving the
+ * newly created ticket in tkt.
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket. When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * tkt->length length of ticket (multiple of 8 bytes)
+ *
+ * tkt->dat:
+ *
+ * unsigned char flags namely, HOST_BYTE_ORDER
+ *
+ * string pname client's name
+ *
+ * string pinstance client's instance
+ *
+ * string prealm client's realm
+ *
+ * 4 bytes paddress client's address
+ *
+ * 8 bytes session session key
+ *
+ * 1 byte life ticket lifetime
+ *
+ * 4 bytes time_sec KDC timestamp
+ *
+ * string sname service's name
+ *
+ * string sinstance service's instance
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+{
+ Key_schedule key_s;
+ register char *data; /* running index into ticket */
+
+ tkt->length = 0; /* Clear previous data */
+ flags |= HOST_BYTE_ORDER; /* ticket byte order */
+ bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
+ data = ((char *)tkt->dat) + sizeof(flags);
+ (void) strcpy(data, pname);
+ data += 1 + strlen(pname);
+ (void) strcpy(data, pinstance);
+ data += 1 + strlen(pinstance);
+ (void) strcpy(data, prealm);
+ data += 1 + strlen(prealm);
+ bcopy((char *) &paddress, data, 4);
+ data += 4;
+
+ bcopy((char *) session, data, 8);
+ data += 8;
+ *(data++) = (char) life;
+ /* issue time */
+ bcopy((char *) &time_sec, data, 4);
+ data += 4;
+ (void) strcpy(data, sname);
+ data += 1 + strlen(sname);
+ (void) strcpy(data, sinstance);
+ data += 1 + strlen(sinstance);
+
+ /* guarantee null padded ticket to multiple of 8 bytes */
+ bzero(data, 7);
+ tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+ /* Check length of ticket */
+ if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+ bzero(tkt->dat, tkt->length);
+ tkt->length = 0;
+ return KFAILURE /* XXX */;
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,ENCRYPT);
+#endif
+ return 0;
+}
diff --git a/eBones/krb/debug_decl.c b/eBones/krb/debug_decl.c
new file mode 100644
index 0000000..1a0f6df
--- /dev/null
+++ b/eBones/krb/debug_decl.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $
+ * $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $";
+#endif lint
+
+/* Declare global debugging variables. */
+
+int krb_ap_req_debug = 0;
+int krb_debug = 0;
diff --git a/eBones/krb/decomp_ticket.c b/eBones/krb/decomp_ticket.c
new file mode 100644
index 0000000..181864c
--- /dev/null
+++ b/eBones/krb/decomp_ticket.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $
+ * $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine takes a ticket and pointers to the variables that
+ * should be filled in based on the information in the ticket. It
+ * fills in values for its arguments.
+ *
+ * Note: if the client realm field in the ticket is the null string,
+ * then the "prealm" variable is filled in with the local realm (as
+ * defined by KRB_REALM).
+ *
+ * If the ticket byte order is different than the host's byte order
+ * (as indicated by the byte order bit of the "flags" field), then
+ * the KDC timestamp "time_sec" is byte-swapped. The other fields
+ * potentially affected by byte order, "paddress" and "session" are
+ * not byte-swapped.
+ *
+ * The routine returns KFAILURE if any of the "pname", "pinstance",
+ * or "prealm" fields is too big, otherwise it returns KSUCCESS.
+ *
+ * The corresponding routine to generate tickets is create_ticket.
+ * When changes are made to this routine, the corresponding changes
+ * should also be made to that file.
+ *
+ * See create_ticket.c for the format of the ticket packet.
+ */
+
+decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
+ life, time_sec, sname, sinstance, key, key_s)
+ KTEXT tkt; /* The ticket to be decoded */
+ unsigned char *flags; /* Kerberos ticket flags */
+ char *pname; /* Authentication name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ unsigned long *paddress; /* Net address of entity
+ * requesting ticket */
+ C_Block session; /* Session key inserted in ticket */
+ int *life; /* Lifetime of the ticket */
+ unsigned long *time_sec; /* Issue time and date */
+ char *sname; /* Service name */
+ char *sinstance; /* Service instance */
+ C_Block key; /* Service's secret key
+ * (to decrypt the ticket) */
+ Key_schedule key_s; /* The precomputed key schedule */
+{
+ static int tkt_swap_bytes;
+ unsigned char *uptr;
+ char *ptr = (char *)tkt->dat;
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,DECRYPT);
+#endif /* ! NOENCRYPTION */
+
+ *flags = *ptr; /* get flags byte */
+ ptr += sizeof(*flags);
+ tkt_swap_bytes = 0;
+ if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
+ tkt_swap_bytes++;
+
+ if (strlen(ptr) > ANAME_SZ)
+ return(KFAILURE);
+ (void) strcpy(pname,ptr); /* pname */
+ ptr += strlen(pname) + 1;
+
+ if (strlen(ptr) > INST_SZ)
+ return(KFAILURE);
+ (void) strcpy(pinstance,ptr); /* instance */
+ ptr += strlen(pinstance) + 1;
+
+ if (strlen(ptr) > REALM_SZ)
+ return(KFAILURE);
+ (void) strcpy(prealm,ptr); /* realm */
+ ptr += strlen(prealm) + 1;
+ /* temporary hack until realms are dealt with properly */
+ if (*prealm == 0)
+ (void) strcpy(prealm,KRB_REALM);
+
+ bcopy(ptr,(char *)paddress,4); /* net address */
+ ptr += 4;
+
+ bcopy(ptr,(char *)session,8); /* session key */
+ ptr+= 8;
+#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
+ if (tkt_swap_bytes)
+ swap_C_Block(session);
+#endif
+
+ /* get lifetime, being certain we don't get negative lifetimes */
+ uptr = (unsigned char *) ptr++;
+ *life = (int) *uptr;
+
+ bcopy(ptr,(char *) time_sec,4); /* issue time */
+ ptr += 4;
+ if (tkt_swap_bytes)
+ swap_u_long(*time_sec);
+
+ (void) strcpy(sname,ptr); /* service name */
+ ptr += 1 + strlen(sname);
+
+ (void) strcpy(sinstance,ptr); /* instance */
+ ptr += 1 + strlen(sinstance);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/des_rw.c b/eBones/krb/des_rw.c
new file mode 100644
index 0000000..c958355
--- /dev/null
+++ b/eBones/krb/des_rw.c
@@ -0,0 +1,265 @@
+/* -
+ * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
+ * All rights reserved.
+ *
+ * This code is derived from a specification based on software
+ * which forms part of the 4.4BSD-Lite distribution, which was developed
+ * by the University of California and its contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the entire comment,
+ * including the above copyright notice, this list of conditions
+ * and the following disclaimer, verbatim, at the beginning of
+ * the source file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Geoffrey M. Rehmet
+ * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $
+ */
+
+/*
+ *
+ * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED.
+ *
+ */
+
+/*
+ * Routines for reading and writing DES encrypted messages onto sockets.
+ * (These routines will fail if non-blocking I/O is used.)
+ *
+ * When a message is written, its length is first transmitted as an int,
+ * in network byte order. The encrypted message is then transmitted,
+ * to a multiple of 8 bytes. Messages shorter than 8 bytes are right
+ * justified into a buffer of length 8 bytes, and the remainder of the
+ * buffer is filled with random garbage (before encryption):
+ *
+ * DDD -------->--+--------+
+ * | |
+ * +--+--+--+--+--+--+--+--+
+ * |x |x |x |x |x |D |D |D |
+ * +--+--+--+--+--+--+--+--+
+ * | garbage | data |
+ * | |
+ * +-----------------------+----> des_pcbc_encrypt() -->
+ *
+ * (Note that the length field sent before the actual message specifies
+ * the number of data bytes, not the length of the entire padded message.
+ *
+ * When data is read, if the message received is longer than the number
+ * of bytes requested, then the remaining bytes are stored until the
+ * following call to des_read(). If the number of bytes received is
+ * less then the number of bytes received, then only the number of bytes
+ * actually received is returned.
+ *
+ * This interface corresponds with the original des_rw.c, except for the
+ * bugs in des_read() in the original 4.4BSD version. (One bug is
+ * normally not visible, due to undocumented behaviour of
+ * des_pcbc_encrypt() in the original MIT libdes.)
+ *
+ * XXX Todo:
+ * 1) Give better error returns on writes
+ * 2) Improve error checking on reads
+ * 3) Get rid of need for extern decl. of krb_net_read()
+ * 4) Tidy garbage generation a bit
+ * 5) Make the above comment more readable
+ */
+
+#ifdef CRYPT
+#ifdef KERBEROS
+
+#ifndef BUFFER_LEN
+#define BUFFER_LEN 10240
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+extern int krb_net_read(int fd, void * data, size_t length);
+extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output,
+ register long length,
+ des_key_schedule schedule,
+ des_cblock *ivec,
+ int encrypt);
+
+static bit_64 des_key;
+static des_key_schedule key_sched;
+
+/*
+ * Buffer for storing extra data when more data is received, then was
+ * actually requested in des_read().
+ */
+static u_char des_buff[BUFFER_LEN];
+static u_char buffer[BUFFER_LEN];
+static unsigned stored = 0;
+static u_char *buff_ptr = buffer;
+
+/*
+ * Set the encryption key for des_read() and des_write().
+ * inkey is the initial vector for the DES encryption, while insched is
+ * the DES key, in unwrapped form.
+ */
+void des_set_key(inkey, insched)
+ bit_64 *inkey;
+ u_char *insched;
+{
+ bcopy(inkey, &des_key, sizeof(bit_64));
+ bcopy(insched, &key_sched, sizeof(des_key_schedule));
+}
+
+/*
+ * Clear the key schedule, and initial vector, which were previously
+ * stored in static vars by des_set_key().
+ */
+void des_clear_key()
+{
+ bzero(&des_key, sizeof(des_cblock));
+ bzero(&key_sched, sizeof(des_key_schedule));
+}
+
+int des_read(fd, buf, len)
+ int fd;
+ register char * buf;
+ int len;
+{
+ int msg_length; /* length of actual message data */
+ int pad_length; /* length of padded message */
+ int nread; /* number of bytes actually read */
+ int nreturned = 0;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ return(len);
+ } else {
+ if (stored) {
+ bcopy(buff_ptr, buf, stored);
+ nreturned = stored;
+ len -= stored;
+ stored = 0;
+ buff_ptr = buffer;
+ } else {
+ nreturned = 0;
+ buff_ptr = buffer;
+ }
+ }
+
+ nread = krb_net_read(fd, &msg_length, sizeof(msg_length));
+ if(nread != (int)(sizeof(msg_length)))
+ return(0);
+
+ msg_length = ntohl(msg_length);
+ pad_length = roundup(msg_length, 8);
+
+ nread = krb_net_read(fd, des_buff, pad_length);
+ if(nread != pad_length)
+ return(0);
+
+ des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr,
+ (msg_length < 8 ? 8 : msg_length),
+ key_sched, (des_cblock*) &des_key, DES_DECRYPT);
+
+
+ if(msg_length < 8)
+ buff_ptr += (8 - msg_length);
+ stored = msg_length;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ nreturned += len;
+ } else {
+ bcopy(buff_ptr, buf, stored);
+ nreturned += stored;
+ stored = 0;
+ }
+
+ return(nreturned);
+}
+
+
+/*
+ * Write a message onto a file descriptor (generally a socket), using
+ * DES to encrypt the message.
+ */
+int des_write(fd, buf, len)
+ int fd;
+ char * buf;
+ int len;
+{
+ static int seeded = 0;
+ char garbage[8];
+ long rnd;
+ int pad_len;
+ int write_len;
+ int nwritten = 0;
+ int i;
+ char *data;
+
+ if(len < 8) {
+ /*
+ * Right justify the message in 8 bytes of random garbage.
+ */
+ if(!seeded) {
+ seeded = 1;
+ srandom((unsigned)time(NULL));
+ }
+
+ for(i = 0 ; i < 8 ; i+= sizeof(long)) {
+ rnd = random();
+ bcopy(&rnd, garbage+i,
+ (i <= (8 - sizeof(long)))?sizeof(long):(8-i));
+ }
+ bcopy(buf, garbage + 8 - len, len);
+ data = garbage;
+ pad_len = 8;
+ } else {
+ data = buf;
+ pad_len = roundup(len, 8);
+ }
+
+ des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff,
+ (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT);
+
+
+ write_len = htonl(len);
+ if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len))
+ return(-1);
+ if(write(fd, des_buff, pad_len) != pad_len)
+ return(-1);
+
+ return(len);
+}
+
+#endif /* KERBEROS */
+#endif /* CRYPT */
diff --git a/eBones/krb/dest_tkt.c b/eBones/krb/dest_tkt.c
new file mode 100644
index 0000000..17c7855
--- /dev/null
+++ b/eBones/krb/dest_tkt.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $
+ * $Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+#include <errno.h>
+
+/*
+ * dest_tkt() is used to destroy the ticket store upon logout.
+ * If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
+ * Otherwise the function returns RET_OK on success, KFAILURE on
+ * failure.
+ *
+ * The ticket file (TKT_FILE) is defined in "krb.h".
+ */
+
+dest_tkt()
+{
+ char *file = TKT_FILE;
+ int i,fd;
+ extern int errno;
+ struct stat statb;
+ char buf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ errno = 0;
+ if (lstat(file,&statb) < 0)
+ goto out;
+
+ if (!(statb.st_mode & S_IFREG)
+#ifdef notdef
+ || statb.st_mode & 077
+#endif
+ )
+ goto out;
+
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out;
+
+ bzero(buf, BUFSIZ);
+
+ for (i = 0; i < statb.st_size; i += BUFSIZ)
+ if (write(fd, buf, BUFSIZ) != BUFSIZ) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+
+ (void) unlink(file);
+
+out:
+ if (errno == ENOENT) return RET_TKFIL;
+ else if (errno != 0) return KFAILURE;
+#ifdef TKT_SHMEM
+ /*
+ * handle the shared memory case
+ */
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
+ return(i);
+#endif /* TKT_SHMEM */
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/extract_ticket.c b/eBones/krb/extract_ticket.c
new file mode 100644
index 0000000..571d5da
--- /dev/null
+++ b/eBones/krb/extract_ticket.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $
+ * $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is obsolete.
+ *
+ * This routine accepts the ciphertext returned by kerberos and
+ * extracts the nth ticket. It also fills in the variables passed as
+ * session, liftime and kvno.
+ */
+
+extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket)
+ KTEXT cipher; /* The ciphertext */
+ int n; /* Which ticket */
+ char *session; /* The session key for this tkt */
+ int *lifetime; /* The life of this ticket */
+ int *kvno; /* The kvno for the service */
+ char *realm; /* Realm in which tkt issued */
+ KTEXT ticket; /* The ticket itself */
+{
+ char *ptr;
+ int i;
+
+ /* Start after the ticket lengths */
+ ptr = (char *) cipher->dat;
+ ptr = ptr + 1 + (int) *(cipher->dat);
+
+ /* Step through earlier tickets */
+ for (i = 1; i < n; i++)
+ ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
+ bcopy(ptr, (char *) session, 8); /* Save the session key */
+ ptr += 8;
+ *lifetime = *(ptr++); /* Save the life of the ticket */
+ *kvno = *(ptr++); /* Save the kvno */
+ (void) strcpy(realm,ptr); /* instance */
+ ptr += strlen(realm) + 1;
+
+ /* Save the ticket if its length is non zero */
+ ticket->length = *(cipher->dat+n);
+ if (ticket->length)
+ bcopy(ptr, (char *) (ticket->dat), ticket->length);
+}
diff --git a/eBones/krb/fgetst.c b/eBones/krb/fgetst.c
new file mode 100644
index 0000000..d938013
--- /dev/null
+++ b/eBones/krb/fgetst.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $
+ * $Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+
+/*
+ * fgetst takes a file descriptor, a character pointer, and a count.
+ * It reads from the file it has either read "count" characters, or
+ * until it reads a null byte. When finished, what has been read exists
+ * in "s". If "count" characters were actually read, the last is changed
+ * to a null, so the returned string is always null-terminated. fgetst
+ * returns the number of characters read, including the null terminator.
+ */
+
+fgetst(f, s, n)
+ FILE *f;
+ register char *s;
+ int n;
+{
+ register count = n;
+ int ch; /* NOT char; otherwise you don't see EOF */
+
+ while ((ch = getc(f)) != EOF && ch && --count) {
+ *s++ = ch;
+ }
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/krb/get_ad_tkt.c b/eBones/krb/get_ad_tkt.c
new file mode 100644
index 0000000..d8e1283
--- /dev/null
+++ b/eBones/krb/get_ad_tkt.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $
+ * $Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+#include <strings.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+extern int krb_debug;
+
+struct timeval tt_local = { 0, 0 };
+
+int swap_bytes;
+unsigned long rep_err_code;
+
+/*
+ * get_ad_tkt obtains a new service ticket from Kerberos, using
+ * the ticket-granting ticket which must be in the ticket file.
+ * It is typically called by krb_mk_req() when the client side
+ * of an application is creating authentication information to be
+ * sent to the server side.
+ *
+ * get_ad_tkt takes four arguments: three pointers to strings which
+ * contain the name, instance, and realm of the service for which the
+ * ticket is to be obtained; and an integer indicating the desired
+ * lifetime of the ticket.
+ *
+ * It returns an error status if the ticket couldn't be obtained,
+ * or AD_OK if all went well. The ticket is stored in the ticket
+ * cache.
+ *
+ * The request sent to the Kerberos ticket-granting service looks
+ * like this:
+ *
+ * pkt->dat
+ *
+ * TEXT original contents of authenticator+ticket
+ * pkt->dat built in krb_mk_req call
+ *
+ * 4 bytes time_ws always 0 (?)
+ * char lifetime lifetime argument passed
+ * string service service name argument
+ * string sinstance service instance arg.
+ *
+ * See "prot.h" for the reply packet layout and definitions of the
+ * extraction macros like pkt_version(), pkt_msg_type(), etc.
+ */
+
+get_ad_tkt(service,sinstance,realm,lifetime)
+ char *service;
+ char *sinstance;
+ char *realm;
+ int lifetime;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = & pkt_st; /* Packet to KDC */
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ static KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ static KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ CREDENTIALS cr;
+ int kvno; /* Kvno for session key */
+ char lrealm[REALM_SZ];
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ long time_ws = 0;
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ int msg_byte_order;
+ int kerror;
+ char rlm[REALM_SZ];
+ char *ptr;
+
+ unsigned long kdc_time; /* KDC time */
+
+ if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+ return(kerror);
+
+ /* Create skeleton of packet to be sent */
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+
+ pkt->length = 0;
+
+ /*
+ * Look for the session key (and other stuff we don't need)
+ * in the ticket file for krbtgt.realm@lrealm where "realm"
+ * is the service's realm (passed in "realm" argument) and
+ * lrealm is the realm of our initial ticket. If we don't
+ * have this, we will try to get it.
+ */
+
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+ /*
+ * If realm == lrealm, we have no hope, so let's not even try.
+ */
+ if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
+ return(AD_NOTGT);
+ else{
+ if ((kerror =
+ get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
+ return(kerror);
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
+ return(kerror);
+ }
+ }
+
+ /*
+ * Make up a request packet to the "krbtgt.realm@lrealm".
+ * Start by calling krb_mk_req() which puts ticket+authenticator
+ * into "pkt". Then tack other stuff on the end.
+ */
+
+ kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+
+ if (kerror)
+ return(AD_NOTGT);
+
+ /* timestamp */
+ bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (char) lifetime;
+ (void) strcpy((char *) (pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* Send the request to the local ticket-granting server */
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION )
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
+ if (swap_bytes)
+ swap_u_long(rep_err_code);
+ return(rep_err_code);
+
+ default:
+ return(INTK_PROT);
+ }
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length,
+ key_s,cr.session,DECRYPT);
+#endif
+ /* Get rid of all traces of key */
+ bzero((char *) cr.session, sizeof(key));
+ bzero((char *) key_s, sizeof(key_s));
+
+ ptr = (char *) cip->dat;
+
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ lifetime = (unsigned long) ptr[0];
+ kvno = (unsigned long) ptr[1];
+ tkt->length = (int) ptr[2];
+ ptr += 3;
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+ if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
+ kvno,tkt,tt_local.tv_sec))
+ return(kerror);
+
+ return(AD_OK);
+}
diff --git a/eBones/krb/get_admhst.c b/eBones/krb/get_admhst.c
new file mode 100644
index 0000000..c36e997
--- /dev/null
+++ b/eBones/krb/get_admhst.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $
+ * $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <string.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos database
+ * administration server can be found.
+ *
+ * krb_get_admhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer n, and
+ * returns (in h) the nth administrative host entry from the configuration
+ * file (KRB_CONF, defined in "krb.h") associated with the specified realm.
+ *
+ * On error, get_admhst returns KFAILURE. If all goes well, the routine
+ * returns KSUCCESS.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * a Kerberos admin server. In the long run, this functionality will be
+ * provided by a nameserver.
+ */
+
+krb_get_admhst(h, r, n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char scratch[64];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ return(KFAILURE);
+ }
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ /* error reading */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (!index(linebuf, '\n')) {
+ /* didn't all fit into buffer, punt */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ for (i = 0; i < n; ) {
+ /* run through the file, looking for admin host */
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ /* need to scan for a token after 'admin' to make sure that
+ admin matched correctly */
+ if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_cred.c b/eBones/krb/get_cred.c
new file mode 100644
index 0000000..baf7ae2
--- /dev/null
+++ b/eBones/krb/get_cred.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $
+ * $Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * krb_get_cred takes a service name, instance, and realm, and a
+ * structure of type CREDENTIALS to be filled in with ticket
+ * information. It then searches the ticket file for the appropriate
+ * ticket and fills in the structure with the corresponding
+ * information from the file. If successful, it returns KSUCCESS.
+ * On failure it returns a Kerberos error code.
+ */
+
+krb_get_cred(service,instance,realm,c)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ CREDENTIALS *c; /* Credentials struct */
+{
+ int tf_status; /* return value of tf function calls */
+
+ /* Open ticket file and lock it for shared reading */
+ if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Copy principal's name and instance into the CREDENTIALS struc c */
+
+ if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
+ (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
+ return (tf_status);
+
+ /* Search for requested service credentials and copy into c */
+
+ while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
+ /* Is this the right ticket? */
+ if ((strcmp(c->service,service) == 0) &&
+ (strcmp(c->instance,instance) == 0) &&
+ (strcmp(c->realm,realm) == 0))
+ break;
+ }
+ (void) tf_close();
+
+ if (tf_status == EOF)
+ return (GC_NOTKT);
+ return(tf_status);
+}
diff --git a/eBones/krb/get_in_tkt.c b/eBones/krb/get_in_tkt.c
new file mode 100644
index 0000000..5fb1560
--- /dev/null
+++ b/eBones/krb/get_in_tkt.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $
+ * $Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: passwd_to_key() converts
+ * a password into a DES key (prompting for the password if
+ * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
+ * a user.
+ */
+
+/*
+ * passwd_to_key(): given a password, return a DES key.
+ * There are extra arguments here which (used to be?)
+ * used by srvtab_to_key().
+ *
+ * If the "passwd" argument is not null, generate a DES
+ * key from it, using string_to_key().
+ *
+ * If the "passwd" argument is null, call des_read_password()
+ * to prompt for a password and then convert it into a DES key.
+ *
+ * In either case, the resulting key is put in the "key" argument,
+ * and 0 is returned.
+ */
+
+/*ARGSUSED */
+static int passwd_to_key(user,instance,realm,passwd,key)
+ char *user, *instance, *realm, *passwd;
+ C_Block key;
+{
+#ifdef NOENCRYPTION
+ if (!passwd)
+ placebo_read_password(key, "Password: ", 0);
+#else
+ if (passwd)
+ string_to_key(passwd,key);
+ else
+ des_read_password(key,"Password: ",0);
+#endif
+ return (0);
+}
+
+/*
+ * krb_get_pw_in_tkt() takes the name of the server for which the initial
+ * ticket is to be obtained, the name of the principal the ticket is
+ * for, the desired lifetime of the ticket, and the user's password.
+ * It passes its arguments on to krb_get_in_tkt(), which contacts
+ * Kerberos to get the ticket, decrypts it using the password provided,
+ * and stores it away for future use.
+ *
+ * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
+ * the name of a routine (passwd_to_key()) to be used to get the
+ * password in case the "password" argument is null and NULL for the
+ * decryption procedure indicating that krb_get_in_tkt should use the
+ * default method of decrypting the response from the KDC.
+ *
+ * The result of the call to krb_get_in_tkt() is returned.
+ */
+
+krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return(krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+ passwd_to_key, NULL, password));
+}
+
+#ifdef NOENCRYPTION
+/*
+ * $Source: /home/CVS/src/eBones/krb/get_in_tkt.c,v $
+ * $Author: g89r4222 $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine prints the supplied string to standard
+ * output as a prompt, and reads a password string without
+ * echoing.
+ */
+
+#ifndef lint
+static char rcsid_read_password_c[] =
+"Bones$Header: /home/CVS/src/eBones/krb/get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif lint
+
+#include <des.h>
+#include "conf.h"
+
+#include <stdio.h>
+#ifdef BSDUNIX
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+#else
+char *strcpy();
+int strcmp();
+#endif
+
+#ifdef BSDUNIX
+static jmp_buf env;
+#endif
+
+#ifdef BSDUNIX
+static void sig_restore();
+static push_signals(), pop_signals();
+int placebo_read_pw_string();
+#endif
+
+/*** Routines ****************************************************** */
+int
+placebo_read_password(k,prompt,verify)
+ des_cblock *k;
+ char *prompt;
+ int verify;
+{
+ int ok;
+ char key_string[BUFSIZ];
+
+#ifdef BSDUNIX
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+#endif
+
+ ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
+ if (ok == 0)
+ bzero(k, sizeof(C_Block));
+
+lose:
+ bzero(key_string, sizeof (key_string));
+ return ok;
+}
+
+/*
+ * This version just returns the string, doesn't map to key.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int
+placebo_read_pw_string(s,max,prompt,verify)
+ char *s;
+ int max;
+ char *prompt;
+ int verify;
+{
+ int ok = 0;
+ char *ptr;
+
+#ifdef BSDUNIX
+ jmp_buf old_env;
+ struct sgttyb tty_state;
+#endif
+ char key_string[BUFSIZ];
+
+ if (max > BUFSIZ) {
+ return -1;
+ }
+
+#ifdef BSDUNIX
+ bcopy(old_env, env, sizeof(env));
+ if (setjmp(env))
+ goto lose;
+
+ /* save terminal state*/
+ if (ioctl(0,TIOCGETP,&tty_state) == -1)
+ return -1;
+
+ push_signals();
+ /* Turn off echo */
+ tty_state.sg_flags &= ~ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state) == -1)
+ return -1;
+#endif
+ while (!ok) {
+ printf(prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(s,sizeof(s),0);
+ if (!strlen(s))
+ continue;
+#else
+ if (!fgets(s, max, stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(s, '\n')))
+ *ptr = '\0';
+#endif
+ if (verify) {
+ printf("\nVerifying, please re-enter %s",prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(key_string,sizeof(key_string),0);
+ if (!strlen(key_string))
+ continue;
+#else
+ if (!fgets(key_string, sizeof(key_string), stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(key_string, '\n')))
+ *ptr = '\0';
+#endif
+ if (strcmp(s,key_string)) {
+ printf("\n\07\07Mismatch - try again\n");
+ fflush(stdout);
+ continue;
+ }
+ }
+ ok = 1;
+ }
+
+#ifdef BSDUNIX
+lose:
+ if (!ok)
+ bzero(s, max);
+ printf("\n");
+ /* turn echo back on */
+ tty_state.sg_flags |= ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state))
+ ok = 0;
+ pop_signals();
+ bcopy(env, old_env, sizeof(env));
+#endif
+ if (verify)
+ bzero(key_string, sizeof (key_string));
+ s[max-1] = 0; /* force termination */
+ return !ok; /* return nonzero if not okay */
+}
+
+#ifdef BSDUNIX
+/*
+ * this can be static since we should never have more than
+ * one set saved....
+ */
+#ifdef POSIX
+static void (*old_sigfunc[NSIG])();
+#else
+static int (*old_sigfunc[NSIG])();
+#endif POSIX
+
+static push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}
+#endif
+#endif /* NOENCRYPTION */
diff --git a/eBones/krb/get_krbhst.c b/eBones/krb/get_krbhst.c
new file mode 100644
index 0000000..16c4ff2
--- /dev/null
+++ b/eBones/krb/get_krbhst.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $
+ * $Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos authenti-
+ * cation server can be found.
+ *
+ * krb_get_krbhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer, n, and
+ * returns (in h) the nth entry from the configuration file (KRB_CONF,
+ * defined in "krb.h") associated with the specified realm.
+ *
+ * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the
+ * configuration file does not exist, krb_get_krbhst will return KRB_HOST
+ * (also defined in "krb.h"). If all goes well, the routine returnes
+ * KSUCCESS.
+ *
+ * The KRB_CONF file contains the name of the local realm in the first
+ * line (not used by this routine), followed by lines indicating realm/host
+ * entries. The words "admin server" following the hostname indicate that
+ * the host provides an administrative database server.
+ *
+ * For example:
+ *
+ * ATHENA.MIT.EDU
+ * ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ * ATHENA.MIT.EDU kerberos-2.mit.edu
+ * LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * kerberos. In the long run, this functionality will be provided by a
+ * nameserver.
+ */
+
+krb_get_krbhst(h,r,n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ if (n==1) {
+ (void) strcpy(h,KRB_HOST);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+ if (fscanf(cnffile,"%s",tr) == EOF)
+ return(KFAILURE);
+ /* run through the file, looking for the nth server for this realm */
+ for (i = 1; i <= n;) {
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (sscanf(linebuf, "%s %s", tr, h) != 2)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_krbrlm.c b/eBones/krb/get_krbrlm.c
new file mode 100644
index 0000000..7df073d
--- /dev/null
+++ b/eBones/krb/get_krbrlm.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $
+ * $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_get_lrealm takes a pointer to a string, and a number, n. It fills
+ * in the string, r, with the name of the nth realm specified on the
+ * first line of the kerberos config file (KRB_CONF, defined in "krb.h").
+ * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the
+ * config file does not exist, and if n=1, a successful return will occur
+ * with r = KRB_REALM (also defined in "krb.h").
+ *
+ * NOTE: for archaic & compatibility reasons, this routine will only return
+ * valid results when n = 1.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ */
+
+krb_get_lrealm(r,n)
+ char *r;
+ int n;
+{
+ FILE *cnffile, *fopen();
+
+ if (n > 1)
+ return(KFAILURE); /* Temporary restriction */
+
+ if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+ if (n == 1) {
+ (void) strcpy(r, KRB_REALM);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+
+ if (fscanf(cnffile,"%s",r) != 1) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/get_phost.c b/eBones/krb/get_phost.c
new file mode 100644
index 0000000..9b12d10
--- /dev/null
+++ b/eBones/krb/get_phost.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $
+ * $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+
+char *index();
+
+/*
+ * This routine takes an alias for a host name and returns the first
+ * field, lower case, of its domain name. For example, if "menel" is
+ * an alias for host officially named "menelaus" (in /etc/hosts), for
+ * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
+ * is returned.
+ *
+ * This is done for historical Athena reasons: the Kerberos name of
+ * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
+ * where "host"is the lowercase for of the host name ("menelaus").
+ * This should go away: the instance should be the domain name
+ * (MENELAUS.MIT.EDU). But for now we need this routine...
+ *
+ * A pointer to the name is returned, if found, otherwise a pointer
+ * to the original "alias" argument is returned.
+ */
+
+char * krb_get_phost(alias)
+ char *alias;
+{
+ struct hostent *h;
+ char *phost = alias;
+ if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
+ char *p = index( h->h_name, '.' );
+ if (p)
+ *p = NULL;
+ p = phost = h->h_name;
+ do {
+ if (isupper(*p)) *p=tolower(*p);
+ } while (*p++);
+ }
+ return(phost);
+}
diff --git a/eBones/krb/get_pw_tkt.c b/eBones/krb/get_pw_tkt.c
new file mode 100644
index 0000000..48a003c
--- /dev/null
+++ b/eBones/krb/get_pw_tkt.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $
+ * $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $";
+#endif /* lint */
+
+
+#include <krb.h>
+
+/*
+ * Get a ticket for the password-changing server ("changepw.KRB_MASTER").
+ *
+ * Given the name, instance, realm, and current password of the
+ * principal for which the user wants a password-changing-ticket,
+ * return either:
+ *
+ * GT_PW_BADPW if current password was wrong,
+ * GT_PW_NULL if principal had a NULL password,
+ * or the result of the krb_get_pw_in_tkt() call.
+ *
+ * First, try to get a ticket for "user.instance@realm" to use the
+ * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
+ * The requested lifetime for the ticket is "1", and the current
+ * password is the "cpw" argument given.
+ *
+ * If the password was bad, give up.
+ *
+ * If the principal had a NULL password in the Kerberos database
+ * (indicating that the principal is known to Kerberos, but hasn't
+ * got a password yet), try instead to get a ticket for the principal
+ * "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
+ * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL
+ * if all goes well, otherwise the error.
+ *
+ * If this routine succeeds, a ticket and session key for either the
+ * principal "user.instance@realm" or "default.changepw@realm" to use
+ * the password-changing server will be in the user's ticket file.
+ */
+
+get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ int kerror;
+
+ kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
+ KRB_MASTER, 1, cpw);
+
+ if (kerror == INTK_BADPW)
+ return(GT_PW_BADPW);
+
+ if (kerror == KDC_NULL_KEY) {
+ kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
+ KRB_MASTER,1,"changepwkrb");
+ if (kerror)
+ return(kerror);
+ return(GT_PW_NULL);
+ }
+
+ return(kerror);
+}
diff --git a/eBones/krb/get_request.c b/eBones/krb/get_request.c
new file mode 100644
index 0000000..131ffd5
--- /dev/null
+++ b/eBones/krb/get_request.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $
+ * $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * This procedure is obsolete. It is used in the kerberos_slave
+ * code for Version 3 tickets.
+ *
+ * This procedure sets s_name, and instance to point to
+ * the corresponding fields from tne nth request in the packet.
+ * it returns the lifetime requested. Garbage will be returned
+ * if there are less than n requests in the packet.
+ */
+
+get_request(pkt, n, s_name, instance)
+ KTEXT pkt; /* The packet itself */
+ int n; /* Which request do we want */
+ char **s_name; /* Service name to be filled in */
+ char **instance; /* Instance name to be filled in */
+{
+ /* Go to the beginning of the request list */
+ char *ptr = (char *) pkt_a_realm(pkt) + 6 +
+ strlen((char *)pkt_a_realm(pkt));
+
+ /* Read requests until we hit the right one */
+ while (n-- > 1) {
+ ptr++;
+ ptr += 1 + strlen(ptr);
+ ptr += 1 + strlen(ptr);
+ }
+
+ /* Set the arguments to point to the right place */
+ *s_name = 1 + ptr;
+ *instance = 2 + ptr + strlen(*s_name);
+
+ /* Return the requested lifetime */
+ return((int) *ptr);
+}
diff --git a/eBones/krb/get_svc_in_tkt.c b/eBones/krb/get_svc_in_tkt.c
new file mode 100644
index 0000000..6d9702f
--- /dev/null
+++ b/eBones/krb/get_svc_in_tkt.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $
+ * $Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: srvtab_to_key(), which gets
+ * a server's key from a srvtab file, and krb_get_svc_in_tkt() which
+ * gets an initial ticket for a server.
+ */
+
+/*
+ * srvtab_to_key(): given a "srvtab" file (where the keys for the
+ * service on a host are stored), return the private key of the
+ * given service (user.instance@realm).
+ *
+ * srvtab_to_key() passes its arguments on to read_service_key(),
+ * plus one additional argument, the key version number.
+ * (Currently, the key version number is always 0; this value
+ * is treated as a wildcard by read_service_key().)
+ *
+ * If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
+ * is passed in its place.
+ *
+ * It returns the return value of the read_service_key() call.
+ * The service key is placed in "key".
+ */
+
+static int srvtab_to_key(user, instance, realm, srvtab, key)
+ char *user, *instance, *realm, *srvtab;
+ C_Block key;
+{
+ if (!srvtab)
+ srvtab = KEYFILE;
+
+ return(read_service_key(user, instance, realm, 0, srvtab,
+ (char *)key));
+}
+
+/*
+ * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
+ * plus two additional arguments: a pointer to the srvtab_to_key()
+ * function to be used to get the key from the key file and a NULL
+ * for the decryption procedure indicating that krb_get_in_tkt should
+ * use the default method of decrypting the response from the KDC.
+ *
+ * It returns the return value of the krb_get_in_tkt() call.
+ */
+
+krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return(krb_get_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab_to_key, NULL, srvtab));
+}
diff --git a/eBones/krb/get_tf_fullname.c b/eBones/krb/get_tf_fullname.c
new file mode 100644
index 0000000..753ad1e
--- /dev/null
+++ b/eBones/krb/get_tf_fullname.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $
+ * $Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+#include <stdio.h>
+
+/*
+ * This file contains a routine to extract the fullname of a user
+ * from the ticket file.
+ */
+
+/*
+ * krb_get_tf_fullname() takes four arguments: the name of the
+ * ticket file, and variables for name, instance, and realm to be
+ * returned in. Since the realm of a ticket file is not really fully
+ * supported, the realm used will be that of the the first ticket in
+ * the file as this is the one that was obtained with a password by
+ * krb_get_in_tkt().
+ */
+
+krb_get_tf_fullname(ticket_file, name, instance, realm)
+ char *ticket_file;
+ char *name;
+ char *instance;
+ char *realm;
+{
+ int tf_status;
+ CREDENTIALS c;
+
+ if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
+ ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
+ return (tf_status);
+
+ if (name)
+ strcpy(name, c.pname);
+ if (instance)
+ strcpy(instance, c.pinst);
+ if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
+ if (realm)
+ strcpy(realm, c.realm);
+ }
+ else {
+ if (tf_status == EOF)
+ return(KFAILURE);
+ else
+ return(tf_status);
+ }
+ (void) tf_close();
+
+ return(tf_status);
+}
diff --git a/eBones/krb/get_tf_realm.c b/eBones/krb/get_tf_realm.c
new file mode 100644
index 0000000..f405dcb
--- /dev/null
+++ b/eBones/krb/get_tf_realm.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $
+ * $Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * This file contains a routine to extract the realm of a kerberos
+ * ticket file.
+ */
+
+/*
+ * krb_get_tf_realm() takes two arguments: the name of a ticket
+ * and a variable to store the name of the realm in.
+ *
+ */
+
+krb_get_tf_realm(ticket_file, realm)
+ char *ticket_file;
+ char *realm;
+{
+ return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
+}
diff --git a/eBones/krb/getrealm.c b/eBones/krb/getrealm.c
new file mode 100644
index 0000000..96e9588
--- /dev/null
+++ b/eBones/krb/getrealm.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * routine to convert hostname into realm name.
+ *
+ * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $
+ * $Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $";
+#endif lint
+
+#include <strings.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <krb.h>
+#include <sys/param.h>
+
+/* for Ultrix and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+/*
+ * krb_realmofhost.
+ * Given a fully-qualified domain-style primary host name,
+ * return the name of the Kerberos realm for the host.
+ * If the hostname contains no discernable domain, or an error occurs,
+ * return the local realm name, as supplied by get_krbrlm().
+ * If the hostname contains a domain, but no translation is found,
+ * the hostname's domain is converted to upper-case and returned.
+ *
+ * The format of each line of the translation file is:
+ * domain_name kerberos_realm
+ * -or-
+ * host_name kerberos_realm
+ *
+ * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
+ * host names should be in the usual form (e.g. FOO.BAR.BAZ)
+ */
+
+static char ret_realm[REALM_SZ+1];
+
+char *
+krb_realmofhost(host)
+char *host;
+{
+ char *domain;
+ FILE *trans_file;
+ char trans_host[MAXHOSTNAMELEN+1];
+ char trans_realm[REALM_SZ+1];
+ int retval;
+
+ domain = index(host, '.');
+
+ /* prepare default */
+ if (domain) {
+ char *cp;
+
+ strncpy(ret_realm, &domain[1], REALM_SZ);
+ ret_realm[REALM_SZ] = '\0';
+ /* Upper-case realm */
+ for (cp = ret_realm; *cp; cp++)
+ if (islower(*cp))
+ *cp = toupper(*cp);
+ } else {
+ krb_get_lrealm(ret_realm, 1);
+ }
+
+ if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
+ /* krb_errno = KRB_NO_TRANS */
+ return(ret_realm);
+ }
+ while (1) {
+ if ((retval = fscanf(trans_file, "%s %s",
+ trans_host, trans_realm)) != 2) {
+ if (retval == EOF) {
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ continue; /* ignore broken lines */
+ }
+ trans_host[MAXHOSTNAMELEN] = '\0';
+ trans_realm[REALM_SZ] = '\0';
+ if (!strcasecmp(trans_host, host)) {
+ /* exact match of hostname, so return the realm */
+ (void) strcpy(ret_realm, trans_realm);
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ if ((trans_host[0] == '.') && domain) {
+ /* this is a domain match */
+ if (!strcasecmp(trans_host, domain)) {
+ /* domain match, save for later */
+ (void) strcpy(ret_realm, trans_realm);
+ continue;
+ }
+ }
+ }
+}
diff --git a/eBones/krb/getst.c b/eBones/krb/getst.c
new file mode 100644
index 0000000..edd55ec
--- /dev/null
+++ b/eBones/krb/getst.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $
+ * $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $";
+#endif /* lint */
+
+/*
+ * getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. getst() returns the number of characters read, including
+ * the null terminator.
+ */
+
+getst(fd, s, n)
+ int fd;
+ register char *s;
+{
+ register count = n;
+ while (read(fd, s, 1) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/krb/in_tkt.c b/eBones/krb/in_tkt.c
new file mode 100644
index 0000000..53510da
--- /dev/null
+++ b/eBones/krb/in_tkt.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $
+ * $Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+extern int krb_debug;
+
+/*
+ * in_tkt() is used to initialize the ticket store. It creates the
+ * file to contain the tickets and writes the given user's name "pname"
+ * and instance "pinst" in the file. in_tkt() returns KSUCCESS on
+ * success, or KFAILURE if something goes wrong.
+ */
+
+in_tkt(pname,pinst)
+ char *pname;
+ char *pinst;
+{
+ int tktfile;
+ uid_t me, metoo;
+ struct stat buf;
+ int count;
+ char *file = TKT_FILE;
+ int fd;
+ register int i;
+ char charbuf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ me = getuid ();
+ metoo = geteuid();
+ if (lstat(file,&buf) == 0) {
+ if (buf.st_uid != me && me == 0) {
+ unlink(file);
+ } else {
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",file);
+ return(KFAILURE);
+ }
+ /* file already exists, and permissions appear ok, so nuke it */
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out; /* can't zero it, but we can still try truncating it */
+
+ bzero(charbuf, sizeof(charbuf));
+
+ for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+ if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+ }
+ }
+ out:
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary).
+ This isn't a security problem, since the ticket file, if it already
+ exists, has the right uid (== ruid) and mode. */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid2");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+ if (lstat(file,&buf) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ count = strlen(pname)+1;
+ if (write(tktfile,pname,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ count = strlen(pinst)+1;
+ if (write(tktfile,pinst,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ (void) close(tktfile);
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ return(krb_shm_create(shmidname));
+#else /* !TKT_SHMEM */
+ return(KSUCCESS);
+#endif /* TKT_SHMEM */
+}
diff --git a/eBones/krb/k_gethostname.c b/eBones/krb/k_gethostname.c
new file mode 100644
index 0000000..e5c11ca
--- /dev/null
+++ b/eBones/krb/k_gethostname.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $
+ * $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $";
+#endif /* lint */
+
+#ifndef PC
+#ifndef BSD42
+/* teach me how to k_gethostname for your system here */
+#endif
+#endif
+
+#ifdef PC
+#include <stdio.h>
+typedef long in_name;
+#include "custom.h" /* where is this file? */
+extern get_custom();
+#define LEN 64 /* just a guess */
+#endif /* PC */
+
+/*
+ * Return the local host's name in "name", up to "namelen" characters.
+ * "name" will be null-terminated if "namelen" is big enough.
+ * The return code is 0 on success, -1 on failure. (The calling
+ * interface is identical to gethostname(2).)
+ *
+ * Currently defined for BSD 4.2 and PC. The BSD version just calls
+ * gethostname(); the PC code was taken from "kinit.c", and may or may
+ * not work.
+ */
+
+k_gethostname(name, namelen)
+ char *name;
+{
+#ifdef BSD42
+ return gethostname(name, namelen);
+#endif
+
+#ifdef PC
+ char buf[LEN];
+ char b1, b2, b3, b4;
+ register char *ptr;
+
+ get_custom(); /* should check for errors,
+ * return -1 on failure */
+ ptr = (char *) &(custom.c_me);
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr;
+ (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4);
+ if (strlen(buf) > namelen)
+ fprintf(stderr, "gethostname: namelen too small; truncating");
+ strnpcy(name, buf, namelen);
+ return 0;
+#endif
+}
diff --git a/eBones/krb/klog.c b/eBones/krb/klog.c
new file mode 100644
index 0000000..b530e8b
--- /dev/null
+++ b/eBones/krb/klog.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $
+ * $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static int is_open;
+static char logtxt[1000];
+
+/*
+ * This file contains two logging routines: kset_logfile()
+ * to determine the file to which log entries should be written;
+ * and klog() to write log entries to the file.
+ */
+
+/*
+ * klog() is used to add entries to the logfile (see kset_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format" string.
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * If the given log type "type" is unknown, or if the log file
+ * cannot be opened, no entry is made to the log file.
+ *
+ * The return value is always a pointer to the formatted log
+ * text string "logtxt".
+ */
+
+char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ int type;
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ char *month_sname();
+ struct tm *tm;
+ static int logtype_array[NLOGTYPE] = {0,0};
+ static int array_initialized;
+
+ if (!(array_initialized++)) {
+ logtype_array[L_NET_ERR] = 1;
+ logtype_array[L_KRB_PERR] = 1;
+ logtype_array[L_KRB_PWARN] = 1;
+ logtype_array[L_APPL_REQ] = 1;
+ logtype_array[L_INI_REQ] = 1;
+ logtype_array[L_DEATH_REQ] = 1;
+ logtype_array[L_NTGT_INTK] = 1;
+ logtype_array[L_ERR_SEXP] = 1;
+ logtype_array[L_ERR_MKV] = 1;
+ logtype_array[L_ERR_NKY] = 1;
+ logtype_array[L_ERR_NUN] = 1;
+ logtype_array[L_ERR_UNK] = 1;
+ }
+
+ (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+
+ if (!logtype_array[type])
+ return(logtxt);
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return(logtxt);
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,"%s\n",logtxt);
+ (void) fclose(logfile);
+ return(logtxt);
+}
+
+/*
+ * kset_logfile() changes the name of the file to which
+ * messages are logged. If kset_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+kset_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
diff --git a/eBones/krb/kname_parse.c b/eBones/krb/kname_parse.c
new file mode 100644
index 0000000..dd5fe0b
--- /dev/null
+++ b/eBones/krb/kname_parse.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $
+ * $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/* max size of full name */
+#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
+
+#define NAME 0 /* which field are we in? */
+#define INST 1
+#define REALM 2
+
+extern char *krb_err_txt[];
+
+/*
+ * This file contains four routines for handling Kerberos names.
+ *
+ * kname_parse() breaks a Kerberos name into its name, instance,
+ * and realm components.
+ *
+ * k_isname(), k_isinst(), and k_isrealm() check a given string to see if
+ * it's a syntactically legitimate respective part of a Kerberos name,
+ * returning 1 if it is, 0 if it isn't.
+ *
+ * Definition of "syntactically legitimate" names is according to
+ * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
+ * names", version dated 21 Dec 1987.
+ * /
+
+/*
+ * kname_parse() takes a Kerberos name "fullname" of the form:
+ *
+ * username[.instance][@realm]
+ *
+ * and returns the three components ("name", "instance", and "realm"
+ * in the example above) in the given arguments "np", "ip", and "rp".
+ *
+ * If successful, it returns KSUCCESS. If there was an error,
+ * KNAME_FMT is returned.
+ */
+
+kname_parse(np, ip, rp, fullname)
+ char *np, *ip, *rp, *fullname;
+{
+ static char buf[FULL_SZ];
+ char *rnext, *wnext; /* next char to read, write */
+ register char c;
+ int backslash;
+ int field;
+
+ backslash = 0;
+ rnext = buf;
+ wnext = np;
+ field = NAME;
+
+ if (strlen(fullname) > FULL_SZ)
+ return KNAME_FMT;
+ (void) strcpy(buf, fullname);
+
+ while (c = *rnext++) {
+ if (backslash) {
+ *wnext++ = c;
+ backslash = 0;
+ continue;
+ }
+ switch (c) {
+ case '\\':
+ backslash++;
+ break;
+ case '.':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *wnext = '\0';
+ field = INST;
+ wnext = ip;
+ break;
+ case INST:
+ return KNAME_FMT;
+ /* break; */
+ case REALM:
+ *wnext++ = c;
+ break;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ case '@':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *ip = '\0';
+ /* fall through */
+ case INST:
+ *wnext = '\0';
+ field = REALM;
+ wnext = rp;
+ break;
+ case REALM:
+ return KNAME_FMT;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ default:
+ *wnext++ = c;
+ }
+ }
+ *wnext = '\0';
+ if ((strlen(np) > ANAME_SZ - 1) ||
+ (strlen(ip) > INST_SZ - 1) ||
+ (strlen(rp) > REALM_SZ - 1))
+ return KNAME_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * k_isname() returns 1 if the given name is a syntactically legitimate
+ * Kerberos name; returns 0 if it's not.
+ */
+
+k_isname(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > ANAME_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * k_isinst() returns 1 if the given name is a syntactically legitimate
+ * Kerberos instance; returns 0 if it's not.
+ */
+
+k_isinst(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (strlen(s) > INST_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+/*
+ * k_isrealm() returns 1 if the given name is a syntactically legitimate
+ * Kerberos realm; returns 0 if it's not.
+ */
+
+k_isrealm(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > REALM_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
diff --git a/eBones/krb/kntoln.c b/eBones/krb/kntoln.c
new file mode 100644
index 0000000..62ec1b5
--- /dev/null
+++ b/eBones/krb/kntoln.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $
+ * $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_kntoln converts an auth name into a local name by looking up
+ * the auth name in the /etc/aname file. The format of the aname
+ * file is:
+ *
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | anl | inl | rll | lnl | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | 1by | 1by | 1by | 1by | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ *
+ * If the /etc/aname file can not be opened it will set the
+ * local name to the auth name. Thus, in this case it performs as
+ * the identity function.
+ *
+ * The name instance and realm are passed to krb_kntoln through
+ * the AUTH_DAT structure (ad).
+ *
+ * Now here's what it *really* does:
+ *
+ * Given a Kerberos name in an AUTH_DAT structure, check that the
+ * instance is null, and that the realm is the same as the local
+ * realm, and return the principal's name in "lname". Return
+ * KSUCCESS if all goes well, otherwise KFAILURE.
+ */
+
+krb_kntoln(ad,lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ static char lrealm[REALM_SZ] = "";
+
+ if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
+ return(KFAILURE);
+
+ if (strcmp(ad->pinst,""))
+ return(KFAILURE);
+ if (strcmp(ad->prealm,lrealm))
+ return(KFAILURE);
+ (void) strcpy(lname,ad->pname);
+ return(KSUCCESS);
+}
diff --git a/eBones/krb/kparse.c b/eBones/krb/kparse.c
new file mode 100644
index 0000000..d79f1cf
--- /dev/null
+++ b/eBones/krb/kparse.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Purpose:
+ * This module was developed to parse the "~/.klogin" files for
+ * Kerberos-authenticated rlogin/rcp/rsh services. However, it is
+ * general purpose and can be used to parse any such parameter file.
+ *
+ * The parameter file should consist of one or more entries, with each
+ * entry on a separate line and consisting of zero or more
+ * "keyword=value" combinations. The keyword is case insensitive, but
+ * the value is not. Any string may be enclosed in quotes, and
+ * c-style "\" literals are supported. A comma may be used to
+ * separate the k/v combinations, and multiple commas are ignored.
+ * Whitespace (blank or tab) may be used freely and is ignored.
+ *
+ * Full error processing is available. When PS_BAD_KEYWORD or
+ * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
+ * contains a meaningful error message.
+ *
+ * Keywords and their default values are programmed by an external
+ * table.
+ *
+ * Routines:
+ * fGetParameterSet() parse one line of the parameter file
+ * fGetKeywordValue() parse one "keyword=value" combo
+ * fGetToken() parse one token
+ *
+ *
+ * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
+ * $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <ctype.h>
+#include <kparse.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define void int
+
+#define MAXKEY 80
+#define MAXVALUE 80
+
+char *malloc();
+char *strcpy();
+
+int LineNbr=1; /* current line nbr in parameter file */
+char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX,
+ * or PS_BAD_KEYWORD is returned by
+ * fGetKeywordValue or fGetParameterSet */
+
+int fGetParameterSet( fp,parm,parmcount )
+ FILE *fp;
+ parmtable parm[];
+ int parmcount;
+{
+ int rc,i;
+ char keyword[MAXKEY];
+ char value[MAXVALUE];
+
+ while (TRUE) {
+ rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
+
+ switch (rc) {
+
+ case KV_EOF:
+ return(PS_EOF);
+
+ case KV_EOL:
+ return(PS_OKAY);
+
+ case KV_SYNTAX:
+ return(PS_SYNTAX);
+
+ case KV_OKAY:
+ /*
+ * got a reasonable keyword/value pair. Search the
+ * parameter table to see if we recognize the keyword; if
+ * not, return an error. If we DO recognize it, make sure
+ * it has not already been given. If not already given,
+ * save the value.
+ */
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(strutol(keyword),parm[i].keyword)==0) {
+ if (parm[i].value) {
+ sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ parm[i].value = strsave( value );
+ break;
+ }
+ }
+ if (i >= parmcount) {
+ sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ break;
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ break;
+ }
+ }
+}
+
+/*
+ * Routine: ParmCompare
+ *
+ * Purpose:
+ * ParmCompare checks a specified value for a particular keyword.
+ * fails if keyword not found or keyword found but the value was
+ * different. Like strcmp, ParmCompare returns 0 for a match found, -1
+ * otherwise
+ */
+int ParmCompare( parm, parmcount, keyword, value )
+ parmtable parm[];
+ int parmcount;
+ char *keyword;
+ char *value;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(parm[i].keyword,keyword)==0) {
+ if (parm[i].value) {
+ return(strcmp(parm[i].value,value));
+ } else {
+ return(strcmp(parm[i].defvalue,value));
+ }
+ }
+ }
+ return(-1);
+}
+
+void FreeParameterSet(parm,parmcount)
+ parmtable parm[];
+ int parmcount;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (parm[i].value) {
+ free(parm[i].value);
+ parm[i].value = (char *)NULL;
+ }
+ }
+}
+
+int fGetKeywordValue( fp, keyword, klen, value, vlen )
+ FILE *fp;
+ char *keyword;
+ int klen;
+ char *value;
+ int vlen;
+{
+ int rc;
+ int gotit;
+
+ *keyword = *value = '\0'; /* preset strings to NULL */
+
+ /*
+ * Looking for a keyword.
+ * return an exception for EOF or BAD_QSTRING
+ * ignore leading WHITEspace
+ * ignore any number of leading commas
+ * newline means we have all the parms for this
+ * statement; give an indication that there is
+ * nothing more on this line.
+ * stop looking if we find QSTRING, STRING, or NUMBER
+ * return syntax error for any other PUNKtuation
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,keyword,klen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ return(KV_EOF);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",keyword)==0) {
+ return(KV_EOL);
+ } else if (strcmp(",",keyword)!=0) {
+ sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ break;
+
+ default:
+ sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while (!gotit);
+
+ /*
+ * now we expect an equal sign.
+ * skip any whitespace
+ * stop looking if we find an equal sign
+ * anything else causes a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,
+ "expecting \'=\', found unterminated string \"%s",
+ value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("=",value)==0) {
+ gotit = TRUE;
+ } else {
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting \"=\", found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",keyword);
+ }
+ return(KV_SYNTAX);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
+ return(KV_SYNTAX);
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting \'=\', found EOF");
+ return(KV_SYNTAX);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+
+ /*
+ * got the keyword and equal sign, now get a value.
+ * ignore any whitespace
+ * any punctuation is a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting rvalue, found EOF");
+ return(KV_SYNTAX);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting rvalue, found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",value);
+ }
+ return(KV_SYNTAX);
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ return(KV_OKAY);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+ /*NOTREACHED*/
+}
+
+/*
+ * Routine Name: fGetToken
+ *
+ * Function: read the next token from the specified file.
+ * A token is defined as a group of characters
+ * terminated by a white space char (SPACE, CR,
+ * LF, FF, TAB). The token returned is stripped of
+ * both leading and trailing white space, and is
+ * terminated by a NULL terminator. An alternate
+ * definition of a token is a string enclosed in
+ * single or double quotes.
+ *
+ * Explicit Parameters:
+ * fp pointer to the input FILE
+ * dest pointer to destination buffer
+ * maxlen length of the destination buffer. The buffer
+ * length INCLUDES the NULL terminator.
+ *
+ * Implicit Parameters: stderr where the "token too long" message goes
+ *
+ * External Procedures: fgetc
+ *
+ * Side Effects: None
+ *
+ * Return Value: A token classification value, as
+ * defined in kparse.h. Note that the
+ * classification for end of file is
+ * always zero.
+ */
+int fGetToken(fp, dest, maxlen)
+ FILE *fp;
+ char *dest;
+ int maxlen;
+{
+ int ch='\0';
+ int len=0;
+ char *p = dest;
+ int digits;
+
+ ch=fGetChar(fp);
+
+ /*
+ * check for a quoted string. If found, take all characters
+ * that fit until a closing quote is found. Note that this
+ * algorithm will not behave well for a string which is too long.
+ */
+ if (ISQUOTE(ch)) {
+ int done = FALSE;
+ do {
+ ch = fGetChar(fp);
+ done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
+ ||ISQUOTE(ch));
+ if (ch=='\\')
+ ch = fGetLiteral(fp);
+ if (!done)
+ *p++ = ch;
+ else if ((ch!=EOF) && !ISQUOTE(ch))
+ fUngetChar(ch,fp);
+ } while (!done);
+ *p = '\0';
+ if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
+ return(GTOK_QSTRING);
+ }
+
+ /*
+ * Not a quoted string. If its a token character (rules are
+ * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
+ * token chars following it until we run out of space.
+ */
+ digits=TRUE;
+ if (ISTOKENCHAR(ch)) {
+ while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
+ if (!isdigit(ch)) digits=FALSE;
+ *p++ = ch;
+ len++;
+ ch = fGetChar(fp);
+ };
+ *p = '\0';
+
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ if (digits) {
+ return(GTOK_NUMBER);
+ } else {
+ return(GTOK_STRING);
+ }
+ }
+
+ /*
+ * Neither a quoted string nor a token character. Return a string
+ * with just that one character in it.
+ */
+ if (ch==EOF) {
+ return(GTOK_EOF);
+ }
+ if (!ISWHITESPACE(ch)) {
+ *p++ = ch;
+ *p='\0';
+ } else {
+ *p++ = ' '; /* white space is always the
+ * blank character */
+ *p='\0';
+ /*
+ * The character is a white space. Flush all additional white
+ * space.
+ */
+ while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
+ ;
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ return(GTOK_WHITE);
+ }
+ return(GTOK_PUNK);
+}
+
+/*
+ * fGetLiteral is called after we find a '\' in the input stream. A
+ * string of numbers following the backslash are converted to the
+ * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
+ * are all supported. If the char after the \ is not a number, we
+ * special case certain values (\n, \f, \r, \b) or return a literal
+ * otherwise (useful for \", for example).
+ */
+fGetLiteral(fp)
+ FILE *fp;
+{
+ int ch;
+ int n=0;
+ int base;
+
+ ch = fGetChar(fp);
+
+ if (!isdigit(ch)) {
+ switch (ch) {
+ case 'n': return('\n');
+ case 'f': return('\f');
+ case 'r': return('\r');
+ case 'b': return('\b');
+ default: return(ch);
+ }
+ }
+
+ /*
+ * got a number. might be decimal (no prefix), octal (prefix 0),
+ * or hexadecimal (prefix 0x). Set the base appropriately.
+ */
+ if (ch!='0') {
+ base=10; /* its a decimal number */
+ } else {
+ /*
+ * found a zero, its either hex or octal
+ */
+ ch = fGetChar(fp);
+ if ((ch!='x') && (ch!='X')) {
+ base=010;
+ } else {
+ ch = fGetChar(fp);
+ base=0x10;
+ }
+ }
+
+ switch (base) {
+
+ case 010: /* octal */
+ while (ISOCTAL(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+
+ case 10: /* decimal */
+ while (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+ case 0x10: /* hexadecimal */
+ while (isxdigit(ch)) {
+ if (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ } else {
+ n = (n*base) + toupper(ch) - 'A' + 0xA ;
+ }
+ ch = fGetChar(fp);
+ }
+ break;
+ default:
+ fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
+ exit(1);
+ break;
+ }
+ fUngetChar(ch,fp);
+ return(n);
+}
+
+/*
+ * exactly the same as ungetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fUngetChar(ch,fp)
+ int ch;
+ FILE *fp;
+{
+ if (ch=='\n') LineNbr--;
+ return(ungetc(ch,fp));
+}
+
+
+/*
+ * exactly the same as fgetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fGetChar(fp)
+ FILE *fp;
+{
+ int ch = fgetc(fp);
+ if (ch=='\n') LineNbr++;
+ return(ch);
+}
+
+
+/*
+ * Routine Name: strsave
+ *
+ * Function: return a pointer to a saved copy of the
+ * input string. the copy will be allocated
+ * as large as necessary.
+ *
+ * Explicit Parameters: pointer to string to save
+ *
+ * Implicit Parameters: None
+ *
+ * External Procedures: malloc,strcpy,strlen
+ *
+ * Side Effects: None
+ *
+ * Return Value: pointer to copied string
+ *
+ */
+char * strsave(p)
+ char *p;
+{
+ return(strcpy(malloc(strlen(p)+1),p));
+}
+
+
+/*
+ * strutol changes all characters in a string to lower case, in place.
+ * the pointer to the beginning of the string is returned.
+ */
+
+char * strutol( start )
+ char *start;
+{
+ char *q;
+ for (q=start; *q; q++)
+ if (isupper(*q))
+ *q=tolower(*q);
+ return(start);
+}
+
+#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
+
+#define MAXTOKEN 100
+
+char *pgm = "gettoken";
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char *p;
+ int type;
+ FILE *fp;
+
+ if (--argc) {
+ fp = fopen(*++argv,"ra");
+ if (fp == (FILE *)NULL) {
+ fprintf(stderr,"can\'t open \"%s\"\n",*argv);
+ }
+ } else
+ fp = stdin;
+
+ p = malloc(MAXTOKEN);
+ while (type = fGetToken(fp,p,MAXTOKEN)) {
+ switch(type) {
+ case GTOK_BAD_QSTRING:
+ printf("BAD QSTRING!\t");
+ break;
+ case GTOK_EOF:
+ printf("EOF!\t");
+ break;
+ case GTOK_QSTRING:
+ printf("QSTRING\t");
+ break;
+ case GTOK_STRING:
+ printf("STRING\t");
+ break;
+ case GTOK_NUMBER:
+ printf("NUMBER\t");
+ break;
+ case GTOK_PUNK:
+ printf("PUNK\t");
+ break;
+ case GTOK_WHITE:
+ printf("WHITE\t");
+ break;
+ default:
+ printf("HUH?\t");
+ break;
+ }
+ if (*p=='\n')
+ printf("\\n\n");
+ else
+ printf("%s\n",p);
+ }
+ exit(0);
+}
+#endif
+
+#ifdef KVTEST
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,ch;
+ FILE *fp;
+ char key[MAXKEY],valu[MAXVALUE];
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
+
+ switch (rc) {
+
+ case KV_EOL:
+ printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
+ break;
+
+ case KV_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case KV_OKAY:
+ printf("%s, line %d: okay, %s=\"%s\"\n",
+ filename,LineNbr,key,valu);
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
+ break;
+ }
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
+
+#ifdef PSTEST
+
+parmtable kparm[] = {
+ /* keyword, default, found value */
+ { "user", "", (char *)NULL },
+ { "realm", "Athena", (char *)NULL },
+ { "instance", "", (char *)NULL }
+};
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,i,ch;
+ FILE *fp;
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
+
+ switch (rc) {
+
+ case PS_BAD_KEYWORD:
+ printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_OKAY:
+ printf("%s, line %d: valid parameter set found:\n",
+ filename,LineNbr-1);
+ for (i=0; i<PARMCOUNT(kparm); i++) {
+ printf("\t%s = \"%s\"\n",kparm[i].keyword,
+ (kparm[i].value ? kparm[i].value
+ : kparm[i].defvalue));
+ }
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetParameterSet\n",rc);
+ break;
+ }
+ FreeParameterSet(kparm,PARMCOUNT(kparm));
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
diff --git a/eBones/krb/krb_err.et b/eBones/krb/krb_err.et
new file mode 100644
index 0000000..2c6830b
--- /dev/null
+++ b/eBones/krb/krb_err.et
@@ -0,0 +1,257 @@
+# Copyright 1987,1988 Massachusetts Institute of Technology
+# For copying and distribution information, see the file
+# "Copyright.MIT".
+#
+# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $
+# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $
+#
+ error_table krb
+
+ ec KRBET_KSUCCESS,
+ "Kerberos successful"
+
+ ec KRBET_KDC_NAME_EXP,
+ "Kerberos principal expired"
+
+ ec KRBET_KDC_SERVICE_EXP,
+ "Kerberos service expired"
+
+ ec KRBET_KDC_AUTH_EXP,
+ "Kerberos auth expired"
+
+ ec KRBET_KDC_PKT_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_P_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_S_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_BYTE_ORDER,
+ "Kerberos error: byte order unknown"
+
+ ec KRBET_KDC_PR_UNKNOWN,
+ "Kerberos principal unknown"
+
+ ec KRBET_KDC_PR_N_UNIQUE,
+ "Kerberos principal not unique"
+
+ ec KRBET_KDC_NULL_KEY,
+ "Kerberos principal has null key"
+
+ ec KRBET_KRB_RES11,
+ "Reserved 11"
+
+ ec KRBET_KRB_RES12,
+ "Reserved 12"
+
+ ec KRBET_KRB_RES13,
+ "Reserved 13"
+
+ ec KRBET_KRB_RES14,
+ "Reserved 14"
+
+ ec KRBET_KRB_RES15,
+ "Reserved 15"
+
+ ec KRBET_KRB_RES16,
+ "Reserved 16"
+
+ ec KRBET_KRB_RES17,
+ "Reserved 17"
+
+ ec KRBET_KRB_RES18,
+ "Reserved 18"
+
+ ec KRBET_KRB_RES19,
+ "Reserved 19"
+
+ ec KRBET_KDC_GEN_ERR,
+ "Generic error from Kerberos KDC"
+
+ ec KRBET_GC_TKFIL,
+ "Can't read Kerberos ticket file"
+
+ ec KRBET_GC_NOTKT,
+ "Can't find Kerberos ticket or TGT"
+
+ ec KRBET_KRB_RES23,
+ "Reserved 23"
+
+ ec KRBET_KRB_RES24,
+ "Reserved 24"
+
+ ec KRBET_KRB_RES25,
+ "Reserved 25"
+
+ ec KRBET_MK_AP_TGTEXP,
+ "Kerberos TGT Expired"
+
+ ec KRBET_KRB_RES27,
+ "Reserved 27"
+
+ ec KRBET_KRB_RES28,
+ "Reserved 28"
+
+ ec KRBET_KRB_RES29,
+ "Reserved 29"
+
+ ec KRBET_KRB_RES30,
+ "Reserved 30"
+
+ ec KRBET_RD_AP_UNDEC,
+ "Kerberos error: Can't decode authenticator"
+
+ ec KRBET_RD_AP_EXP,
+ "Kerberos ticket expired"
+
+ ec KRBET_RD_AP_NYV,
+ "Kerberos ticket not yet valid"
+
+ ec KRBET_RD_AP_REPEAT,
+ "Kerberos error: Repeated request"
+
+ ec KRBET_RD_AP_NOT_US,
+ "The kerberos ticket isn't for us"
+
+ ec KRBET_RD_AP_INCON,
+ "Kerberos request inconsistent"
+
+ ec KRBET_RD_AP_TIME,
+ "Kerberos error: delta_t too big"
+
+ ec KRBET_RD_AP_BADD,
+ "Kerberos error: incorrect net address"
+
+ ec KRBET_RD_AP_VERSION,
+ "Kerberos protocol version mismatch"
+
+ ec KRBET_RD_AP_MSG_TYPE,
+ "Kerberos error: invalid msg type"
+
+ ec KRBET_RD_AP_MODIFIED,
+ "Kerberos error: message stream modified"
+
+ ec KRBET_RD_AP_ORDER,
+ "Kerberos error: message out of order"
+
+ ec KRBET_RD_AP_UNAUTHOR,
+ "Kerberos error: unauthorized request"
+
+ ec KRBET_KRB_RES44,
+ "Reserved 44"
+
+ ec KRBET_KRB_RES45,
+ "Reserved 45"
+
+ ec KRBET_KRB_RES46,
+ "Reserved 46"
+
+ ec KRBET_KRB_RES47,
+ "Reserved 47"
+
+ ec KRBET_KRB_RES48,
+ "Reserved 48"
+
+ ec KRBET_KRB_RES49,
+ "Reserved 49"
+
+ ec KRBET_KRB_RES50,
+ "Reserved 50"
+
+ ec KRBET_GT_PW_NULL,
+ "Kerberos error: current PW is null"
+
+ ec KRBET_GT_PW_BADPW,
+ "Kerberos error: Incorrect current password"
+
+ ec KRBET_GT_PW_PROT,
+ "Kerberos protocol error"
+
+ ec KRBET_GT_PW_KDCERR,
+ "Error returned by Kerberos KDC"
+
+ ec KRBET_GT_PW_NULLTKT,
+ "Null Kerberos ticket returned by KDC"
+
+ ec KRBET_SKDC_RETRY,
+ "Kerberos error: Retry count exceeded"
+
+ ec KRBET_SKDC_CANT,
+ "Kerberos error: Can't send request"
+
+ ec KRBET_KRB_RES58,
+ "Reserved 58"
+
+ ec KRBET_KRB_RES59,
+ "Reserved 59"
+
+ ec KRBET_KRB_RES60,
+ "Reserved 60"
+
+ ec KRBET_INTK_W_NOTALL,
+ "Kerberos error: not all tickets returned"
+
+ ec KRBET_INTK_BADPW,
+ "Kerberos error: incorrect password"
+
+ ec KRBET_INTK_PROT,
+ "Kerberos error: Protocol Error"
+
+ ec KRBET_KRB_RES64,
+ "Reserved 64"
+
+ ec KRBET_KRB_RES65,
+ "Reserved 65"
+
+ ec KRBET_KRB_RES66,
+ "Reserved 66"
+
+ ec KRBET_KRB_RES67,
+ "Reserved 67"
+
+ ec KRBET_KRB_RES68,
+ "Reserved 68"
+
+ ec KRBET_KRB_RES69,
+ "Reserved 69"
+
+ ec KRBET_INTK_ERR,
+ "Other error"
+
+ ec KRBET_AD_NOTGT,
+ "Don't have Kerberos ticket-granting ticket"
+
+ ec KRBET_KRB_RES72,
+ "Reserved 72"
+
+ ec KRBET_KRB_RES73,
+ "Reserved 73"
+
+ ec KRBET_KRB_RES74,
+ "Reserved 74"
+
+ ec KRBET_KRB_RES75,
+ "Reserved 75"
+
+ ec KRBET_NO_TKT_FIL,
+ "No ticket file found"
+
+ ec KRBET_TKT_FIL_ACC,
+ "Couldn't access ticket file"
+
+ ec KRBET_TKT_FIL_LCK,
+ "Couldn't lock ticket file"
+
+ ec KRBET_TKT_FIL_FMT,
+ "Bad ticket file format"
+
+ ec KRBET_TKT_FIL_INI,
+ "tf_init not called first"
+
+ ec KRBET_KNAME_FMT,
+ "Bad Kerberos name format"
+
+ end
+
diff --git a/eBones/krb/krb_err_txt.c b/eBones/krb/krb_err_txt.c
new file mode 100644
index 0000000..785563f
--- /dev/null
+++ b/eBones/krb/krb_err_txt.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $
+ * $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $";
+#endif lint
+
+/*
+ * This file contains an array of error text strings.
+ * The associated error codes (which are defined in "krb.h")
+ * follow the string in the comments at the end of each line.
+ */
+
+char *krb_err_txt[256] = {
+ "OK", /* 000 */
+ "Principal expired (kerberos)", /* 001 */
+ "Service expired (kerberos)", /* 002 */
+ "Authentication expired (kerberos)", /* 003 */
+ "Unknown protocol version number (kerberos)", /* 004 */
+ "Principal: Incorrect master key version (kerberos)", /* 005 */
+ "Service: Incorrect master key version (kerberos)", /* 006 */
+ "Bad byte order (kerberos)", /* 007 */
+ "Principal unknown (kerberos)", /* 008 */
+ "Principal not unique (kerberos)", /* 009 */
+ "Principal has null key (kerberos)", /* 010 */
+ "Reserved error message 11 (kerberos)", /* 011 */
+ "Reserved error message 12 (kerberos)", /* 012 */
+ "Reserved error message 13 (kerberos)", /* 013 */
+ "Reserved error message 14 (kerberos)", /* 014 */
+ "Reserved error message 15 (kerberos)", /* 015 */
+ "Reserved error message 16 (kerberos)", /* 016 */
+ "Reserved error message 17 (kerberos)", /* 017 */
+ "Reserved error message 18 (kerberos)", /* 018 */
+ "Reserved error message 19 (kerberos)", /* 019 */
+ "Permission Denied (kerberos)", /* 020 */
+ "Can't read ticket file (krb_get_cred)", /* 021 */
+ "Can't find ticket (krb_get_cred)", /* 022 */
+ "Reserved error message 23 (krb_get_cred)", /* 023 */
+ "Reserved error message 24 (krb_get_cred)", /* 024 */
+ "Reserved error message 25 (krb_get_cred)", /* 025 */
+ "Ticket granting ticket expired (krb_mk_req)", /* 026 */
+ "Reserved error message 27 (krb_mk_req)", /* 027 */
+ "Reserved error message 28 (krb_mk_req)", /* 028 */
+ "Reserved error message 29 (krb_mk_req)", /* 029 */
+ "Reserved error message 30 (krb_mk_req)", /* 030 */
+ "Can't decode authenticator (krb_rd_req)", /* 031 */
+ "Ticket expired (krb_rd_req)", /* 032 */
+ "Ticket issue date too far in the future (krb_rd_req)",/* 033 */
+ "Repeat request (krb_rd_req)", /* 034 */
+ "Ticket for wrong server (krb_rd_req)", /* 035 */
+ "Request inconsistent (krb_rd_req)", /* 036 */
+ "Time is out of bounds (krb_rd_req)", /* 037 */
+ "Incorrect network address (krb_rd_req)", /* 038 */
+ "Protocol version mismatch (krb_rd_req)", /* 039 */
+ "Illegal message type (krb_rd_req)", /* 040 */
+ "Message integrity error (krb_rd_req)", /* 041 */
+ "Message duplicate or out of order (krb_rd_req)", /* 042 */
+ "Unauthorized request (krb_rd_req)", /* 043 */
+ "Reserved error message 44 (krb_rd_req)", /* 044 */
+ "Reserved error message 45 (krb_rd_req)", /* 045 */
+ "Reserved error message 46 (krb_rd_req)", /* 046 */
+ "Reserved error message 47 (krb_rd_req)", /* 047 */
+ "Reserved error message 48 (krb_rd_req)", /* 048 */
+ "Reserved error message 49 (krb_rd_req)", /* 049 */
+ "Reserved error message 50 (krb_rd_req)", /* 050 */
+ "Current password is NULL (get_pw_tkt)", /* 051 */
+ "Current password incorrect (get_pw_tkt)", /* 052 */
+ "Protocol error (gt_pw_tkt)", /* 053 */
+ "Error returned by KDC (gt_pw_tkt)", /* 054 */
+ "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */
+ "Retry count exceeded (send_to_kdc)", /* 056 */
+ "Can't send request (send_to_kdc)", /* 057 */
+ "Reserved error message 58 (send_to_kdc)", /* 058 */
+ "Reserved error message 59 (send_to_kdc)", /* 059 */
+ "Reserved error message 60 (send_to_kdc)", /* 060 */
+ "Warning: Not ALL tickets returned", /* 061 */
+ "Password incorrect", /* 062 */
+ "Protocol error (get_intkt)", /* 063 */
+ "Reserved error message 64 (get_in_tkt)", /* 064 */
+ "Reserved error message 65 (get_in_tkt)", /* 065 */
+ "Reserved error message 66 (get_in_tkt)", /* 066 */
+ "Reserved error message 67 (get_in_tkt)", /* 067 */
+ "Reserved error message 68 (get_in_tkt)", /* 068 */
+ "Reserved error message 69 (get_in_tkt)", /* 069 */
+ "Generic error (get_intkt)", /* 070 */
+ "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */
+ "Reserved error message 72 (get_ad_tkt)", /* 072 */
+ "Reserved error message 73 (get_ad_tkt)", /* 073 */
+ "Reserved error message 74 (get_ad_tkt)", /* 074 */
+ "Reserved error message 75 (get_ad_tkt)", /* 075 */
+ "No ticket file (tf_util)", /* 076 */
+ "Can't access ticket file (tf_util)", /* 077 */
+ "Can't lock ticket file; try later (tf_util)", /* 078 */
+ "Bad ticket file format (tf_util)", /* 079 */
+ "Read ticket file before tf_init (tf_util)", /* 080 */
+ "Bad Kerberos name format (kname_parse)", /* 081 */
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "Generic kerberos error (kfailure)", /* 255 */
+};
diff --git a/eBones/krb/krb_get_in_tkt.c b/eBones/krb/krb_get_in_tkt.c
new file mode 100644
index 0000000..a37bb60
--- /dev/null
+++ b/eBones/krb/krb_get_in_tkt.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $
+ * $Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+int swap_bytes;
+
+/*
+ * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
+ * and the cipher text sent from the KDC, decrypt the cipher text
+ * using the key returned by key_proc.
+ */
+
+static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+
+#ifndef NOENCRYPTION
+ /* Attempt to decrypt it */
+#endif
+
+ /* generate a key */
+
+ {
+ register int rc;
+ rc = (*key_proc)(user,instance,realm,arg,key);
+ if (rc)
+ return(rc);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length,key_s,key,DES_DECRYPT);
+#endif /* !NOENCRYPTION */
+ /* Get rid of all traces of key */
+ bzero((char *)key,sizeof(key));
+ bzero((char *)key_s,sizeof(key_s));
+
+ return(0);
+}
+
+/*
+ * krb_get_in_tkt() gets a ticket for a given principal to use a given
+ * service and stores the returned ticket and session key for future
+ * use.
+ *
+ * The "user", "instance", and "realm" arguments give the identity of
+ * the client who will use the ticket. The "service" and "sinstance"
+ * arguments give the identity of the server that the client wishes
+ * to use. (The realm of the server is the same as the Kerberos server
+ * to whom the request is sent.) The "life" argument indicates the
+ * desired lifetime of the ticket; the "key_proc" argument is a pointer
+ * to the routine used for getting the client's private key to decrypt
+ * the reply from Kerberos. The "decrypt_proc" argument is a pointer
+ * to the routine used to decrypt the reply from Kerberos; and "arg"
+ * is an argument to be passed on to the "key_proc" routine.
+ *
+ * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
+ * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned
+ * by Kerberos, then the error code it contains is returned. Other
+ * error codes returned by this routine include INTK_PROT to indicate
+ * wrong protocol version, INTK_BADPW to indicate bad password (if
+ * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
+ * the wrong server or the ticket store couldn't be initialized.
+ *
+ * The format of the message sent to Kerberos is as follows:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_KDC_REQUEST | message type
+ * HOST_BYTE_ORDER local byte order in lsb
+ * string user client's name
+ * string instance client's instance
+ * string realm client's realm
+ * 4 bytes tlocal.tv_sec timestamp in seconds
+ * 1 byte life desired lifetime
+ * string service service's name
+ * string sinstance service's instance
+ */
+
+krb_get_in_tkt(user, instance, realm, service, sinstance, life,
+ key_proc, decrypt_proc, arg)
+ char *user;
+ char *instance;
+ char *realm;
+ char *service;
+ char *sinstance;
+ int life;
+ int (*key_proc)();
+ int (*decrypt_proc)();
+ char *arg;
+{
+ KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st; /* Packet to KDC */
+ KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ int kvno; /* Kvno for session key */
+ unsigned char *v = pkt->dat; /* Prot vers no */
+ unsigned char *t = (pkt->dat+1); /* Prot msg type */
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ char rlm[REALM_SZ];
+ int lifetime;
+ int msg_byte_order;
+ int kerror;
+ unsigned long exp_date;
+ char *ptr;
+
+ struct timeval t_local;
+
+ unsigned long rep_err_code;
+
+ unsigned long kdc_time; /* KDC time */
+
+ /* BUILD REQUEST PACKET */
+
+ /* Set up the fixed part of the packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Now for the variable info */
+ (void) strcpy((char *)(pkt->dat+2),user); /* aname */
+ pkt->length = 3 + strlen(user);
+ (void) strcpy((char *)(pkt->dat+pkt->length),
+ instance); /* instance */
+ pkt->length += 1 + strlen(instance);
+ (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
+ pkt->length += 1 + strlen(realm);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ /* timestamp */
+ bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+
+ *(pkt->dat+(pkt->length)++) = (char) life;
+ (void) strcpy((char *)(pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION)
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
+ if (swap_bytes) swap_u_long(rep_err_code);
+ return((int)rep_err_code);
+ default:
+ return(INTK_PROT);
+ }
+
+ /* EXTRACT INFORMATION FROM RETURN PACKET */
+
+ /* get the principal's expiration date */
+ bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
+ if (swap_bytes) swap_u_long(exp_date);
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
+ return(INTK_ERR); /* no appropriate error code
+ currently defined for INTK_ */
+ /* copy information from return packet into "cip" */
+ bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
+
+ /* Attempt to decrypt the reply. */
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+ (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
+
+ ptr = (char *) cip->dat;
+
+ /* extract session key */
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's name */
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's instance */
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's realm */
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ /* extract ticket lifetime, server key version, ticket length */
+ /* be sure to avoid sign extension on lifetime! */
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
+ ptr += 3;
+
+ if ((tkt->length < 0) ||
+ ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
+ return(INTK_BADPW);
+
+ /* extract ticket itself */
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ /* initialize ticket cache */
+ if (in_tkt(user,instance) != KSUCCESS)
+ return(INTK_ERR);
+
+ /* stash ticket, session key, etc. for future use */
+ if (kerror = save_credentials(s_name, s_instance, rlm, ses,
+ lifetime, kvno, tkt, t_local.tv_sec))
+ return(kerror);
+
+ return(INTK_OK);
+}
diff --git a/eBones/krb/krb_realmofhost.3 b/eBones/krb/krb_realmofhost.3
new file mode 100644
index 0000000..f284069
--- /dev/null
+++ b/eBones/krb/krb_realmofhost.3
@@ -0,0 +1,161 @@
+.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
+.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question. In order to prevent certain security attacks, this routine
+must either have
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+The configuration file is described by
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned. If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports
+.I n
+= 1. It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/eBones/krb/krb_sendauth.3 b/eBones/krb/krb_sendauth.3
new file mode 100644
index 0000000..f5e95b7
--- /dev/null
+++ b/eBones/krb/krb_sendauth.3
@@ -0,0 +1,348 @@
+.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
+.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated. They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters. It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <mit-copyright.h>.
diff --git a/eBones/krb/krb_set_tkt_string.3 b/eBones/krb/krb_set_tkt_string.3
new file mode 100644
index 0000000..c9f3dcf
--- /dev/null
+++ b/eBones/krb/krb_set_tkt_string.3
@@ -0,0 +1,43 @@
+.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $
+.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_set_tkt_string \- set Kerberos ticket cache file name
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+void krb_set_tkt_string(filename)
+char *filename;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_set_tkt_string
+sets the name of the file that holds the user's
+cache of Kerberos server tickets and associated session keys.
+.PP
+The string
+.I filename
+passed in is copied into local storage.
+Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
+copied in for use as the cache file name.
+.PP
+This routine should be called during initialization, before other
+Kerberos routines are called; otherwise the routines which fetch the
+ticket cache file name may be called and return an undesired ticket file
+name until this routine is called.
+.SH FILES
+.TP 20n
+/tmp/tkt[uid]
+default ticket file name, unless the environment variable KRBTKFILE is set.
+[uid] denotes the user's uid, in decimal.
+.SH SEE ALSO
+kerberos(3), setenv(3)
diff --git a/eBones/krb/krbglue.c b/eBones/krb/krbglue.c
new file mode 100644
index 0000000..8e864c1
--- /dev/null
+++ b/eBones/krb/krbglue.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $
+ * $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $";
+#endif lint
+
+#ifndef NCOMPAT
+/*
+ * glue together new libraries and old clients
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "des.h"
+#include "krb.h"
+
+/* These definitions should be in krb.h, no? */
+#if defined(__HIGHC__)
+#undef __STDC__
+#endif
+#ifdef __STDC__
+extern int krb_mk_req (KTEXT, char *, char *, char *, long);
+extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *);
+extern int krb_kntoln (AUTH_DAT *, char *);
+extern int krb_set_key (char *, int);
+extern int krb_get_cred (char *, char *, char *, CREDENTIALS *);
+extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *);
+extern long krb_rd_priv (u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *, MSG_DAT *);
+extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *);
+extern long krb_rd_safe (u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *,
+ MSG_DAT *);
+extern long krb_mk_err (u_char *, long, char *);
+extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *);
+extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_pw_tkt (char *, char *, char *, char *);
+extern int krb_get_lrealm (char *, char *);
+extern int krb_realmofhost (char *);
+extern char *krb_get_phost (char *);
+extern int krb_get_krbhst (char *, char *, int);
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet (char *);
+#endif /* DEBUG */
+#else
+extern int krb_mk_req ();
+extern int krb_rd_req ();
+extern int krb_kntoln ();
+extern int krb_set_key ();
+extern int krb_get_cred ();
+extern long krb_mk_priv ();
+extern long krb_rd_priv ();
+extern long krb_mk_safe ();
+extern long krb_rd_safe ();
+extern long krb_mk_err ();
+extern int krb_rd_err ();
+extern int krb_get_pw_in_tkt ();
+extern int krb_get_svc_in_tkt ();
+extern int krb_get_pw_tkt ();
+extern int krb_get_lrealm ();
+extern int krb_realmofhost ();
+extern char *krb_get_phost ();
+extern int krb_get_krbhst ();
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet ();
+#endif /* DEBUG */
+#endif /* STDC */
+int mk_ap_req(authent, service, instance, realm, checksum)
+ KTEXT authent;
+ char *service, *instance, *realm;
+ u_long checksum;
+{
+ return krb_mk_req(authent,service,instance,realm,checksum);
+}
+
+int rd_ap_req(authent, service, instance, from_addr, ad, fn)
+ KTEXT authent;
+ char *service, *instance;
+ u_long from_addr;
+ AUTH_DAT *ad;
+ char *fn;
+{
+ return krb_rd_req(authent,service,instance,from_addr,ad,fn);
+}
+
+int an_to_ln(ad, lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ return krb_kntoln (ad,lname);
+}
+
+int set_serv_key (key, cvt)
+ char *key;
+ int cvt;
+{
+ return krb_set_key(key,cvt);
+}
+
+int get_credentials (svc,inst,rlm,cred)
+ char *svc, *inst, *rlm;
+ CREDENTIALS *cred;
+{
+ return krb_get_cred (svc, inst, rlm, cred);
+}
+
+long mk_private_msg (in,out,in_length,schedule,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver);
+}
+
+long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data);
+}
+
+long mk_safe_msg (in,out,in_length,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_safe (in,out,in_length,key,sender,receiver);
+}
+
+long rd_safe_msg (in,length,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_safe (in,length,key,sender,receiver,msg_data);
+}
+
+long mk_appl_err_msg (out,code,string)
+ u_char *out;
+ long code;
+ char *string;
+{
+ return krb_mk_err (out,code,string);
+}
+
+long rd_appl_err_msg (in,length,code,msg_data)
+ u_char *in;
+ u_long length;
+ long *code;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_err (in,length,code,msg_data);
+}
+
+int get_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return krb_get_pw_in_tkt(user,instance,realm,service,sinstance,
+ life,password);
+}
+
+int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return krb_get_svc_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab);
+}
+
+int get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ return krb_get_pw_tkt(user,instance,realm,cpw);
+}
+
+int
+get_krbrlm (r, n)
+char *r;
+int n;
+{
+ return krb_get_lream(r,n);
+}
+
+int
+krb_getrealm (host)
+{
+ return krb_realmofhost(host);
+}
+
+char *
+get_phost (host)
+char *host
+{
+ return krb_get_phost(host);
+}
+
+int
+get_krbhst (h, r, n)
+char *h;
+char *r;
+int n;
+{
+ return krb_get_krbhst(h,r,n);
+}
+#ifdef DEBUG
+struct ktext *create_death_packet(a_name)
+ char *a_name;
+{
+ return krb_create_death_packet(a_name);
+}
+#endif /* DEBUG */
+
+#if 0
+extern int krb_ck_repl ();
+
+int check_replay ()
+{
+ return krb_ck_repl ();
+}
+#endif
+#endif /* NCOMPAT */
diff --git a/eBones/krb/kuserok.3 b/eBones/krb/kuserok.3
new file mode 100644
index 0000000..36968ba
--- /dev/null
+++ b/eBones/krb/kuserok.3
@@ -0,0 +1,63 @@
+.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $
+.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kuserok \- Kerberos version of ruserok
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+kuserok(kdata, localuser)
+AUTH_DAT *auth_data;
+char *localuser;
+.fi
+.ft R
+.SH DESCRIPTION
+.I kuserok
+determines whether a Kerberos principal described by the structure
+.I auth_data
+is authorized to login as user
+.I localuser
+according to the authorization file
+("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized,
+1 (one) if not authorized.
+.PP
+If there is no account for
+.I localuser
+on the local machine, authorization is not granted.
+If there is no authorization file, and the Kerberos principal described
+by
+.I auth_data
+translates to
+.I localuser
+(using
+.IR krb_kntoln (3)),
+authorization is granted.
+If the authorization file
+can't be accessed, or the file is not owned by
+.IR localuser,
+authorization is denied. Otherwise, the file is searched for
+a matching principal name, instance, and realm. If a match is found,
+authorization is granted, else authorization is denied.
+.PP
+The file entries are in the format:
+.nf
+.in +5n
+ name.instance@realm
+.in -5n
+.fi
+with one entry per line.
+.SH SEE ALSO
+kerberos(3), ruserok(3), krb_kntoln(3)
+.SH FILES
+.TP 20n
+~\fIlocaluser\fR/.klogin
+authorization list
diff --git a/eBones/krb/kuserok.c b/eBones/krb/kuserok.c
new file mode 100644
index 0000000..cb1f708
--- /dev/null
+++ b/eBones/krb/kuserok.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * kuserok: check if a kerberos principal has
+ * access to a local account
+ *
+ * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $
+ * $Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <strings.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "kdata", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default). Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK. If there is no authorization file, and the given Kerberos
+ * name "kdata" translates to the same name as "luser" (using
+ * krb_kntoln()), returns OK. Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK. Otherwise, the file is read for
+ * a matching principal name, instance, and realm. If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format:
+ *
+ * name.instance@realm
+ *
+ * one entry per line.
+ *
+ * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
+ * file entries. See the file "kparse.c".
+ */
+
+#ifdef ATHENA_COMPAT
+
+#include <kparse.h>
+
+/*
+ * The parmtable defines the keywords we will recognize with their
+ * default values, and keeps a pointer to the found value. The found
+ * value should be filled in with strsave(), since FreeParameterSet()
+ * will release memory for all non-NULL found strings.
+ *
+*** NOTE WELL! ***
+ *
+ * The table below is very nice, but we cannot hard-code a default for the
+ * realm: we have to get the realm via krb_get_lrealm(). Even though the
+ * default shows as "from krb_get_lrealm, below", it gets changed in
+ * kuserok to whatever krb_get_lrealm() tells us. That code assumes that
+ * the realm will be the entry number in the table below, so if you
+ * change the order of the entries below, you have to change the
+ * #definition of REALM_SCRIPT to reflect it.
+ */
+#define REALM_SUBSCRIPT 1
+parmtable kparm[] = {
+
+/* keyword default found value */
+{"user", "", (char *) NULL},
+{"realm", "see krb_get_lrealm, below", (char *) NULL},
+{"instance", "", (char *) NULL},
+};
+#define KPARMS kparm,PARMCOUNT(kparm)
+#endif ATHENA_COMPAT
+
+kuserok(kdata, luser)
+ AUTH_DAT *kdata;
+ char *luser;
+{
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+ int isok = NOTOK, rc;
+ FILE *fp;
+ char kuser[MAX_USERNAME];
+ char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char *newline;
+ int gobble;
+#ifdef ATHENA_COMPAT
+ char local_realm[REALM_SZ];
+#endif ATHENA_COMPAT
+
+ /* no account => no access */
+ if ((pwd = getpwnam(luser)) == NULL) {
+ return(NOTOK);
+ }
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, "/.klogin");
+
+ if (access(pbuf, F_OK)) { /* not accessible */
+ /*
+ * if he's trying to log in as himself, and there is no .klogin file,
+ * let him. To find out, call
+ * krb_kntoln to convert the triple in kdata to a name which we can
+ * string compare.
+ */
+ if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
+ return(OK);
+ }
+ }
+ /* open ~/.klogin */
+ if ((fp = fopen(pbuf, "r")) == NULL) {
+ return(NOTOK);
+ }
+ /*
+ * security: if the user does not own his own .klogin file,
+ * do not grant access
+ */
+ if (fstat(fileno(fp), &sbuf)) {
+ fclose(fp);
+ return(NOTOK);
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ fclose(fp);
+ return(NOTOK);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* Accept old-style .klogin files */
+
+ /*
+ * change the default realm from the hard-coded value to the
+ * accepted realm that Kerberos specifies.
+ */
+ rc = krb_get_lrealm(local_realm, 1);
+ if (rc == KSUCCESS)
+ kparm[REALM_SUBSCRIPT].defvalue = local_realm;
+ else
+ return (rc);
+
+ /* check each line */
+ while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
+ switch (rc) {
+ case PS_BAD_KEYWORD:
+ case PS_SYNTAX:
+ while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
+ break;
+
+ case PS_OKAY:
+ isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
+ ParmCompare(KPARMS, "instance", kdata->pinst) ||
+ ParmCompare(KPARMS, "realm", kdata->prealm));
+ break;
+
+ default:
+ break;
+ }
+ FreeParameterSet(kparm, PARMCOUNT(kparm));
+ }
+ /* reset the stream for parsing new-style names, if necessary */
+ rewind(fp);
+#endif ATHENA_COMPAT
+
+ /* check each line */
+ while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+ /* null-terminate the input string */
+ linebuf[BUFSIZ-1] = '\0';
+ newline = NULL;
+ /* nuke the newline if it exists */
+ if (newline = index(linebuf, '\n'))
+ *newline = '\0';
+ rc = kname_parse(principal, inst, realm, linebuf);
+ if (rc == KSUCCESS) {
+ isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
+ strncmp(kdata->pinst, inst, INST_SZ) ||
+ strncmp(kdata->prealm, realm, REALM_SZ));
+ }
+ /* clean up the rest of the line if necessary */
+ if (!newline)
+ while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+ }
+ fclose(fp);
+ return(isok);
+}
diff --git a/eBones/krb/log.c b/eBones/krb/log.c
new file mode 100644
index 0000000..42fccfb
--- /dev/null
+++ b/eBones/krb/log.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $
+ * $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static is_open;
+
+/*
+ * This file contains three logging routines: set_logfile()
+ * to determine the file that log entries should be written to;
+ * and log() and new_log() to write log entries to the file.
+ */
+
+/*
+ * log() is used to add entries to the logfile (see set_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format".
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * The return value is undefined.
+ */
+
+__BEGIN_DECLS
+char *month_sname __P((int));
+__END_DECLS
+
+
+/*VARARGS1 */
+void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ struct tm *tm;
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return;
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+ fprintf(logfile,"\n");
+ (void) fclose(logfile);
+ return;
+}
+
+/*
+ * set_logfile() changes the name of the file to which
+ * messages are logged. If set_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+set_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
+
+/*
+ * new_log() appends a log entry containing the give time "t" and the
+ * string "string" to the logfile (see set_logfile() above). The file
+ * is opened once and left open. The routine returns 1 on failure, 0
+ * on success.
+ */
+
+new_log(t,string)
+ long t;
+ char *string;
+{
+ static FILE *logfile;
+
+ long time();
+ struct tm *tm;
+
+ if (!is_open) {
+ if ((logfile = fopen(log_name,"a")) == NULL) return(1);
+ is_open = 1;
+ }
+
+ if (t) {
+ tm = localtime(&t);
+
+ fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, string);
+ }
+ else {
+ fprintf(logfile,"\n%20s%s","",string);
+ }
+
+ (void) fflush(logfile);
+ return(0);
+}
diff --git a/eBones/krb/mk_err.c b/eBones/krb/mk_err.c
new file mode 100644
index 0000000..331cba9
--- /dev/null
+++ b/eBones/krb/mk_err.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $
+ * $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a general purpose error reply message. It
+ * doesn't use KTEXT because application protocol may have long
+ * messages, and may want this part of buffer contiguous to other
+ * stuff.
+ *
+ * The error reply is built in "p", using the error code "e" and
+ * error text "e_string" given. The length of the error reply is
+ * returned.
+ *
+ * The error reply is in the following format:
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_ERR message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte order
+ * 4 bytes e given error code
+ * string e_string given error text
+ */
+
+long krb_mk_err(p,e,e_string)
+ u_char *p; /* Where to build error packet */
+ long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *start;
+
+ start = p;
+
+ /* Create fixed part of packet */
+ *p++ = (unsigned char) KRB_PROT_VERSION;
+ *p = (unsigned char) AUTH_MSG_APPL_ERR;
+ *p++ |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ bcopy((char *)&e,(char *)p,4); /* err code */
+ p += sizeof(e);
+ (void) strcpy((char *)p,e_string); /* err text */
+ p += strlen(e_string);
+
+ /* And return the length */
+ return p-start;
+}
diff --git a/eBones/krb/mk_priv.c b/eBones/krb/mk_priv.c
new file mode 100644
index 0000000..3bae4ed
--- /dev/null
+++ b/eBones/krb/mk_priv.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'private msg', i.e.
+ * cryptographically sealed with a private session key.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT.
+ *
+ * Note-- It's too bad that it did a long int compare on the RT before.
+ *
+ * Returns either < 0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $
+ * $Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+
+static u_long c_length;
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+#ifndef NOENCRYTION
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+#endif
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum. Also, the protocol version
+ * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte private_msg_ver protocol version number
+ * 1 byte AUTH_MSG_PRIVATE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * 4 bytes c_length length of data
+#ifndef NOENCRYPT
+ * we encrypt from here with pcbc_encrypt
+#endif
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * 0<=n<=7 bytes pad to 8 byte multiple zeroes
+ */
+
+long krb_mk_priv(in,out,length,schedule,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /* put msg here, leave room for
+ * header! breaks if in and out
+ * (header stuff) overlap */
+ u_long length; /* of in data */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+ static u_char *c_length_ptr;
+ extern int private_msg_ver; /* in krb_rd_priv.c */
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = private_msg_ver;
+ *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+
+ /* calculate cipher length */
+ c_length_ptr = p;
+ p += sizeof(c_length);
+
+ q = p;
+
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+#ifdef NOENCRYPTION
+ /* make all the stuff contiguous for checksum */
+#else
+ /* make all the stuff contiguous for checksum and encryption */
+#endif
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok
+ * until 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+#ifdef notdef
+ /*
+ * calculate the checksum of the length, address, sequence, and
+ * inp data
+ */
+ cksum = quad_cksum(q,NULL,p-q,0,key);
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+ /* stuff checksum */
+ bcopy((char *) &cksum,(char *) p,sizeof(cksum));
+ p += sizeof(cksum);
+#endif
+
+ /*
+ * All the data have been assembled, compute length
+ */
+
+ c_length = p - q;
+ c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
+ sizeof(C_Block);
+ /* stuff the length */
+ bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return (q - out + c_length); /* resulting size */
+}
diff --git a/eBones/krb/mk_req.c b/eBones/krb/mk_req.c
new file mode 100644
index 0000000..bb0f097
--- /dev/null
+++ b/eBones/krb/mk_req.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $
+ * $Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <des.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+static struct timeval tv_local = { 0, 0 };
+static int lifetime = DEFAULT_TKT_LIFE;
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum. It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument. krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req. When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_REQUEST message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte ordering
+ * unsigned char kvno from ticket server's key version
+ * string realm server's realm
+ * unsigned char tl ticket length
+ * unsigned char idl request id length
+ * text ticket->dat ticket for server
+ * text req_id->dat request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos. The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string cr.pname {name, instance, and
+ * string cr.pinst realm of principal
+ * string myrealm making this request}
+ * 4 bytes checksum checksum argument given
+ * unsigned char tv_local.tf_usec time (milliseconds)
+ * 4 bytes tv_local.tv_sec time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ * all rounded up to multiple of 8.
+ */
+
+krb_mk_req(authent,service,instance,realm,checksum)
+ register KTEXT authent; /* Place to build the authenticator */
+ char *service; /* Name of the service */
+ char *instance; /* Service instance */
+ char *realm; /* Authentication domain of service */
+ long checksum; /* Checksum of data (optional) */
+{
+ static KTEXT_ST req_st; /* Temp storage for req id */
+ register KTEXT req_id = &req_st;
+ unsigned char *v = authent->dat; /* Prot version number */
+ unsigned char *t = (authent->dat+1); /* Message type */
+ unsigned char *kv = (authent->dat+2); /* Key version no */
+ unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
+ unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
+ CREDENTIALS cr; /* Credentials used by retr */
+ register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+ int retval; /* Returned by krb_get_cred */
+ static Key_schedule key_s;
+ char myrealm[REALM_SZ];
+
+ /* The fixed parts of the authenticator */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Get the ticket and move it into the authenticator */
+ if (krb_ap_req_debug)
+ printf("Realm: %s\n",realm);
+ /*
+ * Determine realm of these tickets. We will send this to the
+ * KDC from which we are requesting tickets so it knows what to
+ * with our session key.
+ */
+ if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
+ return(retval);
+
+ retval = krb_get_cred(service,instance,realm,&cr);
+
+ if (retval == RET_NOTKT) {
+ if (retval = get_ad_tkt(service,instance,realm,lifetime))
+ return(retval);
+ if (retval = krb_get_cred(service,instance,realm,&cr))
+ return(retval);
+ }
+
+ if (retval != KSUCCESS) return (retval);
+
+ if (krb_ap_req_debug)
+ printf("%s %s %s %s %s\n", service, instance, realm,
+ cr.pname, cr.pinst);
+ *kv = (unsigned char) cr.kvno;
+ (void) strcpy((char *)(authent->dat+3),realm);
+ *tl = (unsigned char) ticket->length;
+ bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
+ ticket->length);
+ authent->length = 6 + strlen(realm) + ticket->length;
+ if (krb_ap_req_debug)
+ printf("Ticket->length = %d\n",ticket->length);
+ if (krb_ap_req_debug)
+ printf("Issue date: %d\n",cr.issue_date);
+
+ /* Build request id */
+ (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
+ req_id->length = strlen(cr.pname)+1;
+ /* Principal's instance */
+ (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
+ req_id->length += strlen(cr.pinst)+1;
+ /* Authentication domain */
+ (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
+ req_id->length += strlen(myrealm)+1;
+ /* Checksum */
+ bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
+ req_id->length += 4;
+
+ /* Fill in the times on the request id */
+ (void) gettimeofday(&tv_local,(struct timezone *) 0);
+ *(req_id->dat+(req_id->length)++) =
+ (unsigned char) tv_local.tv_usec;
+ /* Time (coarse) */
+ bcopy((char *)&(tv_local.tv_sec),
+ (char *)(req_id->dat+req_id->length), 4);
+ req_id->length += 4;
+
+ /* Fill to a multiple of 8 bytes for DES */
+ req_id->length = ((req_id->length+7)/8)*8;
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,key_s,cr.session,ENCRYPT);
+ bzero((char *) key_s, sizeof(key_s));
+#endif /* NOENCRYPTION */
+
+ /* Copy it into the authenticator */
+ bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
+ req_id->length);
+ authent->length += req_id->length;
+ /* And set the id length */
+ *idl = (unsigned char) req_id->length;
+ /* clean up */
+ bzero((char *)req_id, sizeof(*req_id));
+
+ if (krb_ap_req_debug)
+ printf("Authent->length = %d\n",authent->length);
+ if (krb_ap_req_debug)
+ printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
+
+ return(KSUCCESS);
+}
+
+/*
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ *
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(newval)
+int newval;
+{
+ int olife = lifetime;
+
+ lifetime = newval;
+ return(olife);
+}
diff --git a/eBones/krb/mk_safe.c b/eBones/krb/mk_safe.c
new file mode 100644
index 0000000..567004b
--- /dev/null
+++ b/eBones/krb/mk_safe.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'safe msg', i.e. authenticated
+ * using a private session key to seed a checksum. Msg is NOT
+ * encrypted.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT
+ *
+ * Returns either <0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $
+ * $Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long cksum;
+static C_Block big_cksum[2];
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key". The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_SAFE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes big_cksum quadratic checksum of
+ * above using "key"
+ */
+
+long krb_mk_safe(in,out,length,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /*
+ * put msg here, leave room for header!
+ * breaks if in and out (header stuff)
+ * overlap
+ */
+ u_long length; /* of in data */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = KRB_PROT_VERSION;
+ *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+
+ q = p; /* start for checksum stuff */
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+ /* make all the stuff contiguous for checksum */
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok until
+ * 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /*
+ * all that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+#ifdef NOENCRYPTION
+ cksum = 0;
+ bzero(big_cksum, sizeof(big_cksum));
+#else
+ cksum=quad_cksum(q,big_cksum,p-q,2,key);
+#endif
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+
+ /* stuff checksum */
+ bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
+ p += sizeof(big_cksum);
+
+ return ((long)(p - out)); /* resulting size */
+
+}
diff --git a/eBones/krb/month_sname.c b/eBones/krb/month_sname.c
new file mode 100644
index 0000000..e7a63ec
--- /dev/null
+++ b/eBones/krb/month_sname.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $
+ * $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $";
+#endif /* lint */
+
+
+/*
+ * Given an integer 1-12, month_sname() returns a string
+ * containing the first three letters of the corresponding
+ * month. Returns 0 if the argument is out of range.
+ */
+
+char *month_sname(n)
+ int n;
+{
+ static char *name[] = {
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+ };
+ return((n < 1 || n > 12) ? 0 : name [n-1]);
+}
diff --git a/eBones/krb/netread.c b/eBones/krb/netread.c
new file mode 100644
index 0000000..eb86327
--- /dev/null
+++ b/eBones/krb/netread.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $
+ * $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_read() reads from the file descriptor "fd" to the buffer
+ * "buf", until either 1) "len" bytes have been read or 2) cannot
+ * read anymore from "fd". It returns the number of bytes read
+ * or a read() error. (The calling interface is identical to
+ * read(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_read(fd, buf, len)
+int fd;
+register char *buf;
+register int len;
+{
+ int cc, len2 = 0;
+
+ do {
+ cc = read(fd, buf, len);
+ if (cc < 0)
+ return(cc); /* errno is already set */
+ else if (cc == 0) {
+ return(len2);
+ } else {
+ buf += cc;
+ len2 += cc;
+ len -= cc;
+ }
+ } while (len > 0);
+ return(len2);
+}
diff --git a/eBones/krb/netwrite.c b/eBones/krb/netwrite.c
new file mode 100644
index 0000000..5945ce0
--- /dev/null
+++ b/eBones/krb/netwrite.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $";
+ * $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_write() writes "len" bytes from "buf" to the file
+ * descriptor "fd". It returns the number of bytes written or
+ * a write() error. (The calling interface is identical to
+ * write(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_write(fd, buf, len)
+int fd;
+register char *buf;
+int len;
+{
+ int cc;
+ register int wrlen = len;
+ do {
+ cc = write(fd, buf, wrlen);
+ if (cc < 0)
+ return(cc);
+ else {
+ buf += cc;
+ wrlen -= cc;
+ }
+ } while (wrlen > 0);
+ return(len);
+}
diff --git a/eBones/krb/one.c b/eBones/krb/one.c
new file mode 100644
index 0000000..c0e8bc6
--- /dev/null
+++ b/eBones/krb/one.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $
+ * $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $";
+#endif lint
+
+/*
+ * definition of variable set to 1.
+ * used in krb_conf.h to determine host byte order.
+ */
+
+int krbONE = 1;
diff --git a/eBones/krb/pkt_cipher.c b/eBones/krb/pkt_cipher.c
new file mode 100644
index 0000000..6ef870c
--- /dev/null
+++ b/eBones/krb/pkt_cipher.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $
+ * $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+
+/*
+ * This routine takes a reply packet from the Kerberos ticket-granting
+ * service and returns a pointer to the beginning of the ciphertext in it.
+ *
+ * See "prot.h" for packet format.
+ */
+
+KTEXT
+pkt_cipher(packet)
+ KTEXT packet;
+{
+ unsigned char *ptr = pkt_a_realm(packet) + 6
+ + strlen((char *)pkt_a_realm(packet));
+ /* Skip a few more fields */
+ ptr += 3 + 4; /* add 4 for exp_date */
+
+ /* And return the pointer */
+ return((KTEXT) ptr);
+}
diff --git a/eBones/krb/pkt_clen.c b/eBones/krb/pkt_clen.c
new file mode 100644
index 0000000..23ad4c3
--- /dev/null
+++ b/eBones/krb/pkt_clen.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $
+ * $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+extern int krb_debug;
+extern int swap_bytes;
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion. The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order. pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+pkt_clen(pkt)
+ KTEXT pkt;
+{
+ static unsigned short temp,temp2;
+ int clen = 0;
+
+ /* Start of ticket list */
+ unsigned char *ptr = pkt_a_realm(pkt) + 10
+ + strlen((char *)pkt_a_realm(pkt));
+
+ /* Finally the length */
+ bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+ if (swap_bytes) {
+ /* assume a short is 2 bytes?? */
+ swab((char *)&temp,(char *)&temp2,2);
+ temp = temp2;
+ }
+
+ clen = (int) temp;
+
+ if (krb_debug)
+ printf("Clen is %d\n",clen);
+ return(clen);
+}
diff --git a/eBones/krb/rd_err.c b/eBones/krb/rd_err.c
new file mode 100644
index 0000000..e73c47b
--- /dev/null
+++ b/eBones/krb/rd_err.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg',
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $
+ * $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
+ * return the error code from the message in "code" and the text in
+ * "m_data" as follows:
+ *
+ * m_data->app_data points to the error text
+ * m_data->app_length points to the length of the error text
+ *
+ * If all goes well, return RD_AP_OK. If the version number
+ * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
+ * type message, return RD_AP_MSG_TYPE.
+ *
+ * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
+ */
+
+int
+krb_rd_err(in,in_length,code,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* of in msg */
+ long *code; /* received error code */
+ MSG_DAT *m_data;
+{
+ register u_char *p;
+ int swap_bytes = 0;
+ p = in; /* beginning of message */
+
+ if (*p++ != KRB_PROT_VERSION)
+ return(RD_AP_VERSION);
+ if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
+ return(RD_AP_MSG_TYPE);
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* safely get code */
+ bcopy((char *)p,(char *)code,sizeof(*code));
+ if (swap_bytes)
+ swap_u_long(*code);
+ p += sizeof(*code); /* skip over */
+
+ m_data->app_data = p; /* we're now at the error text
+ * message */
+ m_data->app_length = in_length;
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/krb/rd_priv.c b/eBones/krb/rd_priv.c
new file mode 100644
index 0000000..9adefec
--- /dev/null
+++ b/eBones/krb/rd_priv.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'private msg', decrypting it,
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
+ * the return value is RD_AP_TIME, then either the times are too far
+ * out of synch, OR the packet was modified.
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $
+ * $Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[]=
+"$Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long c_length;
+static int swap_bytes;
+static struct timeval local_time;
+static long delta_t;
+int private_msg_ver = KRB_PROT_VERSION;
+
+/*
+#ifdef NOENCRPYTION
+ * krb_rd_priv() checks the integrity of an
+#else
+ * krb_rd_priv() decrypts and checks the integrity of an
+#endif
+ * AUTH_MSG_PRIVATE message. Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data". The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender;
+ struct sockaddr_in *receiver;
+ MSG_DAT *m_data; /*various input/output data from msg */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+ return RD_AP_VERSION;
+ private_msg_ver = *(p-1);
+ if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+ return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* get cipher length */
+ bcopy((char *)p,(char *)&c_length,sizeof(c_length));
+ if (swap_bytes)
+ swap_u_long(c_length);
+ p += sizeof(c_length);
+ /* check for rational length so we don't go comatose */
+ if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+ return RD_AP_MODIFIED;
+
+
+ q = p; /* mark start of encrypted stuff */
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT);
+#endif
+
+ /* safely get application data length */
+ bcopy((char *) p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes)
+ swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
+ sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
+ sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
+ > in_length)
+ return RD_AP_MODIFIED;
+
+#ifndef NOENCRYPTION
+ /* we're now at the decrypted application data */
+#endif
+ m_data->app_data = p;
+
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *) p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *) p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes) swap_u_long(m_data->time_sec);
+
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ /*
+ * all that for one tiny bit!
+ * Heaven help those that talk to themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec
+ - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW)
+ return RD_AP_TIME;
+ if (krb_debug)
+ printf("\ndelta_t = %d",delta_t);
+
+ /*
+ * caller must check timestamps for proper order and
+ * replays, since server might have multiple clients
+ * each with its own timestamps and we don't assume
+ * tightly synchronized clocks.
+ */
+
+#ifdef notdef
+ bcopy((char *) p,(char *)&cksum,sizeof(cksum));
+ if (swap_bytes) swap_u_long(cksum)
+ /*
+ * calculate the checksum of the length, sequence,
+ * and input data, on the sending byte order!!
+ */
+ calc_cksum = quad_cksum(q,NULL,p-q,0,key);
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ calc_cksum, cksum);
+ if (cksum != calc_cksum)
+ return RD_AP_MODIFIED;
+#endif
+ return RD_AP_OK; /* OK == 0 */
+}
diff --git a/eBones/krb/rd_req.c b/eBones/krb/rd_req.c
new file mode 100644
index 0000000..22b6540
--- /dev/null
+++ b/eBones/krb/rd_req.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $
+ * $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+
+static struct timeval t_local = { 0, 0 };
+
+/*
+ * Keep the following information around for subsequent calls
+ * to this routine by the same server using the same key.
+ */
+
+static Key_schedule serv_key; /* Key sched to decrypt ticket */
+static C_Block ky; /* Initialization vector */
+static int st_kvno; /* version number for this key */
+static char st_rlm[REALM_SZ]; /* server's realm */
+static char st_nam[ANAME_SZ]; /* service name */
+static char st_inst[INST_SZ]; /* server's instance */
+
+/*
+ * This file contains two functions. krb_set_key() takes a DES
+ * key or password string and returns a DES key (either the original
+ * key, or the password converted into a DES key) and a key schedule
+ * for it.
+ *
+ * krb_rd_req() reads an authentication request and returns information
+ * about the identity of the requestor, or an indication that the
+ * identity information was not authentic.
+ */
+
+/*
+ * krb_set_key() takes as its first argument either a DES key or a
+ * password string. The "cvt" argument indicates how the first
+ * argument "key" is to be interpreted: if "cvt" is null, "key" is
+ * taken to be a DES key; if "cvt" is non-null, "key" is taken to
+ * be a password string, and is converted into a DES key using
+ * string_to_key(). In either case, the resulting key is returned
+ * in the external static variable "ky". A key schedule is
+ * generated for "ky" and returned in the external static variable
+ * "serv_key".
+ *
+ * This routine returns the return value of des_key_sched.
+ *
+ * krb_set_key() needs to be in the same .o file as krb_rd_req() so that
+ * the key set by krb_set_key() is available in private storage for
+ * krb_rd_req().
+ */
+
+int
+krb_set_key(key,cvt)
+ char *key;
+ int cvt;
+{
+#ifdef NOENCRYPTION
+ bzero(ky, sizeof(ky));
+ return KSUCCESS;
+#else
+ if (cvt)
+ string_to_key(key,ky);
+ else
+ bcopy(key,(char *)ky,8);
+ return(des_key_sched(ky,serv_key));
+#endif
+}
+
+
+/*
+ * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
+ * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
+ * checks its integrity and returns a judgement as to the requestor's
+ * identity.
+ *
+ * The "authent" argument is a pointer to the received message.
+ * The "service" and "instance" arguments name the receiving server,
+ * and are used to get the service's ticket to decrypt the ticket
+ * in the message, and to compare against the server name inside the
+ * ticket. "from_addr" is the network address of the host from which
+ * the message was received; this is checked against the network
+ * address in the ticket. If "from_addr" is zero, the check is not
+ * performed. "ad" is an AUTH_DAT structure which is
+ * filled in with information about the sender's identity according
+ * to the authenticator and ticket sent in the message. Finally,
+ * "fn" contains the name of the file containing the server's key.
+ * (If "fn" is NULL, the server's key is assumed to have been set
+ * by krb_set_key(). If "fn" is the null string ("") the default
+ * file KEYFILE, defined in "krb.h", is used.)
+ *
+ * krb_rd_req() returns RD_AP_OK if the authentication information
+ * was genuine, or one of the following error codes (defined in
+ * "krb.h"):
+ *
+ * RD_AP_VERSION - wrong protocol version number
+ * RD_AP_MSG_TYPE - wrong message type
+ * RD_AP_UNDEC - couldn't decipher the message
+ * RD_AP_INCON - inconsistencies found
+ * RD_AP_BADD - wrong network address
+ * RD_AP_TIME - client time (in authenticator)
+ * too far off server time
+ * RD_AP_NYV - Kerberos time (in ticket) too
+ * far off server time
+ * RD_AP_EXP - ticket expired
+ *
+ * For the message format, see krb_mk_req().
+ *
+ * Mutual authentication is not implemented.
+ */
+
+krb_rd_req(authent,service,instance,from_addr,ad,fn)
+ register KTEXT authent; /* The received message */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ long from_addr; /* Net address of originating host */
+ AUTH_DAT *ad; /* Structure to be filled in */
+ char *fn; /* Filename to get keys from */
+{
+ static KTEXT_ST ticket; /* Temp storage for ticket */
+ static KTEXT tkt = &ticket;
+ static KTEXT_ST req_id_st; /* Temp storage for authenticator */
+ register KTEXT req_id = &req_id_st;
+
+ char realm[REALM_SZ]; /* Realm of issuing kerberos */
+ static Key_schedule seskey_sched; /* Key sched for session key */
+ unsigned char skey[KKEY_SZ]; /* Session key from ticket */
+ char sname[SNAME_SZ]; /* Service name from ticket */
+ char iname[INST_SZ]; /* Instance name from ticket */
+ char r_aname[ANAME_SZ]; /* Client name from authenticator */
+ char r_inst[INST_SZ]; /* Client instance from authenticator */
+ char r_realm[REALM_SZ]; /* Client realm from authenticator */
+ unsigned int r_time_ms; /* Fine time from authenticator */
+ unsigned long r_time_sec; /* Coarse time from authenticator */
+ register char *ptr; /* For stepping through */
+ unsigned long delta_t; /* Time in authenticator - local time */
+ long tkt_age; /* Age of ticket */
+ static int swap_bytes; /* Need to swap bytes? */
+ static int mutual; /* Mutual authentication requested? */
+ static unsigned char s_kvno;/* Version number of the server's key
+ * Kerberos used to encrypt ticket */
+ int status;
+
+ if (authent->length <= 0)
+ return(RD_AP_MODIFIED);
+
+ ptr = (char *) authent->dat;
+
+ /* get msg version, type and byte order, and server key version */
+
+ /* check version */
+ if (KRB_PROT_VERSION != (unsigned int) *ptr++)
+ return(RD_AP_VERSION);
+
+ /* byte order */
+ swap_bytes = 0;
+ if ((*ptr & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* check msg type */
+ mutual = 0;
+ switch (*ptr++ & ~1) {
+ case AUTH_MSG_APPL_REQUEST:
+ break;
+ case AUTH_MSG_APPL_REQUEST_MUTUAL:
+ mutual++;
+ break;
+ default:
+ return(RD_AP_MSG_TYPE);
+ }
+
+#ifdef lint
+ /* XXX mutual is set but not used; why??? */
+ /* this is a crock to get lint to shut up */
+ if (mutual)
+ mutual = 0;
+#endif /* lint */
+ s_kvno = *ptr++; /* get server key version */
+ (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
+ ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+
+ /*
+ * If "fn" is NULL, key info should already be set; don't
+ * bother with ticket file. Otherwise, check to see if we
+ * already have key info for the given server and key version
+ * (saved in the static st_* variables). If not, go get it
+ * from the ticket file. If "fn" is the null string, use the
+ * default ticket file.
+ */
+ if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
+ strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+ if (*fn == 0) fn = KEYFILE;
+ st_kvno = s_kvno;
+#ifndef NOENCRYPTION
+ if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey))
+ return(RD_AP_UNDEC);
+ if (status=krb_set_key((char *)skey,0)) return(status);
+#endif
+ (void) strcpy(st_rlm,realm);
+ (void) strcpy(st_nam,service);
+ (void) strcpy(st_inst,instance);
+ }
+
+ /* Get ticket from authenticator */
+ tkt->length = (int) *ptr++;
+ if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
+
+ if (krb_ap_req_debug)
+ log("ticket->length: %d",tkt->length);
+
+#ifndef NOENCRYPTION
+ /* Decrypt and take apart ticket */
+#endif
+
+ if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm,
+ &(ad->address),ad->session, &(ad->life),
+ &(ad->time_sec),sname,iname,ky,serv_key))
+ return(RD_AP_UNDEC);
+
+ if (krb_ap_req_debug) {
+ log("Ticket Contents.");
+ log(" Aname: %s.%s",ad->pname,
+ ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+ log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname);
+ }
+
+ /* Extract the authenticator */
+ req_id->length = (int) *(ptr++);
+ if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
+ authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
+
+#ifndef NOENCRYPTION
+ key_sched(ad->session,seskey_sched);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,seskey_sched,ad->session,DES_DECRYPT);
+#endif /* NOENCRYPTION */
+
+#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
+
+ ptr = (char *) req_id->dat;
+ (void) strcpy(r_aname,ptr); /* Authentication name */
+ ptr += strlen(r_aname)+1;
+ check_ptr();
+ (void) strcpy(r_inst,ptr); /* Authentication instance */
+ ptr += strlen(r_inst)+1;
+ check_ptr();
+ (void) strcpy(r_realm,ptr); /* Authentication name */
+ ptr += strlen(r_realm)+1;
+ check_ptr();
+ bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */
+ ptr += 4;
+ check_ptr();
+ if (swap_bytes) swap_u_long(ad->checksum);
+ r_time_ms = *(ptr++); /* Time (fine) */
+#ifdef lint
+ /* XXX r_time_ms is set but not used. why??? */
+ /* this is a crock to get lint to shut up */
+ if (r_time_ms)
+ r_time_ms = 0;
+#endif /* lint */
+ check_ptr();
+ /* assume sizeof(r_time_sec) == 4 ?? */
+ bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(r_time_sec);
+
+ /* Check for authenticity of the request */
+ if (krb_ap_req_debug)
+ log("Pname: %s %s",ad->pname,r_aname);
+ if (strcmp(ad->pname,r_aname) != 0)
+ return(RD_AP_INCON);
+ if (strcmp(ad->pinst,r_inst) != 0)
+ return(RD_AP_INCON);
+ if (krb_ap_req_debug)
+ log("Realm: %s %s",ad->prealm,r_realm);
+ if ((strcmp(ad->prealm,r_realm) != 0))
+ return(RD_AP_INCON);
+
+ if (krb_ap_req_debug)
+ log("Address: %d %d",ad->address,from_addr);
+ if (from_addr && (ad->address != from_addr))
+ return(RD_AP_BADD);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ delta_t = abs((int)(t_local.tv_sec - r_time_sec));
+ if (delta_t > CLOCK_SKEW) {
+ if (krb_ap_req_debug)
+ log("Time out of range: %d - %d = %d",
+ t_local.tv_sec,r_time_sec,delta_t);
+ return(RD_AP_TIME);
+ }
+
+ /* Now check for expiration of ticket */
+
+ tkt_age = t_local.tv_sec - ad->time_sec;
+ if (krb_ap_req_debug)
+ log("Time: %d Issue Date: %d Diff: %d Life %x",
+ t_local.tv_sec,ad->time_sec,tkt_age,ad->life);
+
+ if (t_local.tv_sec < ad->time_sec) {
+ if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW)
+ return(RD_AP_NYV);
+ }
+ else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life)
+ return(RD_AP_EXP);
+
+ /* All seems OK */
+ ad->reply.length = 0;
+
+ return(RD_AP_OK);
+}
diff --git a/eBones/krb/rd_safe.c b/eBones/krb/rd_safe.c
new file mode 100644
index 0000000..e500b4d
--- /dev/null
+++ b/eBones/krb/rd_safe.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg', checking its
+ * integrity, and returning a pointer to the application data
+ * contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $
+ * $Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static C_Block calc_cksum[2];
+static C_Block big_cksum[2];
+static int swap_bytes;
+static struct timeval local_time;
+static u_long delta_t;
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data". The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender's address */
+ struct sockaddr_in *receiver; /* receiver's address -- me */
+ MSG_DAT *m_data; /* where to put message information */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+ /* Be very conservative */
+ if (sizeof(u_long) != sizeof(struct in_addr)) {
+ fprintf(stderr,"\n\
+krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
+ exit(-1);
+ }
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION;
+ if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+
+ q = p; /* mark start of cksum stuff */
+
+ /* safely get length */
+ bcopy((char *)p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes) swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(in_length)
+ + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
+ + sizeof(big_cksum) + sizeof(src_addr)
+ + VERSION_SZ + MSG_TYPE_SZ > in_length)
+ return(RD_AP_MODIFIED);
+
+ m_data->app_data = p; /* we're now at the application data */
+
+ /* skip app data */
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *)p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
+
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *)p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes)
+ swap_u_long(m_data->time_sec);
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+ /*
+ * caller must check timestamps for proper order and replays, since
+ * server might have multiple clients each with its own timestamps
+ * and we don't assume tightly synchronized clocks.
+ */
+
+ bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
+ if (swap_bytes) swap_u_16(big_cksum);
+
+#ifdef NOENCRYPTION
+ bzero(calc_cksum, sizeof(calc_cksum));
+#else
+ quad_cksum(q,calc_cksum,p-q,2,key);
+#endif
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ (long) calc_cksum[0], (long) big_cksum[0]);
+ if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
+ return(RD_AP_MODIFIED);
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/krb/read_service_key.c b/eBones/krb/read_service_key.c
new file mode 100644
index 0000000..4d66710
--- /dev/null
+++ b/eBones/krb/read_service_key.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $
+ * $Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <stdio.h>
+#include <strings.h>
+
+/*
+ * The private keys for servers on a given host are stored in a
+ * "srvtab" file (typically "/etc/srvtab"). This routine extracts
+ * a given server's key from the file.
+ *
+ * read_service_key() takes the server's name ("service"), "instance",
+ * and "realm" and a key version number "kvno", and looks in the given
+ * "file" for the corresponding entry, and if found, returns the entry's
+ * key field in "key".
+ *
+ * If "instance" contains the string "*", then it will match
+ * any instance, and the chosen instance will be copied to that
+ * string. For this reason it is important that the there is enough
+ * space beyond the "*" to receive the entry.
+ *
+ * If "kvno" is 0, it is treated as a wild card and the first
+ * matching entry regardless of the "vno" field is returned.
+ *
+ * This routine returns KSUCCESS on success, otherwise KFAILURE.
+ *
+ * The format of each "srvtab" entry is as follows:
+ *
+ * Size Variable Field in file
+ * ---- -------- -------------
+ * string serv server name
+ * string inst server instance
+ * string realm server realm
+ * 1 byte vno server key version #
+ * 8 bytes key server's key
+ * ... ... ...
+ */
+
+
+/*ARGSUSED */
+read_service_key(service,instance,realm,kvno,file,key)
+ char *service; /* Service Name */
+ char *instance; /* Instance name or "*" */
+ char *realm; /* Realm */
+ int kvno; /* Key version number */
+ char *file; /* Filename */
+ char *key; /* Pointer to key to be filled in */
+{
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char vno; /* Key version number */
+ int wcard;
+
+ int stab, open();
+
+ if ((stab = open(file, 0, 0)) < NULL)
+ return(KFAILURE);
+
+ wcard = (instance[0] == '*') && (instance[1] == '\0');
+
+ while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
+ (void) getst(stab,inst,INST_SZ); /* Instance */
+ (void) getst(stab,rlm,REALM_SZ); /* Realm */
+ /* Vers number */
+ if (read(stab,(char *)&vno,1) != 1) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Key */
+ if (read(stab,key,8) != 8) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Is this the right service */
+ if (strcmp(serv,service))
+ continue;
+ /* How about instance */
+ if (!wcard && strcmp(inst,instance))
+ continue;
+ if (wcard)
+ (void) strncpy(instance,inst,INST_SZ);
+ /* Is this the right realm */
+#ifdef ATHENA_COMPAT
+ /* XXX For backward compatibility: if keyfile says "Athena"
+ and caller wants "ATHENA.MIT.EDU", call it a match */
+ if (strcmp(rlm,realm) &&
+ (strcmp(rlm,"Athena") ||
+ strcmp(realm,"ATHENA.MIT.EDU")))
+ continue;
+#else /* ! ATHENA_COMPAT */
+ if (strcmp(rlm,realm))
+ continue;
+#endif /* ATHENA_COMPAT */
+
+ /* How about the key version number */
+ if (kvno && kvno != (int) vno)
+ continue;
+
+ (void) close(stab);
+ return(KSUCCESS);
+ }
+
+ /* Can't find the requested service */
+ (void) close(stab);
+ return(KFAILURE);
+}
diff --git a/eBones/krb/recvauth.c b/eBones/krb/recvauth.c
new file mode 100644
index 0000000..fe26814
--- /dev/null
+++ b/eBones/krb/recvauth.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $";
+ * $Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
+ chars */
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_sendauth.c
+ * be sure to support old versions of krb_sendauth!
+ */
+
+extern int errno;
+
+/*
+ * krb_recvauth() reads (and optionally responds to) a message sent
+ * using krb_sendauth(). The "options" argument is a bit-field of
+ * selected options (see "sendauth.c" for options description).
+ * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
+ * (mutual authentication requested). The "fd" argument supplies
+ * a file descriptor to read from (and write to, if mutual authenti-
+ * cation is requested).
+ *
+ * Part of the received message will be a Kerberos ticket sent by the
+ * client; this is read into the "ticket" argument. The "service" and
+ * "instance" arguments supply the server's Kerberos name. If the
+ * "instance" argument is the string "*", it is treated as a wild card
+ * and filled in during the krb_rd_req() call (see read_service_key()).
+ *
+ * The "faddr" and "laddr" give the sending (client) and receiving
+ * (local server) network addresses. ("laddr" may be left NULL unless
+ * mutual authentication is requested, in which case it must be set.)
+ *
+ * The authentication information extracted from the message is returned
+ * in "kdata". The "filename" argument indicates the file where the
+ * server's key can be found. (It is passed on to krb_rd_req().) If
+ * left null, the default "/etc/srvtab" will be used.
+ *
+ * If mutual authentication is requested, the session key schedule must
+ * be computed in order to reply; this schedule is returned in the
+ * "schedule" argument. A string containing the application version
+ * number from the received message is returned in "version", which
+ * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
+ *
+ * See krb_sendauth() for the format of the received client message.
+ *
+ * This routine supports another client format, for backward
+ * compatibility, consisting of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * string tmp_buf, tkt_len length of ticket, in
+ * ascii
+ *
+ * char ' ' (space char) separator
+ *
+ * tkt_len ticket->dat the ticket
+ *
+ * This old-style version does not support mutual authentication.
+ *
+ * krb_recvauth() first reads the protocol version string from the
+ * given file descriptor. If it doesn't match the current protocol
+ * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In
+ * that case, the string of characters up to the first space is read
+ * and interpreted as the ticket length, then the ticket is read.
+ *
+ * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
+ * next reads the application protocol version string. Then the
+ * ticket length and ticket itself are read.
+ *
+ * The ticket is decrypted and checked by the call to krb_rd_req().
+ * If no mutual authentication is required, the result of the
+ * krb_rd_req() call is retured by this routine. If mutual authenti-
+ * cation is required, a message in the following format is returned
+ * on "fd":
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 4 bytes tkt_len length of ticket or -1
+ * if error occurred
+ *
+ * priv_len tmp_buf "private" message created
+ * by krb_mk_priv() which
+ * contains the incremented
+ * checksum sent by the client
+ * encrypted in the session
+ * key. (This field is not
+ * present in case of error.)
+ *
+ * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
+ * other error code is returned.
+ */
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+int
+krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+ filename, schedule, version)
+long options; /* bit-pattern of options */
+int fd; /* file descr. to read from */
+KTEXT ticket; /* storage for client's ticket */
+char *service; /* service expected */
+char *instance; /* inst expected (may be filled in) */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+struct sockaddr_in *laddr; /* local address */
+AUTH_DAT *kdata; /* kerberos data (returned) */
+char *filename; /* name of file with service keys */
+Key_schedule schedule; /* key schedule (return) */
+char *version; /* version string (filled in) */
+{
+
+ int i, cc, old_vers = 0;
+ char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
+ char *cp;
+ int rem;
+ long tkt_len, priv_len;
+ u_long cksum;
+ u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+ /* read the protocol version number */
+ if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ krb_vers[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* check version string */
+ if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
+ /* Assume the old version of sendkerberosdata: send ascii
+ length, ' ', and ticket. */
+ if (options & KOPT_DO_MUTUAL)
+ return(KFAILURE); /* XXX can't do old style with mutual auth */
+ old_vers = 1;
+
+ /* copy what we have read into tmp_buf */
+ (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
+
+ /* search for space, and make it a null */
+ for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
+ if (tmp_buf[i]== ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+
+ if (i == KRB_SENDAUTH_VLEN)
+ /* didn't find the space, keep reading to find it */
+ for (; i<20; i++) {
+ if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
+ return(KFAILURE);
+ }
+ if (tmp_buf[i] == ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+ }
+
+ tkt_len = (long) atoi((char *) tmp_buf);
+
+ /* sanity check the length */
+ if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
+ return(KFAILURE);
+
+ if (i < KRB_SENDAUTH_VLEN) {
+ /* since we already got the space, and part of the ticket,
+ we read fewer bytes to get the rest of the ticket */
+ if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
+ (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ return(errno);
+ } else {
+ if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
+ (int) tkt_len)
+ return(errno);
+ }
+ ticket->length = tkt_len;
+ /* copy the ticket into the struct */
+ (void) bcopy(cp, (char *) ticket->dat, ticket->length);
+
+ } else {
+ /* read the application version string */
+ if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ version[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* get the length of the ticket */
+ if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+
+ /* sanity check */
+ ticket->length = ntohl((unsigned long)tkt_len);
+ if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+ if (options & KOPT_DO_MUTUAL) {
+ rem = KFAILURE;
+ goto mutual_fail;
+ } else
+ return(KFAILURE); /* XXX there may still be junk on the fd? */
+ }
+
+ /* read the ticket */
+ if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+ != ticket->length)
+ return(errno);
+ }
+ /*
+ * now have the ticket. decrypt it to get the authenticated
+ * data.
+ */
+ rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+ kdata,filename);
+
+ if (old_vers) return(rem); /* XXX can't do mutual with old client */
+
+ /* if we are doing mutual auth, compose a response */
+ if (options & KOPT_DO_MUTUAL) {
+ if (rem != KSUCCESS)
+ /* the krb_rd_req failed */
+ goto mutual_fail;
+
+ /* add one to the (formerly) sealed checksum, and re-seal it
+ for return to the client */
+ cksum = kdata->checksum + 1;
+ cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+ key_sched(kdata->session,schedule);
+#endif
+ priv_len = krb_mk_priv((unsigned char *)&cksum,
+ tmp_buf,
+ (unsigned long) sizeof(cksum),
+ schedule,
+ kdata->session,
+ laddr,
+ faddr);
+ if (priv_len < 0) {
+ /* re-sealing failed; notify the client */
+ rem = KFAILURE; /* XXX */
+mutual_fail:
+ priv_len = -1;
+ tkt_len = htonl((unsigned long) priv_len);
+ /* a length of -1 is interpreted as an authentication
+ failure by the client */
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ return(rem);
+ } else {
+ /* re-sealing succeeded, send the private message */
+ tkt_len = htonl((unsigned long)priv_len);
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+ != (int) priv_len)
+ return(cc);
+ }
+ }
+ return(rem);
+}
diff --git a/eBones/krb/save_credentials.c b/eBones/krb/save_credentials.c
new file mode 100644
index 0000000..129c912
--- /dev/null
+++ b/eBones/krb/save_credentials.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $
+ * $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * This routine takes a ticket and associated info and calls
+ * tf_save_cred() to store them in the ticket cache. The peer
+ * routine for extracting a ticket and associated info from the
+ * ticket cache is krb_get_cred(). When changes are made to
+ * this routine, the corresponding changes should be made
+ * in krb_get_cred() as well.
+ *
+ * Returns KSUCCESS if all goes well, otherwise an error returned
+ * by the tf_init() or tf_save_cred() routines.
+ */
+
+save_credentials(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+ int tf_status; /* return values of the tf_util calls */
+
+ /* Open and lock the ticket file for writing */
+ if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Save credentials by appending to the ticket file */
+ tf_status = tf_save_cred(service, instance, realm, session,
+ lifetime, kvno, ticket, issue_date);
+ (void) tf_close();
+ return (tf_status);
+}
diff --git a/eBones/krb/send_to_kdc.c b/eBones/krb/send_to_kdc.c
new file mode 100644
index 0000000..aeaf389
--- /dev/null
+++ b/eBones/krb/send_to_kdc.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $
+ * $Id: send_to_kdc.c,v 1.2 1994/07/19 19:26:21 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid_send_to_kdc_c[] =
+"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp ";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef lint
+#include <sys/uio.h> /* struct iovec to make lint happy */
+#endif /* lint */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <strings.h>
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+extern int errno;
+extern int krb_debug;
+
+extern char *malloc(), *calloc(), *realloc();
+
+int krb_udp_port = 0;
+
+/* CLIENT_KRB_TIMEOUT indicates the time to wait before
+ * retrying a server. It's defined in "krb.h".
+ */
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};
+static char *prog = "send_to_kdc";
+static send_recv();
+
+/*
+ * This file contains two routines, send_to_kdc() and send_recv().
+ * send_recv() is a static routine used by send_to_kdc().
+ */
+
+/*
+ * send_to_kdc() sends a message to the Kerberos authentication
+ * server(s) in the given realm and returns the reply message.
+ * The "pkt" argument points to the message to be sent to Kerberos;
+ * the "rpkt" argument will be filled in with Kerberos' reply.
+ * The "realm" argument indicates the realm of the Kerberos server(s)
+ * to transact with. If the realm is null, the local realm is used.
+ *
+ * If more than one Kerberos server is known for a given realm,
+ * different servers will be queried until one of them replies.
+ * Several attempts (retries) are made for each server before
+ * giving up entirely.
+ *
+ * If an answer was received from a Kerberos host, KSUCCESS is
+ * returned. The following errors can be returned:
+ *
+ * SKDC_CANT - can't get local realm
+ * - can't find "kerberos" in /etc/services database
+ * - can't open socket
+ * - can't bind socket
+ * - all ports in use
+ * - couldn't find any Kerberos host
+ *
+ * SKDC_RETRY - couldn't get an answer from any Kerberos server,
+ * after several retries
+ */
+
+send_to_kdc(pkt,rpkt,realm)
+ KTEXT pkt;
+ KTEXT rpkt;
+ char *realm;
+{
+ int i, f;
+ int no_host; /* was a kerberos host found? */
+ int retry;
+ int n_hosts;
+ int retval;
+ struct sockaddr_in to;
+ struct hostent *host, *hostlist;
+ char *cp;
+ char krbhst[MAX_HSTNM];
+ char lrealm[REALM_SZ];
+
+ /*
+ * If "realm" is non-null, use that, otherwise get the
+ * local realm.
+ */
+ if (realm)
+ (void) strcpy(lrealm, realm);
+ else
+ if (krb_get_lrealm(lrealm,1)) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't get local realm\n", prog);
+ return(SKDC_CANT);
+ }
+ if (krb_debug)
+ printf("lrealm is %s\n", lrealm);
+ if (krb_udp_port == 0) {
+ register struct servent *sp;
+ if ((sp = getservbyname("kerberos","udp")) == 0) {
+ if (krb_debug)
+ fprintf(stderr, "%s: Can't get kerberos/udp service\n",
+ prog);
+ return(SKDC_CANT);
+ }
+ krb_udp_port = sp->s_port;
+ if (krb_debug)
+ printf("krb_udp_port is %d\n", krb_udp_port);
+ }
+ bzero((char *)&to, S_AD_SZ);
+ hostlist = (struct hostent *) malloc(sizeof(struct hostent));
+ if (!hostlist)
+ return (/*errno */SKDC_CANT);
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"%s: Can't open socket\n", prog);
+ return(SKDC_CANT);
+ }
+ /* from now on, exit through rtn label for cleanup */
+
+ no_host = 1;
+ /* get an initial allocation */
+ n_hosts = 0;
+ for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
+ if (krb_debug) {
+ printf("Getting host entry for %s...",krbhst);
+ (void) fflush(stdout);
+ }
+ host = gethostbyname(krbhst);
+ if (krb_debug) {
+ printf("%s.\n",
+ host ? "Got it" : "Didn't get it");
+ (void) fflush(stdout);
+ }
+ if (!host)
+ continue;
+ no_host = 0; /* found at least one */
+ n_hosts++;
+ /* preserve host network address to check later
+ * (would be better to preserve *all* addresses,
+ * take care of that later)
+ */
+ hostlist = (struct hostent *)
+ realloc((char *)hostlist,
+ (unsigned)
+ sizeof(struct hostent)*(n_hosts+1));
+ if (!hostlist)
+ return /*errno */SKDC_CANT;
+ bcopy((char *)host, (char *)&hostlist[n_hosts-1],
+ sizeof(struct hostent));
+ host = &hostlist[n_hosts-1];
+ cp = malloc((unsigned)host->h_length);
+ if (!cp) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+ bcopy((char *)host->h_addr, cp, host->h_length);
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+ (or worse) only return one name ... */
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ host->h_addr_list = (char **)malloc(sizeof(char *));
+ if (!host->h_addr_list) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+#endif /* ULTRIX022 || SunOS */
+ host->h_addr = cp;
+ bzero((char *)&hostlist[n_hosts],
+ sizeof(struct hostent));
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ to.sin_port = krb_udp_port;
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ if (krb_debug) {
+ printf("Timeout, error, or wrong descriptor\n");
+ (void) fflush(stdout);
+ }
+ }
+ if (no_host) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't find any Kerberos host.\n",
+ prog);
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ /* retry each host in sequence */
+ for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
+ for (host = hostlist; host->h_name != (char *)NULL; host++) {
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ }
+ }
+ retval = SKDC_RETRY;
+rtn:
+ (void) close(f);
+ if (hostlist) {
+ register struct hostent *hp;
+ for (hp = hostlist; hp->h_name; hp++)
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ if (hp->h_addr_list) {
+#endif /* ULTRIX022 || SunOS */
+ if (hp->h_addr)
+ free(hp->h_addr);
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ free((char *)hp->h_addr_list);
+ }
+#endif /* ULTRIX022 || SunOS */
+ free((char *)hostlist);
+ }
+ return(retval);
+}
+
+/*
+ * try to send out and receive message.
+ * return 1 on success, 0 on failure
+ */
+
+static send_recv(pkt,rpkt,f,_to,addrs)
+ KTEXT pkt;
+ KTEXT rpkt;
+ int f;
+ struct sockaddr_in *_to;
+ struct hostent *addrs;
+{
+ fd_set readfds;
+ register struct hostent *hp;
+ struct sockaddr_in from;
+ int sin_size;
+ int numsent;
+
+ if (krb_debug) {
+ if (_to->sin_family == AF_INET)
+ printf("Sending message to %s...",
+ inet_ntoa(_to->sin_addr));
+ else
+ printf("Sending message...");
+ (void) fflush(stdout);
+ }
+ if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0,
+ (struct sockaddr *)_to,
+ S_AD_SZ)) != pkt->length) {
+ if (krb_debug)
+ printf("sent only %d/%d\n",numsent, pkt->length);
+ return 0;
+ }
+ if (krb_debug) {
+ printf("Sent\nWaiting for reply...");
+ (void) fflush(stdout);
+ }
+ FD_ZERO(&readfds);
+ FD_SET(f, &readfds);
+ errno = 0;
+ /* select - either recv is ready, or timeout */
+ /* see if timeout or error or wrong descriptor */
+ if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1
+ || !FD_ISSET(f, &readfds)) {
+ if (krb_debug) {
+ fprintf(stderr, "select failed: readfds=%x",
+ readfds);
+ perror("");
+ }
+ return 0;
+ }
+ sin_size = sizeof(from);
+ if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0,
+ (struct sockaddr *)&from, &sin_size)
+ < 0) {
+ if (krb_debug)
+ perror("recvfrom");
+ return 0;
+ }
+ if (krb_debug) {
+ printf("received packet from %s\n", inet_ntoa(from.sin_addr));
+ fflush(stdout);
+ }
+ for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+ if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr,
+ hp->h_length)) {
+ if (krb_debug) {
+ printf("Received it\n");
+ (void) fflush(stdout);
+ }
+ return 1;
+ }
+ if (krb_debug)
+ fprintf(stderr,
+ "packet not from %x\n",
+ hp->h_addr);
+ }
+ if (krb_debug)
+ fprintf(stderr, "%s: received packet from wrong host! (%x)\n",
+ "send_to_kdc(send_rcv)", from.sin_addr.s_addr);
+ return 0;
+}
diff --git a/eBones/krb/sendauth.c b/eBones/krb/sendauth.c
new file mode 100644
index 0000000..7d798bb
--- /dev/null
+++ b/eBones/krb/sendauth.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $
+ * $Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_recvauth.c
+ */
+
+extern int errno;
+
+extern char *krb_get_phost();
+
+/*
+ * This file contains two routines: krb_sendauth() and krb_sendsrv().
+ *
+ * krb_sendauth() transmits a ticket over a file descriptor for a
+ * desired service, instance, and realm, doing mutual authentication
+ * with the server if desired.
+ *
+ * krb_sendsvc() sends a service name to a remote knetd server.
+ */
+
+/*
+ * The first argument to krb_sendauth() contains a bitfield of
+ * options (the options are defined in "krb.h"):
+ *
+ * KOPT_DONT_CANON Don't canonicalize instance as a hostname.
+ * (If this option is not chosen, krb_get_phost()
+ * is called to canonicalize it.)
+ *
+ * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos.
+ * A ticket must be supplied in the "ticket"
+ * argument.
+ * (If this option is not chosen, and there
+ * is no ticket for the given server in the
+ * ticket cache, one will be fetched using
+ * krb_mk_req() and returned in "ticket".)
+ *
+ * KOPT_DO_MUTUAL Do mutual authentication, requiring that the
+ * receiving server return the checksum+1 encrypted
+ * in the session key. The mutual authentication
+ * is done using krb_mk_priv() on the other side
+ * (see "recvauth.c") and krb_rd_priv() on this
+ * side.
+ *
+ * The "fd" argument is a file descriptor to write to the remote
+ * server on. The "ticket" argument is used to store the new ticket
+ * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
+ * chosen, the ticket must be supplied in the "ticket" argument.
+ * The "service", "inst", and "realm" arguments identify the ticket.
+ * If "realm" is null, the local realm is used.
+ *
+ * The following arguments are only needed if the KOPT_DO_MUTUAL option
+ * is chosen:
+ *
+ * The "checksum" argument is a number that the server will add 1 to
+ * to authenticate itself back to the client; the "msg_data" argument
+ * holds the returned mutual-authentication message from the server
+ * (i.e., the checksum+1); the "cred" structure is used to hold the
+ * session key of the server, extracted from the ticket file, for use
+ * in decrypting the mutual authentication message from the server;
+ * and "schedule" holds the key schedule for that decryption. The
+ * the local and server addresses are given in "laddr" and "faddr".
+ *
+ * The application protocol version number (of up to KRB_SENDAUTH_VLEN
+ * characters) is passed in "version".
+ *
+ * If all goes well, KSUCCESS is returned, otherwise some error code.
+ *
+ * The format of the message sent to the server is:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol
+ * bytes version number
+ *
+ * KRB_SENDAUTH_VLEN version application protocol
+ * bytes version number
+ *
+ * 4 bytes ticket->length length of ticket
+ *
+ * ticket->length ticket->dat ticket itself
+ */
+
+/*
+ * XXX: Note that krb_rd_priv() is coded in such a way that
+ * "msg_data->app_data" will be pointing into "priv_buf", which
+ * will disappear when krb_sendauth() returns.
+ */
+
+int
+krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
+ msg_data, cred, schedule, laddr, faddr, version)
+long options; /* bit-pattern of options */
+int fd; /* file descriptor to write onto */
+KTEXT ticket; /* where to put ticket (return); or
+ * supplied in case of KOPT_DONT_MK_REQ */
+char *service, *inst, *realm; /* service name, instance, realm */
+u_long checksum; /* checksum to include in request */
+MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */
+CREDENTIALS *cred; /* credentials (return) */
+Key_schedule schedule; /* key schedule (return) */
+struct sockaddr_in *laddr; /* local address */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+char *version; /* version string */
+{
+ int rem, i, cc;
+ char srv_inst[INST_SZ];
+ char krb_realm[REALM_SZ];
+ char buf[BUFSIZ];
+ long tkt_len;
+ u_char priv_buf[1024];
+ u_long cksum;
+
+ rem=KSUCCESS;
+
+ /* get current realm if not passed in */
+ if (!realm) {
+ rem = krb_get_lrealm(krb_realm,1);
+ if (rem != KSUCCESS)
+ return(rem);
+ realm = krb_realm;
+ }
+
+ /* copy instance into local storage, canonicalizing if desired */
+ if (options & KOPT_DONT_CANON)
+ (void) strncpy(srv_inst, inst, INST_SZ);
+ else
+ (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
+
+ /* get the ticket if desired */
+ if (!(options & KOPT_DONT_MK_REQ)) {
+ rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
+ if (rem != KSUCCESS)
+ return(rem);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* this is only for compatibility with old servers */
+ if (options & KOPT_DO_OLDSTYLE) {
+ (void) sprintf(buf,"%d ",ticket->length);
+ (void) write(fd, buf, strlen(buf));
+ (void) write(fd, (char *) ticket->dat, ticket->length);
+ return(rem);
+ }
+#endif ATHENA_COMPAT
+ /* if mutual auth, get credentials so we have service session
+ keys for decryption below */
+ if (options & KOPT_DO_MUTUAL)
+ if (cc = krb_get_cred(service, srv_inst, realm, cred))
+ return(cc);
+
+ /* zero the buffer */
+ (void) bzero(buf, BUFSIZ);
+
+ /* insert version strings */
+ (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+ (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
+
+ /* increment past vers strings */
+ i = 2*KRB_SENDAUTH_VLEN;
+
+ /* put ticket length into buffer */
+ tkt_len = htonl((unsigned long) ticket->length);
+ (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
+ i += sizeof(tkt_len);
+
+ /* put ticket into buffer */
+ (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
+ i += ticket->length;
+
+ /* write the request to the server */
+ if ((cc = krb_net_write(fd, buf, i)) != i)
+ return(cc);
+
+ /* mutual authentication, if desired */
+ if (options & KOPT_DO_MUTUAL) {
+ /* get the length of the reply */
+ if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+ tkt_len = ntohl((unsigned long)tkt_len);
+
+ /* if the length is negative, the server failed to recognize us. */
+ if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf)))
+ return(KFAILURE); /* XXX */
+ /* read the reply... */
+ if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
+ return(errno);
+
+ /* ...and decrypt it */
+#ifndef NOENCRYPTION
+ key_sched(cred->session,schedule);
+#endif
+ if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule,
+ cred->session, faddr, laddr, msg_data))
+ return(cc);
+
+ /* fetch the (modified) checksum */
+ (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
+ sizeof(cksum));
+ cksum = ntohl(cksum);
+
+ /* if it doesn't match, fail */
+ if (cksum != checksum + 1)
+ return(KFAILURE); /* XXX */
+ }
+ return(KSUCCESS);
+}
+
+#ifdef ATHENA_COMPAT
+/*
+ * krb_sendsvc
+ */
+
+int
+krb_sendsvc(fd, service)
+int fd;
+char *service;
+{
+ /* write the service name length and then the service name to
+ the fd */
+ long serv_length;
+ int cc;
+
+ serv_length = htonl((unsigned long)strlen(service));
+ if ((cc = krb_net_write(fd, (char *) &serv_length,
+ sizeof(serv_length)))
+ != sizeof(serv_length))
+ return(cc);
+ if ((cc = krb_net_write(fd, service, strlen(service)))
+ != strlen(service))
+ return(cc);
+ return(KSUCCESS);
+}
+#endif ATHENA_COMPAT
diff --git a/eBones/krb/stime.c b/eBones/krb/stime.c
new file mode 100644
index 0000000..c040374
--- /dev/null
+++ b/eBones/krb/stime.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $
+ * $Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h> /* for sprintf() */
+
+/*
+ * Given a pointer to a long containing the number of seconds
+ * since the beginning of time (midnight 1 Jan 1970 GMT), return
+ * a string containing the local time in the form:
+ *
+ * "25-Jan-88 10:17:56"
+ */
+
+char *stime(t)
+ long *t;
+{
+ static char st_data[40];
+ static char *st = st_data;
+ struct tm *tm;
+ char *month_sname();
+
+ tm = localtime(t);
+ (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return st;
+}
diff --git a/eBones/krb/tf_shm.c b/eBones/krb/tf_shm.c
new file mode 100644
index 0000000..5548f0d
--- /dev/null
+++ b/eBones/krb/tf_shm.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Shared memory segment functions for session keys. Derived from code
+ * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
+ *
+ * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $
+ * $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <krb.h>
+#include <des.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */
+
+extern int errno;
+extern int krb_debug;
+
+/*
+ * krb_create_shmtkt:
+ *
+ * create a shared memory segment for session keys, leaving its id
+ * in the specified filename.
+ */
+
+int
+krb_shm_create(file_name)
+char *file_name;
+{
+ int retval;
+ int shmid;
+ struct shmid_ds shm_buf;
+ FILE *sfile;
+ uid_t me, metoo, getuid(), geteuid();
+
+ (void) krb_shm_dest(file_name); /* nuke it if it exists...
+ this cleans up to make sure we
+ don't slowly lose memory. */
+
+ shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT);
+ if (shmid == -1) {
+ if (krb_debug)
+ perror("krb_shm_create shmget");
+ return(KFAILURE); /* XXX */
+ }
+ me = getuid();
+ metoo = geteuid();
+ /*
+ * now set up the buffer so that we can modify it
+ */
+ shm_buf.shm_perm.uid = me;
+ shm_buf.shm_perm.gid = getgid();
+ shm_buf.shm_perm.mode = 0600;
+ if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */
+ if (krb_debug)
+ perror("krb_shm_create shmctl");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary). */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((sfile = fopen(file_name,"w")) == 0) {
+ if (krb_debug)
+ perror("krb_shm_create file");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (fchmod(fileno(sfile),0600) < 0) {
+ if (krb_debug)
+ perror("krb_shm_create fchmod");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid2");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+
+ (void) fprintf(sfile,"%d",shmid);
+ (void) fflush(sfile);
+ (void) fclose(sfile);
+ return(KSUCCESS);
+}
+
+
+/*
+ * krb_is_diskless:
+ *
+ * check / to see if file .diskless exists. If so it is diskless.
+ * Do it this way now to avoid dependencies on a particular routine.
+ * Choose root file system since that will be private to the client.
+ */
+
+int krb_is_diskless()
+{
+ struct stat buf;
+ if (stat("/.diskless",&buf) < 0)
+ return(0);
+ else return(1);
+}
+
+/*
+ * krb_shm_dest: destroy shared memory segment with session keys, and remove
+ * file pointing to it.
+ */
+
+int krb_shm_dest(file)
+char *file;
+{
+ int shmid;
+ FILE *sfile;
+ struct stat st_buf;
+
+ if (stat(file,&st_buf) == 0) {
+ /* successful stat */
+ if ((sfile = fopen(file,"r")) == 0) {
+ if (krb_debug)
+ perror("cannot open shared memory file");
+ return(KFAILURE); /* XXX */
+ }
+ if (fscanf(sfile,"%d",&shmid) == 1) {
+ if (shmctl(shmid,IPC_RMID,0) != 0) {
+ if (krb_debug)
+ perror("krb_shm_dest: cannot delete shm segment");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ } else {
+ if (krb_debug)
+ fprintf(stderr, "bad format in shmid file\n");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ (void) fclose(sfile);
+ (void) unlink(file);
+ return(KSUCCESS);
+ } else
+ return(RET_TKFIL); /* XXX */
+}
+
+
+
diff --git a/eBones/krb/tf_util.3 b/eBones/krb/tf_util.3
new file mode 100644
index 0000000..3a9bc94
--- /dev/null
+++ b/eBones/krb/tf_util.3
@@ -0,0 +1,151 @@
+.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $
+.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \
+\- Routines for manipulating a Kerberos ticket file
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+tf_init(tf_name, rw)
+char *tf_name;
+int rw;
+.PP
+.ft B
+tf_get_pname(pname)
+char *pname;
+.PP
+.ft B
+tf_get_pinst(pinst)
+char *pinst;
+.PP
+.ft B
+tf_get_cred(c)
+CREDENTIALS *c;
+.PP
+.ft B
+tf_close()
+.PP
+.fi
+.SH DESCRIPTION
+This group of routines are provided to manipulate the Kerberos tickets
+file. A ticket file has the following format:
+.nf
+.in +4
+.sp
+principal's name (null-terminated string)
+principal's instance (null-terminated string)
+CREDENTIAL_1
+CREDENTIAL_2
+ ...
+CREDENTIAL_n
+EOF
+.sp
+.in -4
+.LP
+Where "CREDENTIAL_x" consists of the following fixed-length
+fields from the CREDENTIALS structure (defined in <krb.h>):
+.nf
+.sp
+.in +4
+ char service[ANAME_SZ]
+ char instance[INST_SZ]
+ char realm[REALM_SZ]
+ des_cblock session
+ int lifetime
+ int kvno
+ KTEXT_ST ticket_st
+ long issue_date
+.in -4
+.sp
+.fi
+.PP
+.I tf_init
+must be called before the other ticket file
+routines.
+It takes the name of the ticket file to use,
+and a read/write flag as arguments.
+It tries to open the ticket file, checks the mode and if
+everything is okay, locks the file. If it's opened for
+reading, the lock is shared. If it's opened for writing,
+the lock is exclusive.
+KSUCCESS is returned if all went well, otherwise one of the
+following:
+.nf
+.sp
+NO_TKT_FIL - file wasn't there
+TKT_FIL_ACC - file was in wrong mode, etc.
+TKT_FIL_LCK - couldn't lock the file, even after a retry
+.sp
+.fi
+.PP
+The
+.I tf_get_pname
+reads the principal's name from a ticket file.
+It should only be called after tf_init has been called. The
+principal's name is filled into the
+.I pname
+parameter. If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If the principal's name was null, or EOF was encountered, or the
+name was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+.PP
+The
+.I tf_get_pinst
+reads the principal's instance from a ticket file.
+It should only be called after tf_init and tf_get_pname
+have been called.
+The principal's instance is filled into the
+.I pinst
+parameter.
+If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If EOF was encountered, or the
+name was longer than INST_SZ, TKT_FIL_FMT is returned.
+Note that, unlike the principal name, the instance name may be null.
+.PP
+The
+.I tf_get_cred
+routine reads a CREDENTIALS record from a ticket file and
+fills in the given structure.
+It should only be called after
+tf_init, tf_get_pname, and tf_get_pinst have been called.
+If all goes well, KSUCCESS is returned. Possible error codes
+are:
+.nf
+.sp
+TKT_FIL_INI - tf_init wasn't called first
+TKT_FIL_FMT - bad format
+EOF - end of file encountered
+.sp
+.fi
+.PP
+.I tf_close
+closes the ticket file and releases the lock on it.
+.SH "SEE ALSO"
+krb(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The ticket file routines have to be called in a certain order.
+.SH AUTHORS
+Jennifer Steiner, MIT Project Athena
+.br
+Bill Bryant, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1987 Massachusetts Institute of Technology
diff --git a/eBones/krb/tf_util.c b/eBones/krb/tf_util.c
new file mode 100644
index 0000000..a9e8551
--- /dev/null
+++ b/eBones/krb/tf_util.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $
+ * $Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <krb.h>
+
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* TKT_SHMEM */
+
+#define TOO_BIG -1
+#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before
+ * retry if ticket file is
+ * locked */
+extern errno;
+extern int krb_debug;
+
+#ifdef TKT_SHMEM
+char *krb_shm_addr = 0;
+static char *tmp_shm_addr = 0;
+static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};
+
+char *shmat();
+#endif /* TKT_SHMEM */
+
+/*
+ * fd must be initialized to something that won't ever occur as a real
+ * file descriptor. Since open(2) returns only non-negative numbers as
+ * valid file descriptors, and tf_init always stuffs the return value
+ * from open in here even if it is an error flag, we must
+ * a. Initialize fd to a negative number, to indicate that it is
+ * not initially valid.
+ * b. When checking for a valid fd, assume that negative values
+ * are invalid (ie. when deciding whether tf_init has been
+ * called.)
+ * c. In tf_close, be sure it gets reinitialized to a negative
+ * number.
+ */
+static fd = -1;
+static curpos; /* Position in tfbfr */
+static lastpos; /* End of tfbfr */
+static char tfbfr[BUFSIZ]; /* Buffer for ticket data */
+
+static tf_gets(), tf_read();
+
+/*
+ * This file contains routines for manipulating the ticket cache file.
+ *
+ * The ticket file is in the following format:
+ *
+ * principal's name (null-terminated string)
+ * principal's instance (null-terminated string)
+ * CREDENTIAL_1
+ * CREDENTIAL_2
+ * ...
+ * CREDENTIAL_n
+ * EOF
+ *
+ * Where "CREDENTIAL_x" consists of the following fixed-length
+ * fields from the CREDENTIALS structure (see "krb.h"):
+ *
+ * char service[ANAME_SZ]
+ * char instance[INST_SZ]
+ * char realm[REALM_SZ]
+ * C_Block session
+ * int lifetime
+ * int kvno
+ * KTEXT_ST ticket_st
+ * long issue_date
+ *
+ * Short description of routines:
+ *
+ * tf_init() opens the ticket file and locks it.
+ *
+ * tf_get_pname() returns the principal's name.
+ *
+ * tf_get_pinst() returns the principal's instance (may be null).
+ *
+ * tf_get_cred() returns the next CREDENTIALS record.
+ *
+ * tf_save_cred() appends a new CREDENTIAL record to the ticket file.
+ *
+ * tf_close() closes the ticket file and releases the lock.
+ *
+ * tf_gets() returns the next null-terminated string. It's an internal
+ * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred().
+ *
+ * tf_read() reads a given number of bytes. It's an internal routine
+ * used by tf_get_cred().
+ */
+
+/*
+ * tf_init() should be called before the other ticket file routines.
+ * It takes the name of the ticket file to use, "tf_name", and a
+ * read/write flag "rw" as arguments.
+ *
+ * It tries to open the ticket file, checks the mode, and if everything
+ * is okay, locks the file. If it's opened for reading, the lock is
+ * shared. If it's opened for writing, the lock is exclusive.
+ *
+ * Returns KSUCCESS if all went well, otherwise one of the following:
+ *
+ * NO_TKT_FIL - file wasn't there
+ * TKT_FIL_ACC - file was in wrong mode, etc.
+ * TKT_FIL_LCK - couldn't lock the file, even after a retry
+ */
+
+tf_init(tf_name, rw)
+ char *tf_name;
+{
+ int wflag;
+ uid_t me, getuid();
+ struct stat stat_buf;
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+ FILE *sfp;
+ int shmid;
+#endif
+
+ switch (rw) {
+ case R_TKT_FIL:
+ wflag = 0;
+ break;
+ case W_TKT_FIL:
+ wflag = 1;
+ break;
+ default:
+ if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");
+ return TKT_FIL_ACC;
+ }
+ if (lstat(tf_name, &stat_buf) < 0)
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ me = getuid();
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, tf_name);
+ (void) strcat(shmidname, ".shm");
+ if (stat(shmidname,&stat_buf) < 0)
+ return(TKT_FIL_ACC);
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#endif /* TKT_SHMEM */
+
+ /*
+ * If "wflag" is set, open the ticket file in append-writeonly mode
+ * and lock the ticket file in exclusive mode. If unable to lock
+ * the file, sleep and try again. If we fail again, return with the
+ * proper error message.
+ */
+
+ curpos = sizeof(tfbfr);
+
+#ifdef TKT_SHMEM
+ sfp = fopen(shmidname, "r"); /* only need read/write on the
+ actual tickets */
+ if (sfp == 0)
+ return TKT_FIL_ACC;
+ shmid = -1;
+ {
+ char buf[BUFSIZ];
+ int val; /* useful for debugging fscanf */
+ /* We provide our own buffer here since some STDIO libraries
+ barf on unbuffered input with fscanf() */
+
+ setbuf(sfp, buf);
+ if ((val = fscanf(sfp,"%d",&shmid)) != 1) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ if (shmid < 0) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ (void) fclose(sfp);
+ }
+ /*
+ * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and
+ * attach the same segment twice so we need this check.
+ */
+ if (!krb_shm_addr) {
+ if ((krb_shm_addr = shmat(shmid,0,0)) == -1){
+ if (krb_debug)
+ fprintf(stderr,
+ "cannot attach shared memory for segment %d\n",
+ shmid);
+ krb_shm_addr = 0; /* reset so we catch further errors */
+ return TKT_FIL_ACC;
+ }
+ }
+ tmp_shm_addr = krb_shm_addr;
+#endif /* TKT_SHMEM */
+
+ if (wflag) {
+ fd = open(tf_name, O_RDWR, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+ }
+ /*
+ * Otherwise "wflag" is not set and the ticket file should be opened
+ * for read-only operations and locked for shared access.
+ */
+
+ fd = open(tf_name, O_RDONLY, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pname() reads the principal's name from the ticket file. It
+ * should only be called after tf_init() has been called. The
+ * principal's name is filled into the "p" parameter. If all goes well,
+ * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is
+ * returned. If the name was null, or EOF was encountered, or the name
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+ */
+
+tf_get_pname(p)
+ char *p;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pname called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pinst() reads the principal's instance from a ticket file.
+ * It should only be called after tf_init() and tf_get_pname() have been
+ * called. The instance is filled into the "inst" parameter. If all
+ * goes well, KSUCCESS is returned. If tf_init() wasn't called,
+ * TKT_FIL_INI is returned. If EOF was encountered, or the instance
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the
+ * instance may be null.
+ */
+
+tf_get_pinst(inst)
+ char *inst;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pinst called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(inst, INST_SZ) < 1)
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills
+ * in the given structure "c". It should only be called after tf_init(),
+ * tf_get_pname(), and tf_get_pinst() have been called. If all goes well,
+ * KSUCCESS is returned. Possible error codes are:
+ *
+ * TKT_FIL_INI - tf_init wasn't called first
+ * TKT_FIL_FMT - bad format
+ * EOF - end of file encountered
+ */
+
+tf_get_cred(c)
+ CREDENTIALS *c;
+{
+ KTEXT ticket = &c->ticket_st; /* pointer to ticket */
+ int k_errno;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
+ switch (k_errno) {
+ case TOO_BIG:
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if (
+ tf_read((char *) (c->session), KEY_SZ) < 1 ||
+ tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
+ tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 ||
+ tf_read((char *) &(ticket->length), sizeof(ticket->length))
+ < 1 ||
+ /* don't try to read a silly amount into ticket->dat */
+ ticket->length > MAX_KTXT_LEN ||
+ tf_read((char *) (ticket->dat), ticket->length) < 1 ||
+ tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
+ ) {
+ tf_close();
+ return TKT_FIL_FMT;
+ }
+#ifdef TKT_SHMEM
+ bcopy(tmp_shm_addr,c->session,KEY_SZ);
+ tmp_shm_addr += KEY_SZ;
+#endif /* TKT_SHMEM */
+ return KSUCCESS;
+}
+
+/*
+ * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is
+ * not a valid file descriptor, it just returns. It also clears the
+ * buffer used to read tickets.
+ *
+ * The return value is not defined.
+ */
+
+tf_close()
+{
+ if (!(fd < 0)) {
+#ifdef TKT_SHMEM
+ if (shmdt(krb_shm_addr)) {
+ /* what kind of error? */
+ if (krb_debug)
+ fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno);
+ } else {
+ krb_shm_addr = 0;
+ }
+#endif TKT_SHMEM
+ (void) flock(fd, LOCK_UN);
+ (void) close(fd);
+ fd = -1; /* see declaration of fd above */
+ }
+ bzero(tfbfr, sizeof(tfbfr));
+}
+
+/*
+ * tf_gets() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until either it has read "n" characters,
+ * or until it reads a null byte. When finished, what has been read exists
+ * in "s". If it encounters EOF or an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read (including null terminator)
+ * when all goes well
+ *
+ * 0 end of file or read error
+ *
+ * TOO_BIG if "count" characters are read and no null is
+ * encountered. This is an indication that the ticket
+ * file is seriously ill.
+ */
+
+static
+tf_gets(s, n)
+ register char *s;
+{
+ register count;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_gets called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ for (count = n - 1; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s = tfbfr[curpos++];
+ if (*s++ == '\0')
+ return (n - count);
+ }
+ tf_close();
+ return TOO_BIG;
+}
+
+/*
+ * tf_read() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until "n" bytes have been read. When
+ * finished, what has been read exists in "s". If it encounters EOF or
+ * an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read when all goes well
+ *
+ * 0 on end of file or read error
+ */
+
+static
+tf_read(s, n)
+ register char *s;
+ register n;
+{
+ register count;
+
+ for (count = n; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s++ = tfbfr[curpos++];
+ }
+ return n;
+}
+
+char *tkt_string();
+
+/*
+ * tf_save_cred() appends an incoming ticket to the end of the ticket
+ * file. You must call tf_init() before calling tf_save_cred().
+ *
+ * The "service", "instance", and "realm" arguments specify the
+ * server's name; "session" contains the session key to be used with
+ * the ticket; "kvno" is the server key version number in which the
+ * ticket is encrypted, "ticket" contains the actual ticket, and
+ * "issue_date" is the time the ticket was requested (local host's time).
+ *
+ * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't
+ * called previously, and KFAILURE for anything else that went wrong.
+ */
+
+tf_save_cred(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+
+ off_t lseek();
+ int count; /* count for write */
+#ifdef TKT_SHMEM
+ int *skey_check;
+#endif /* TKT_SHMEM */
+
+ if (fd < 0) { /* fd is ticket file as set by tf_init */
+ if (krb_debug)
+ fprintf(stderr, "tf_save_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ /* Find the end of the ticket file */
+ (void) lseek(fd, 0L, 2);
+#ifdef TKT_SHMEM
+ /* scan to end of existing keys: pick first 'empty' slot.
+ we assume that no real keys will be completely zero (it's a weak
+ key under DES) */
+
+ skey_check = (int *) krb_shm_addr;
+
+ while (*skey_check && *(skey_check+1))
+ skey_check += 2;
+ tmp_shm_addr = (char *)skey_check;
+#endif /* TKT_SHMEM */
+
+ /* Write the ticket and associated data */
+ /* Service */
+ count = strlen(service) + 1;
+ if (write(fd, service, count) != count)
+ goto bad;
+ /* Instance */
+ count = strlen(instance) + 1;
+ if (write(fd, instance, count) != count)
+ goto bad;
+ /* Realm */
+ count = strlen(realm) + 1;
+ if (write(fd, realm, count) != count)
+ goto bad;
+ /* Session key */
+#ifdef TKT_SHMEM
+ bcopy(session,tmp_shm_addr,8);
+ tmp_shm_addr+=8;
+ if (write(fd,krb_dummy_skey,8) != 8)
+ goto bad;
+#else /* ! TKT_SHMEM */
+ if (write(fd, (char *) session, 8) != 8)
+ goto bad;
+#endif /* TKT_SHMEM */
+ /* Lifetime */
+ if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Key vno */
+ if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Tkt length */
+ if (write(fd, (char *) &(ticket->length), sizeof(int)) !=
+ sizeof(int))
+ goto bad;
+ /* Ticket */
+ count = ticket->length;
+ if (write(fd, (char *) (ticket->dat), count) != count)
+ goto bad;
+ /* Issue date */
+ if (write(fd, (char *) &issue_date, sizeof(long))
+ != sizeof(long))
+ goto bad;
+
+ /* Actually, we should check each write for success */
+ return (KSUCCESS);
+bad:
+ return (KFAILURE);
+}
diff --git a/eBones/krb/tkt_string.c b/eBones/krb/tkt_string.c
new file mode 100644
index 0000000..ba22db8
--- /dev/null
+++ b/eBones/krb/tkt_string.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $
+ * $Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <krb.h>
+#include <string.h>
+#include <sys/param.h>
+
+char *getenv();
+
+/*
+ * This routine is used to generate the name of the file that holds
+ * the user's cache of server tickets and associated session keys.
+ *
+ * If it is set, krb_ticket_string contains the ticket file name.
+ * Otherwise, the filename is constructed as follows:
+ *
+ * If it is set, the environment variable "KRBTKFILE" will be used as
+ * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and
+ * the user's uid are concatenated to produce the ticket file name
+ * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket
+ * file name is returned.
+ */
+
+static char krb_ticket_string[MAXPATHLEN] = "";
+
+char *tkt_string()
+{
+ char *env;
+ uid_t getuid();
+
+ if (!*krb_ticket_string) {
+ if (env = getenv("KRBTKFILE")) {
+ (void) strncpy(krb_ticket_string, env,
+ sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+ } else {
+ /* 32 bits of signed integer will always fit in 11 characters
+ (including the sign), so no need to worry about overflow */
+ (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,getuid());
+ }
+ }
+ return krb_ticket_string;
+}
+
+/*
+ * This routine is used to set the name of the file that holds the user's
+ * cache of server tickets and associated session keys.
+ *
+ * The value passed in is copied into local storage.
+ *
+ * NOTE: This routine should be called during initialization, before other
+ * Kerberos routines are called; otherwise tkt_string() above may be called
+ * and return an undesired ticket file name until this routine is called.
+ */
+
+void
+krb_set_tkt_string(val)
+char *val;
+{
+
+ (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+
+ return;
+}
diff --git a/eBones/krb/util.c b/eBones/krb/util.c
new file mode 100644
index 0000000..8e48557
--- /dev/null
+++ b/eBones/krb/util.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Miscellaneous debug printing utilities
+ *
+ * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $
+ * $Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <des.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Print some of the contents of the given authenticator structure
+ * (AUTH_DAT defined in "krb.h"). Fields printed are:
+ *
+ * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session
+ */
+
+ad_print(x)
+AUTH_DAT *x;
+{
+ struct in_addr in;
+
+ /* Print the contents of an auth_dat struct. */
+ in.s_addr = x->address;
+ printf("\n%s %s %s %s flags %u cksum 0x%X\n\ttkt_tm 0x%X sess_key",
+ x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags,
+ x->checksum, x->time_sec);
+
+ printf("[8] =");
+#ifdef NOENCRYPTION
+ placebo_cblock_print(x->session);
+#else
+ des_cblock_print_file(x->session,stdout);
+#endif
+ /* skip reply for now */
+}
+
+/*
+ * Print in hex the 8 bytes of the given session key.
+ *
+ * Printed format is: " 0x { x, x, x, x, x, x, x, x }"
+ */
+
+#ifdef NOENCRYPTION
+placebo_cblock_print(x)
+ des_cblock x;
+{
+ unsigned char *y = (unsigned char *) x;
+ register int i = 0;
+
+ printf(" 0x { ");
+
+ while (i++ <8) {
+ printf("%x",*y++);
+ if (i<8) printf(", ");
+ }
+ printf(" }");
+}
+#endif
diff --git a/eBones/ksrvtgt/Makefile b/eBones/ksrvtgt/Makefile
new file mode 100644
index 0000000..5e8944d
--- /dev/null
+++ b/eBones/ksrvtgt/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:26:54 g89r4222 Exp $
+
+PROG= ksrvtgt
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/ksrvtgt/ksrvtgt.1 b/eBones/ksrvtgt/ksrvtgt.1
new file mode 100644
index 0000000..25fd939
--- /dev/null
+++ b/eBones/ksrvtgt/ksrvtgt.1
@@ -0,0 +1,51 @@
+.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $
+.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a
+service key
+.SH SYNOPSIS
+.B ksrvtgt
+name instance [[realm] srvtab]
+.SH DESCRIPTION
+.I ksrvtgt
+retrieves a ticket-granting ticket with a lifetime of five (5) minutes
+for the principal
+.I name.instance@realm
+(or
+.I name.instance@localrealm
+if
+.I realm
+is not supplied on the command line), decrypts the response using
+the service key found in
+.I srvtab
+(or in
+.B /etc/srvtab
+if
+.I srvtab
+is not specified on the command line), and stores the ticket in the
+standard ticket cache.
+.PP
+This command is intended primarily for use in shell scripts and other
+batch-type facilities.
+.SH DIAGNOSTICS
+"Generic kerberos failure (kfailure)" can indicate a whole range of
+problems, the most common of which is the inability to read the service
+key file.
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm.
+.TP
+/tmp/tkt[uid]
+The default ticket file.
+.TP
+/etc/srvtab
+The default service key file.
+.SH SEE ALSO
+kerberos(1), kinit(1), kdestroy(1)
diff --git a/eBones/ksrvtgt/ksrvtgt.c b/eBones/ksrvtgt/ksrvtgt.c
new file mode 100644
index 0000000..46bbd56
--- /dev/null
+++ b/eBones/ksrvtgt/ksrvtgt.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Get a ticket-granting-ticket given a service key file (srvtab)
+ * The lifetime is the shortest allowed [1 five-minute interval]
+ *
+ * from: ksrvtgt.c,v 4.3 89/07/28 10:17:28 jtkohl Exp $
+ * $Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+const char rcsid[] =
+"$Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <krb.h>
+#include <conf.h>
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char realm[REALM_SZ + 1];
+ register int code;
+ char srvtab[MAXPATHLEN + 1];
+
+ bzero(realm, sizeof(realm));
+ bzero(srvtab, sizeof(srvtab));
+
+ if (argc < 3 || argc > 5) {
+ fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ if (argc == 4)
+ (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1);
+
+ if (argc == 5) {
+ (void) strncpy(realm, argv[3], sizeof(realm) - 1);
+ (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1);
+ }
+
+ if (srvtab[0] == 0)
+ (void) strcpy(srvtab, KEYFILE);
+
+ if (realm[0] == 0)
+ if (krb_get_lrealm(realm) != KSUCCESS)
+ (void) strcpy(realm, KRB_REALM);
+
+ code = krb_get_svc_in_tkt(argv[1], argv[2], realm,
+ "krbtgt", realm, 1, srvtab);
+ if (code)
+ fprintf(stderr, "%s\n", krb_err_txt[code]);
+ exit(code);
+}
diff --git a/eBones/ksrvutil/ksrvutil.8 b/eBones/ksrvutil/ksrvutil.8
new file mode 100644
index 0000000..a7fed82
--- /dev/null
+++ b/eBones/ksrvutil/ksrvutil.8
@@ -0,0 +1,93 @@
+.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $
+.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvutil \- host kerberos keyfile (srvtab) manipulation utility
+.SH SYNOPSIS
+ksrvutil
+.B operation
+[
+.B \-k
+] [
+.B \-i
+] [
+.B \-f filename
+]
+.SH DESCRIPTION
+.I ksrvutil
+allows a system manager to list or change keys currently in his
+keyfile or to add new keys to the keyfile.
+.PP
+
+Operation must be one of the following:
+.TP 10n
+.I list
+lists the keys in a keyfile showing version number and principal
+name. If the \-k option is given, keys will also be shown.
+.TP 10n
+.I change
+changes all the keys in the keyfile by using the regular admin
+protocol. If the \-i flag is given,
+.I ksrvutil
+will prompt for yes or no before changing each key. If the \-k
+option is used, the old and new keys will be displayed.
+.TP 10n
+.I add
+allows the user to add a key.
+.I add
+prompts for name, instance, realm, and key version number, asks
+for confirmation, and then asks for a password.
+.I ksrvutil
+then converts the password to a key and appends the keyfile with
+the new information. If the \-k option is used, the key is
+displayed.
+
+.PP
+In all cases, the default file used is KEY_FILE as defined in
+krb.h unless this is overridden by the \-f option.
+
+.PP
+A good use for
+.I ksrvutil
+would be for adding keys to a keyfile. A system manager could
+ask a kerberos administrator to create a new service key with
+.IR kadmin (8)
+and could supply an initial password. Then, he could use
+.I ksrvutil
+to add the key to the keyfile and then to change the key so that
+it will be random and unknown to either the system manager or
+the kerberos administrator.
+
+.I ksrvutil
+always makes a backup copy of the keyfile before making any
+changes.
+
+.SH DIAGNOSTICS
+If
+.I ksrvutil
+should exit on an error condition at any time during a change or
+add, a copy of the
+original keyfile can be found in
+.IR filename .old
+where
+.I filename
+is the name of the keyfile, and a copy of the file with all new
+keys changed or added so far can be found in
+.IR filename .work.
+The original keyfile is left unmodified until the program exits
+at which point it is removed and replaced it with the workfile.
+Appending the workfile to the backup copy and replacing the
+keyfile with the result should always give a usable keyfile,
+although the resulting keyfile will have some out of date keys
+in it.
+
+.SH SEE ALSO
+kadmin(8), ksrvtgt(1)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/kstash/Makefile b/eBones/kstash/Makefile
new file mode 100644
index 0000000..8331c97a
--- /dev/null
+++ b/eBones/kstash/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.2 (Berkeley) 3/5/91
+# $Id: Makefile,v 1.2 1994/07/19 19:27:04 g89r4222 Exp $
+
+PROG= kstash
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kstash/kstash.8 b/eBones/kstash/kstash.8
new file mode 100644
index 0000000..d83379a
--- /dev/null
+++ b/eBones/kstash/kstash.8
@@ -0,0 +1,41 @@
+.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $
+.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kstash \- stash Kerberos key distribution center database master key
+.SH SYNOPSIS
+kstash
+.SH DESCRIPTION
+.I kstash
+saves the Kerberos key distribution center (KDC) database master key in
+the master key cache file.
+.PP
+The user is prompted to enter the key, to verify the authenticity of the
+key and the authorization to store the key in the file.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.TP
+"kstash: Unable to open master key file"
+The attempt to open the cache file for writing failed (probably due to a
+system or access permission error).
+.TP
+"kstash: Write I/O error on master key file"
+The
+.BR write (2)
+system call returned an error while
+.I kstash
+was attempting to write the key to the file.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/kstash/kstash.c b/eBones/kstash/kstash.c
new file mode 100644
index 0000000..696e4e1
--- /dev/null
+++ b/eBones/kstash/kstash.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $
+ * $Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+extern int errno;
+
+/* change this later, but krblib_dbm needs it for now */
+char *progname;
+
+static C_Block master_key;
+static Key_schedule master_key_schedule;
+static Principal s_name_data; /* for services requested */
+static unsigned char master_key_version;
+int debug;
+static int more;
+static int kfile;
+static void clear_secrets();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ long n;
+ if (n = kerb_init()) {
+ fprintf(stderr, "Kerberos db and cache init failed = %d\n", n);
+ exit(1);
+ }
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]);
+ fflush (stderr);
+ clear_secrets();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets();
+ exit (-1);
+ }
+
+ kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600);
+ if (kfile < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n\07\07%s: Unable to open master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ if (write(kfile, (char *) master_key, 8) < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n%s: Write I/O error on master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ (void) close(kfile);
+ clear_secrets();
+}
+
+static void
+clear_secrets()
+{
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(master_key, sizeof(master_key));
+}
diff --git a/eBones/lib/libacl/Makefile b/eBones/lib/libacl/Makefile
new file mode 100644
index 0000000..77c9a01
--- /dev/null
+++ b/eBones/lib/libacl/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.3 1994/09/09 21:43:17 g89r4222 Exp $
+
+LIB= acl
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-DDEBUG -DKERBEROS -I${.CURDIR}/../include
+SRCS= acl_files.c
+
+.include <bsd.lib.mk>
diff --git a/eBones/lib/libacl/acl_check.3 b/eBones/lib/libacl/acl_check.3
new file mode 100644
index 0000000..c142506
--- /dev/null
+++ b/eBones/lib/libacl/acl_check.3
@@ -0,0 +1,183 @@
+.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $
+.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+acl_canonicalize_principal, acl_check, acl_exact_match, acl_add,
+acl_delete, acl_initialize \- Access control list routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+cc <files> \-lacl \-lkrb
+.PP
+.ft B
+#include <krb.h>
+.PP
+.ft B
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf;
+.PP
+.ft B
+acl_check(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_add(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_initialize(acl_file, mode)
+char *acl_file;
+int mode;
+.fi
+.ft R
+.SH DESCRIPTION
+.SS Introduction
+.PP
+An access control list (ACL) is a list of principals, where each
+principal is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+.PP
+.SS Principal Names
+.PP
+Principal names have the form
+.nf
+.in +5n
+<name>[.<instance>][@<realm>]
+.in -5n
+e.g.:
+.in +5n
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+.in -5n
+.fi
+It is possible for principals to be underspecified. If an instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be the local realm as determined by
+.IR krb_get_lrealm (3).
+The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+.SS Routines
+.PP
+.I acl_canonicalize_principal
+stores the canonical form of
+.I principal
+in
+.IR buf .
+.I Buf
+must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ,
+respectively, in
+.IR /usr/include/krb.h .
+.PP
+.I acl_check
+returns nonzero if
+.I principal
+appears in
+.IR acl .
+Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards. The
+only supported wildcards are entries of the form
+name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the
+its component field. For example, "jtkohl.*@*" would match principal
+jtkohl, with any instance and any realm.
+.PP
+.I acl_exact_match
+performs like
+.IR acl_check ,
+but does no canonicalization or wildcard matching.
+.PP
+.I acl_add
+atomically adds
+.I principal
+to
+.IR acl .
+Returns 0 if successful, nonzero otherwise. It is considered a failure
+if
+.I principal
+is already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_delete
+atomically deletes
+.I principal
+from
+.IR acl .
+Returns 0 if successful,
+nonzero otherwise. It is considered a failure if
+.I principal
+is not
+already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_initialize
+initializes
+.IR acl_file .
+If the file
+.I acl_file
+does not exist,
+.I acl_initialize
+creates it with mode
+.IR mode .
+If the file
+.I acl_file
+exists,
+.I acl_initialize
+removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+.SH NOTES
+In the presence of concurrency, there is a very small chance that
+.I acl_add
+or
+.I acl_delete
+could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+.PP
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
+.SH SEE ALSO
+kerberos(3), krb_get_lrealm(3)
+.SH AUTHOR
+James Aspnes (MIT Project Athena)
diff --git a/eBones/lib/libacl/acl_files.c b/eBones/lib/libacl/acl_files.c
new file mode 100644
index 0000000..6f7f3fd
--- /dev/null
+++ b/eBones/lib/libacl/acl_files.c
@@ -0,0 +1,541 @@
+/*
+ *
+ * Copyright 1987,1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $
+ * $Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: acl_files.c,v 1.2 1994/07/19 19:21:18 g89r4222 Exp $";
+#endif lint
+
+
+/*** Routines for manipulating access control list files ***/
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <ctype.h>
+#include "krb.h"
+
+__BEGIN_DECLS
+static int acl_abort __P((char *, FILE *));
+__END_DECLS
+
+#ifndef KRB_REALM
+#define KRB_REALM "ATHENA.MIT.EDU"
+#endif
+
+/* "aname.inst@realm" */
+#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3)
+#define INST_SEP '.'
+#define REALM_SEP '@'
+
+#define LINESIZE 2048 /* Maximum line length in an acl file */
+
+#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
+#define WAIT_TIME 300 /* Maximum time allowed write acl file */
+
+#define CACHED_ACLS 8 /* How many acls to cache */
+ /* Each acl costs 1 open file descriptor */
+#define ACL_LEN 16 /* Twice a reasonable acl length */
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#define COR(a,b) ((a!=NULL)?(a):(b))
+
+extern int errno;
+
+extern char *malloc(), *calloc();
+extern time_t time();
+
+/* Canonicalize a principal name */
+/* If instance is missing, it becomes "" */
+/* If realm is missing, it becomes the local realm */
+/* Canonicalized form is put in canon, which must be big enough to hold
+ MAX_PRINCIPAL_SIZE characters */
+acl_canonicalize_principal(principal, canon)
+char *principal;
+char *canon;
+{
+ char *dot, *atsign, *end;
+ int len;
+
+ dot = index(principal, INST_SEP);
+ atsign = index(principal, REALM_SEP);
+
+ /* Maybe we're done already */
+ if(dot != NULL && atsign != NULL) {
+ if(dot < atsign) {
+ /* It's for real */
+ /* Copy into canon */
+ strncpy(canon, principal, MAX_PRINCIPAL_SIZE);
+ canon[MAX_PRINCIPAL_SIZE-1] = '\0';
+ return;
+ } else {
+ /* Nope, it's part of the realm */
+ dot = NULL;
+ }
+ }
+
+ /* No such luck */
+ end = principal + strlen(principal);
+
+ /* Get the principal name */
+ len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal);
+ strncpy(canon, principal, len);
+ canon += len;
+
+ /* Add INST_SEP */
+ *canon++ = INST_SEP;
+
+ /* Get the instance, if it exists */
+ if(dot != NULL) {
+ ++dot;
+ len = MIN(INST_SZ, COR(atsign, end) - dot);
+ strncpy(canon, dot, len);
+ canon += len;
+ }
+
+ /* Add REALM_SEP */
+ *canon++ = REALM_SEP;
+
+ /* Get the realm, if it exists */
+ /* Otherwise, default to local realm */
+ if(atsign != NULL) {
+ ++atsign;
+ len = MIN(REALM_SZ, end - atsign);
+ strncpy(canon, atsign, len);
+ canon += len;
+ *canon++ = '\0';
+ } else if(krb_get_lrealm(canon, 1) != KSUCCESS) {
+ strcpy(canon, KRB_REALM);
+ }
+}
+
+/* Get a lock to modify acl_file */
+/* Return new FILE pointer */
+/* or NULL if file cannot be modified */
+/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
+static FILE *acl_lock_file(acl_file)
+char *acl_file;
+{
+ struct stat s;
+ char new[LINESIZE];
+ int nfd;
+ FILE *nf;
+ int mode;
+
+ if(stat(acl_file, &s) < 0) return(NULL);
+ mode = s.st_mode;
+ sprintf(new, NEW_FILE, acl_file);
+ for(;;) {
+ /* Open the new file */
+ if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
+ if(errno == EEXIST) {
+ /* Maybe somebody got here already, maybe it's just old */
+ if(stat(new, &s) < 0) return(NULL);
+ if(time(0) - s.st_ctime > WAIT_TIME) {
+ /* File is stale, kill it */
+ unlink(new);
+ continue;
+ } else {
+ /* Wait and try again */
+ sleep(1);
+ continue;
+ }
+ } else {
+ /* Some other error, we lose */
+ return(NULL);
+ }
+ }
+
+ /* If we got to here, the lock file is ours and ok */
+ /* Reopen it under stdio */
+ if((nf = fdopen(nfd, "w")) == NULL) {
+ /* Oops, clean up */
+ unlink(new);
+ }
+ return(nf);
+ }
+}
+
+/* Commit changes to acl_file written onto FILE *f */
+/* Returns zero if successful */
+/* Returns > 0 if lock was broken */
+/* Returns < 0 if some other error occurs */
+/* Closes f */
+static int acl_commit(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ sprintf(new, NEW_FILE, acl_file);
+ if(fflush(f) < 0
+ || fstat(fileno(f), &s) < 0
+ || s.st_nlink == 0) {
+ acl_abort(acl_file, f);
+ return(-1);
+ }
+
+ ret = rename(new, acl_file);
+ fclose(f);
+ return(ret);
+}
+
+/*
+ * Abort changes to acl_file written onto FILE *f
+ * Returns 0 if successful, < 0 otherwise
+ * Closes f
+ */
+static int
+acl_abort(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ /* make sure we aren't nuking someone else's file */
+ if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) {
+ fclose(f);
+ return(-1);
+ } else {
+ sprintf(new, NEW_FILE, acl_file);
+ ret = unlink(new);
+ fclose(f);
+ return(ret);
+ }
+}
+
+/* Initialize an acl_file */
+/* Creates the file with permissions perm if it does not exist */
+/* Erases it if it does */
+/* Returns return value of acl_commit */
+int acl_initialize(acl_file, perm)
+char *acl_file;
+int perm;
+{
+ FILE *new;
+ int fd;
+
+ /* Check if the file exists already */
+ if((new = acl_lock_file(acl_file)) != NULL) {
+ return(acl_commit(acl_file, new));
+ } else {
+ /* File must be readable and writable by owner */
+ if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
+ return(-1);
+ } else {
+ close(fd);
+ return(0);
+ }
+ }
+}
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static nuke_whitespace(buf)
+char *buf;
+{
+ register char *pin, *pout;
+
+ for(pin = pout = buf; *pin != '\0'; pin++)
+ if(!isspace(*pin)) *pout++ = *pin;
+ *pout = '\0'; /* Terminate the string */
+}
+
+/* Hash table stuff */
+
+struct hashtbl {
+ int size; /* Max number of entries */
+ int entries; /* Actual number of entries */
+ char **tbl; /* Pointer to start of table */
+};
+
+/* Make an empty hash table of size s */
+static struct hashtbl *make_hash(size)
+int size;
+{
+ struct hashtbl *h;
+
+ if(size < 1) size = 1;
+ h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
+ h->size = size;
+ h->entries = 0;
+ h->tbl = (char **) calloc(size, sizeof(char *));
+ return(h);
+}
+
+/* Destroy a hash table */
+static destroy_hash(h)
+struct hashtbl *h;
+{
+ int i;
+
+ for(i = 0; i < h->size; i++) {
+ if(h->tbl[i] != NULL) free(h->tbl[i]);
+ }
+ free(h->tbl);
+ free(h);
+}
+
+/* Compute hash value for a string */
+static unsigned hashval(s)
+register char *s;
+{
+ register unsigned hv;
+
+ for(hv = 0; *s != '\0'; s++) {
+ hv ^= ((hv << 3) ^ *s);
+ }
+ return(hv);
+}
+
+/* Add an element to a hash table */
+static add_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+ char *s;
+ char **old;
+ int i;
+
+ /* Make space if it isn't there already */
+ if(h->entries + 1 > (h->size >> 1)) {
+ old = h->tbl;
+ h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
+ for(i = 0; i < h->size; i++) {
+ if(old[i] != NULL) {
+ hv = hashval(old[i]) % (h->size << 1);
+ while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
+ h->tbl[hv] = old[i];
+ }
+ }
+ h->size = h->size << 1;
+ free(old);
+ }
+
+ hv = hashval(el) % h->size;
+ while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
+ s = malloc(strlen(el)+1);
+ strcpy(s, el);
+ h->tbl[hv] = s;
+ h->entries++;
+}
+
+/* Returns nonzero if el is in h */
+static check_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+
+ for(hv = hashval(el) % h->size;
+ h->tbl[hv] != NULL;
+ hv = (hv + 1) % h->size) {
+ if(!strcmp(h->tbl[hv], el)) return(1);
+ }
+ return(0);
+}
+
+struct acl {
+ char filename[LINESIZE]; /* Name of acl file */
+ int fd; /* File descriptor for acl file */
+ struct stat status; /* File status at last read */
+ struct hashtbl *acl; /* Acl entries */
+};
+
+static struct acl acl_cache[CACHED_ACLS];
+
+static int acl_cache_count = 0;
+static int acl_cache_next = 0;
+
+/* Returns < 0 if unsuccessful in loading acl */
+/* Returns index into acl_cache otherwise */
+/* Note that if acl is already loaded, this is just a lookup */
+static int acl_load(name)
+char *name;
+{
+ int i;
+ FILE *f;
+ struct stat s;
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ /* See if it's there already */
+ for(i = 0; i < acl_cache_count; i++) {
+ if(!strcmp(acl_cache[i].filename, name)
+ && acl_cache[i].fd >= 0) goto got_it;
+ }
+
+ /* It isn't, load it in */
+ /* maybe there's still room */
+ if(acl_cache_count < CACHED_ACLS) {
+ i = acl_cache_count++;
+ } else {
+ /* No room, clean one out */
+ i = acl_cache_next;
+ acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
+ close(acl_cache[i].fd);
+ if(acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
+ }
+
+ /* Set up the acl */
+ strcpy(acl_cache[i].filename, name);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ /* Force reload */
+ acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+ /*
+ * See if the stat matches
+ *
+ * Use stat(), not fstat(), as the file may have been re-created by
+ * acl_add or acl_delete. If this happens, the old inode will have
+ * no changes in the mod-time and the following test will fail.
+ */
+ if(stat(acl_cache[i].filename, &s) < 0) return(-1);
+ if(acl_cache[i].acl == (struct hashtbl *) 0
+ || s.st_nlink != acl_cache[i].status.st_nlink
+ || s.st_mtime != acl_cache[i].status.st_mtime
+ || s.st_ctime != acl_cache[i].status.st_ctime) {
+ /* Gotta reload */
+ if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
+ if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = make_hash(ACL_LEN);
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ nuke_whitespace(buf);
+ acl_canonicalize_principal(buf, canon);
+ add_hash(acl_cache[i].acl, canon);
+ }
+ fclose(f);
+ acl_cache[i].status = s;
+ }
+ return(i);
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+
+ return((idx = acl_load(acl)) >= 0
+ && check_hash(acl_cache[idx].acl, principal));
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Recognizes wildcards in acl of the form
+ name.*@realm, *.*@realm, and *.*@* */
+acl_check(acl, principal)
+char *acl;
+char *principal;
+{
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+ char *realm;
+
+ acl_canonicalize_principal(principal, canon);
+
+ /* Is it there? */
+ if(acl_exact_match(acl, canon)) return(1);
+
+ /* Try the wildcards */
+ realm = index(canon, REALM_SEP);
+ *index(canon, INST_SEP) = '\0'; /* Chuck the instance */
+
+ sprintf(buf, "%s.*%s", canon, realm);
+ if(acl_exact_match(acl, buf)) return(1);
+
+ sprintf(buf, "*.*%s", realm);
+ if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
+
+ return(0);
+}
+
+/* Adds principal to acl */
+/* Wildcards are interpreted literally */
+acl_add(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL) {
+ if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL
+ || putc('\n', new) != '\n') {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ }
+ }
+ fputs(canon, new);
+ putc('\n', new);
+ return(acl_commit(acl, new));
+}
+
+/* Removes principal from acl */
+/* Wildcards are interpreted literally */
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((!acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL
+ && strcmp(acl_cache[idx].acl->tbl[i], canon)) {
+ fputs(acl_cache[idx].acl->tbl[i], new);
+ putc('\n', new);
+ }
+ }
+ return(acl_commit(acl, new));
+}
+
diff --git a/eBones/lib/libacl/acl_files.doc b/eBones/lib/libacl/acl_files.doc
new file mode 100644
index 0000000..78c448a
--- /dev/null
+++ b/eBones/lib/libacl/acl_files.doc
@@ -0,0 +1,107 @@
+PROTOTYPE ACL LIBRARY
+
+Introduction
+
+An access control list (ACL) is a list of principals, where each
+principal is is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+
+
+Usage
+
+cc <files> -lacl -lkrb.
+
+
+
+Principal Names
+
+Principal names have the form
+
+<name>[.<instance>][@<realm>]
+
+e.g.
+
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+
+It is possible for principals to be underspecified. If instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be local_realm. The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+
+
+Routines
+
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf; /*RETVAL*/
+
+Store the canonical form of principal in buf. Buf must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified in /usr/include/krb.h.
+
+acl_check(acl, principal)
+char *acl;
+char *principal;
+
+Returns nonzero if principal appears in acl. Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards.
+
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+
+Like acl_check, but does no canonicalization or wildcarding.
+
+acl_add(acl, principal)
+char *acl;
+char *principal;
+
+Atomically adds principal to acl. Returns 0 if successful, nonzero
+otherwise. It is considered a failure if principal is already in acl.
+This routine will canonicalize principal, but will treat wildcards
+literally.
+
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+
+Atomically deletes principal from acl. Returns 0 if successful,
+nonzero otherwise. It is consider a failure if principal is not
+already in acl. This routine will canonicalize principal, but will
+treat wildcards literally.
+
+acl_initialize(acl, mode)
+char *acl;
+int mode;
+
+Initialize acl. If acl file does not exist, creates it with mode
+mode. If acl exists, removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+
+
+Known problems
+
+In the presence of concurrency, there is a very small chance that
+acl_add or acl_delete could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
diff --git a/eBones/lib/libkdb/Makefile b/eBones/lib/libkdb/Makefile
new file mode 100644
index 0000000..b69c0d9
--- /dev/null
+++ b/eBones/lib/libkdb/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.3 1994/09/09 21:43:41 g89r4222 Exp $
+
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+
+LIB= kdb
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c
+
+.include <bsd.lib.mk>
diff --git a/eBones/lib/libkdb/krb_cache.c b/eBones/lib/libkdb/krb_cache.c
new file mode 100644
index 0000000..4d8c594
--- /dev/null
+++ b/eBones/lib/libkdb/krb_cache.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This is where a cache would be implemented, if it were necessary.
+ *
+ * from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $
+ * $Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_cache.c,v 1.2 1994/07/19 19:23:35 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+extern char *strncpy();
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+#endif
+static init = 0;
+
+/*
+ * initialization routine for cache
+ */
+
+int
+kerb_cache_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * look up a principal in the cache returns number of principals found
+ */
+
+int
+kerb_cache_get_principal(serv, inst, principal, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+ u_long i;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "cache_get_principal for %s %s max = %d\n",
+ serv, inst, max);
+#endif DEBUG
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+ serv, inst, principal->name, principal->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv,
+ inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a principal in the cache returns number of principals
+ * inserted
+ */
+
+int
+kerb_cache_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* max number of principal structs to
+ * insert */
+
+{
+ int found = 0;
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_principal max = %d",
+ max);
+ }
+#endif
+
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ principal->name, principal->instance);
+#endif
+ /* DO IT */
+ count++;
+ principal++;
+ }
+ return count;
+}
+
+/*
+ * look up a dba in the cache returns number of dbas found
+ */
+
+int
+kerb_cache_get_dba(serv, inst, dba, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+ u_long i;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "cache_get_dba for %s %s max = %d\n",
+ serv, inst, max);
+#endif
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
+ serv, inst, dba->name, dba->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv, inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a dba in the cache returns number of dbas inserted
+ */
+
+int
+kerb_cache_put_dba(dba, max)
+ Dba *dba;
+ unsigned int max; /* max number of dba structs to insert */
+
+{
+ int found = 0;
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_dba max = %d", max);
+ }
+#endif
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ dba->name, dba->instance);
+#endif
+ /* DO IT */
+ count++;
+ dba++;
+ }
+ return count;
+}
+
diff --git a/eBones/lib/libkdb/krb_dbl.c b/eBones/lib/libkdb/krb_dbl.c
new file mode 100644
index 0000000..7776298
--- /dev/null
+++ b/eBones/lib/libkdb/krb_dbl.c
@@ -0,0 +1 @@
+This file is now obsolete.
diff --git a/eBones/lib/libkdb/krb_dbm.c b/eBones/lib/libkdb/krb_dbm.c
new file mode 100644
index 0000000..754dd68
--- /dev/null
+++ b/eBones/lib/libkdb/krb_dbm.c
@@ -0,0 +1,741 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $
+ * $Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_dbm.c,v 1.2 1994/07/19 19:23:36 g89r4222 Exp $";
+#endif lint
+
+#if defined(__FreeBSD__)
+#define NDBM
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/errno.h>
+#include <strings.h>
+#include <des.h>
+#include <sys/file.h>
+#ifdef NDBM
+#include <ndbm.h>
+#else /*NDBM*/
+#include <dbm.h>
+#endif /*NDBM*/
+/* before krb_db.h */
+#include <krb.h>
+#include <krb_db.h>
+
+#define KERB_DB_MAX_RETRY 5
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+extern char *progname;
+#endif
+extern char *malloc();
+extern int errno;
+
+static init = 0;
+static char default_db_name[] = DBM_FILE;
+static char *current_db_name = default_db_name;
+static void encode_princ_key(), decode_princ_key();
+static void encode_princ_contents(), decode_princ_contents();
+static void kerb_dbl_fini();
+static int kerb_dbl_lock();
+static void kerb_dbl_unlock();
+
+static struct timeval timestamp;/* current time of request */
+static int non_blocking = 0;
+
+/*
+ * This module contains all of the code which directly interfaces to
+ * the underlying representation of the Kerberos database; this
+ * implementation uses a DBM or NDBM indexed "file" (actually
+ * implemented as two separate files) to store the relations, plus a
+ * third file as a semaphore to allow the database to be replaced out
+ * from underneath the KDC server.
+ */
+
+/*
+ * Locking:
+ *
+ * There are two distinct locking protocols used. One is designed to
+ * lock against processes (the admin_server, for one) which make
+ * incremental changes to the database; the other is designed to lock
+ * against utilities (kdb_util, kpropd) which replace the entire
+ * database in one fell swoop.
+ *
+ * The first locking protocol is implemented using flock() in the
+ * krb_dbl_lock() and krb_dbl_unlock routines.
+ *
+ * The second locking protocol is necessary because DBM "files" are
+ * actually implemented as two separate files, and it is impossible to
+ * atomically rename two files simultaneously. It assumes that the
+ * database is replaced only very infrequently in comparison to the time
+ * needed to do a database read operation.
+ *
+ * A third file is used as a "version" semaphore; the modification
+ * time of this file is the "version number" of the database.
+ * At the start of a read operation, the reader checks the version
+ * number; at the end of the read operation, it checks again. If the
+ * version number changed, or if the semaphore was nonexistant at
+ * either time, the reader sleeps for a second to let things
+ * stabilize, and then tries again; if it does not succeed after
+ * KERB_DB_MAX_RETRY attempts, it gives up.
+ *
+ * On update, the semaphore file is deleted (if it exists) before any
+ * update takes place; at the end of the update, it is replaced, with
+ * a version number strictly greater than the version number which
+ * existed at the start of the update.
+ *
+ * If the system crashes in the middle of an update, the semaphore
+ * file is not automatically created on reboot; this is a feature, not
+ * a bug, since the database may be inconsistant. Note that the
+ * absence of a semaphore file does not prevent another _update_ from
+ * taking place later. Database replacements take place automatically
+ * only on slave servers; a crash in the middle of an update will be
+ * fixed by the next slave propagation. A crash in the middle of an
+ * update on the master would be somewhat more serious, but this would
+ * likely be noticed by an administrator, who could fix the problem and
+ * retry the operation.
+ */
+
+/* Macros to convert ndbm names to dbm names.
+ * Note that dbm_nextkey() cannot be simply converted using a macro, since
+ * it is invoked giving the database, and nextkey() needs the previous key.
+ *
+ * Instead, all routines call "dbm_next" instead.
+ */
+
+#ifndef NDBM
+typedef char DBM;
+
+#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0))
+#define dbm_fetch(db, key) fetch(key)
+#define dbm_store(db, key, content, flag) store(key, content)
+#define dbm_firstkey(db) firstkey()
+#define dbm_next(db,key) nextkey(key)
+#define dbm_close(db) dbmclose()
+#else
+#define dbm_next(db,key) dbm_nextkey(db)
+#endif
+
+/*
+ * Utility routine: generate name of database file.
+ */
+
+static char *gen_dbsuffix(db_name, sfx)
+ char *db_name;
+ char *sfx;
+{
+ char *dbsuffix;
+
+ if (sfx == NULL)
+ sfx = ".ok";
+
+ dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
+ strcpy(dbsuffix, db_name);
+ strcat(dbsuffix, sfx);
+ return dbsuffix;
+}
+
+/*
+ * initialization for data base routines.
+ */
+
+kerb_db_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * gracefully shut down database--must be called by ANY program that does
+ * a kerb_db_init
+ */
+
+kerb_db_fini()
+{
+}
+
+/*
+ * Set the "name" of the current database to some alternate value.
+ *
+ * Passing a null pointer as "name" will set back to the default.
+ * If the alternate database doesn't exist, nothing is changed.
+ */
+
+kerb_db_set_name(name)
+ char *name;
+{
+ DBM *db;
+
+ if (name == NULL)
+ name = default_db_name;
+ db = dbm_open(name, 0, 0);
+ if (db == NULL)
+ return errno;
+ dbm_close(db);
+ kerb_dbl_fini();
+ current_db_name = name;
+ return 0;
+}
+
+/*
+ * Return the last modification time of the database.
+ */
+
+long kerb_get_db_age()
+{
+ struct stat st;
+ char *okname;
+ long age;
+
+ okname = gen_dbsuffix(current_db_name, ".ok");
+
+ if (stat (okname, &st) < 0)
+ age = 0;
+ else
+ age = st.st_mtime;
+
+ free (okname);
+ return age;
+}
+
+/*
+ * Remove the semaphore file; indicates that database is currently
+ * under renovation.
+ *
+ * This is only for use when moving the database out from underneath
+ * the server (for example, during slave updates).
+ */
+
+static long kerb_start_update(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ long age = kerb_get_db_age();
+
+ if (unlink(okname) < 0
+ && errno != ENOENT) {
+ age = -1;
+ }
+ free (okname);
+ return age;
+}
+
+static long kerb_end_update(db_name, age)
+ char *db_name;
+ long age;
+{
+ int fd;
+ int retval = 0;
+ char *new_okname = gen_dbsuffix(db_name, ".ok#");
+ char *okname = gen_dbsuffix(db_name, ".ok");
+
+ fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ retval = errno;
+ else {
+ struct stat st;
+ struct timeval tv[2];
+ /* make sure that semaphore is "after" previous value. */
+ if (fstat (fd, &st) == 0
+ && st.st_mtime <= age) {
+ tv[0].tv_sec = st.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = age;
+ tv[1].tv_usec = 0;
+ /* set times.. */
+ utimes (new_okname, tv);
+ fsync(fd);
+ }
+ close(fd);
+ if (rename (new_okname, okname) < 0)
+ retval = errno;
+ }
+
+ free (new_okname);
+ free (okname);
+
+ return retval;
+}
+
+static long kerb_start_read()
+{
+ return kerb_get_db_age();
+}
+
+static long kerb_end_read(age)
+ u_long age;
+{
+ if (kerb_get_db_age() != age || age == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Create the database, assuming it's not there.
+ */
+
+kerb_db_create(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ int fd;
+ register int ret = 0;
+#ifdef NDBM
+ DBM *db;
+
+ db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (db == NULL)
+ ret = errno;
+ else
+ dbm_close(db);
+#else
+ char *dirname = gen_dbsuffix(db_name, ".dir");
+ char *pagname = gen_dbsuffix(db_name, ".pag");
+
+ fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else {
+ close(fd);
+ fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else
+ close(fd);
+ }
+ if (dbminit(db_name) < 0)
+ ret = errno;
+#endif
+ if (ret == 0) {
+ fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ ret = errno;
+ close(fd);
+ }
+ return ret;
+}
+
+/*
+ * "Atomically" rename the database in a way that locks out read
+ * access in the middle of the rename.
+ *
+ * Not perfect; if we crash in the middle of an update, we don't
+ * necessarily know to complete the transaction the rename, but...
+ */
+
+kerb_db_rename(from, to)
+ char *from;
+ char *to;
+{
+ char *fromdir = gen_dbsuffix (from, ".dir");
+ char *todir = gen_dbsuffix (to, ".dir");
+ char *frompag = gen_dbsuffix (from , ".pag");
+ char *topag = gen_dbsuffix (to, ".pag");
+ char *fromok = gen_dbsuffix(from, ".ok");
+ long trans = kerb_start_update(to);
+ int ok;
+
+ if ((rename (fromdir, todir) == 0)
+ && (rename (frompag, topag) == 0)) {
+ (void) unlink (fromok);
+ ok = 1;
+ }
+
+ free (fromok);
+ free (fromdir);
+ free (todir);
+ free (frompag);
+ free (topag);
+ if (ok)
+ return kerb_end_update(to, trans);
+ else
+ return -1;
+}
+
+/*
+ * look up a principal in the data base returns number of principals
+ * found , and whether there were more than requested.
+ */
+
+kerb_db_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ int found = 0, code;
+ extern int errorproc();
+ int wildp, wildi;
+ datum key, contents;
+ char testname[ANAME_SZ], testinst[INST_SZ];
+ u_long trans;
+ int try;
+ DBM *db;
+
+ if (!init)
+ kerb_db_init(); /* initialize database routines */
+
+ for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
+ trans = kerb_start_read();
+
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return -1;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ *more = 0;
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr,
+ "%s: db_get_principal for %s %s max = %d",
+ progname, name, inst, max);
+#endif
+
+ wildp = !strcmp(name, "*");
+ wildi = !strcmp(inst, "*");
+
+ if (!wildi && !wildp) { /* nothing's wild */
+ encode_princ_key(&key, name, inst);
+ contents = dbm_fetch(db, key);
+ if (contents.dptr == NULL) {
+ found = 0;
+ goto done;
+ }
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ found = 1;
+ goto done;
+ }
+ /* process wild cards by looping through entire database */
+
+ for (key = dbm_firstkey(db); key.dptr != NULL;
+ key = dbm_next(db, key)) {
+ decode_princ_key(&key, testname, testinst);
+ if ((wildp || !strcmp(testname, name)) &&
+ (wildi || !strcmp(testinst, inst))) { /* have a match */
+ if (found >= max) {
+ *more = 1;
+ goto done;
+ } else {
+ found++;
+ contents = dbm_fetch(db, key);
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr,
+ "\tfound %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ principal++; /* point to next */
+ }
+ }
+ }
+
+ done:
+ kerb_dbl_unlock(); /* unlock read lock */
+ dbm_close(db);
+ if (kerb_end_read(trans) == 0)
+ break;
+ found = -1;
+ if (!non_blocking)
+ sleep(1);
+ }
+ return (found);
+}
+
+/*
+ * Update a name in the data base. Returns number of names
+ * successfully updated.
+ */
+
+kerb_db_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* number of principal structs to
+ * update */
+
+{
+ int found = 0, code;
+ u_long i;
+ extern int errorproc();
+ datum key, contents;
+ DBM *db;
+
+ gettimeofday(&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);
+}
+
+static void
+encode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ static char keystring[ANAME_SZ + INST_SZ];
+
+ bzero(keystring, ANAME_SZ + INST_SZ);
+ strncpy(keystring, name, ANAME_SZ);
+ strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
+ key->dptr = keystring;
+ key->dsize = ANAME_SZ + INST_SZ;
+}
+
+static void
+decode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ strncpy(name, key->dptr, ANAME_SZ);
+ strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
+ name[ANAME_SZ - 1] = '\0';
+ instance[INST_SZ - 1] = '\0';
+}
+
+static void
+encode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ contents->dsize = sizeof(*principal);
+ contents->dptr = (char *) principal;
+}
+
+static void
+decode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ bcopy(contents->dptr, (char *) principal, sizeof(*principal));
+}
+
+kerb_db_get_stat(s)
+ DB_stat *s;
+{
+ gettimeofday(&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 */
+}
+
+kerb_db_put_stat(s)
+ DB_stat *s;
+{
+}
+
+delta_stat(a, b, c)
+ DB_stat *a, *b, *c;
+{
+ /* c = a - b then b = a for the next time */
+
+ c->cpu = a->cpu - b->cpu;
+ c->elapsed = a->elapsed - b->elapsed;
+ c->dio = a->dio - b->dio;
+ c->pfault = a->pfault - b->pfault;
+ c->t_stamp = a->t_stamp - b->t_stamp;
+ c->n_retrieve = a->n_retrieve - b->n_retrieve;
+ c->n_replace = a->n_replace - b->n_replace;
+ c->n_append = a->n_append - b->n_append;
+ c->n_get_stat = a->n_get_stat - b->n_get_stat;
+ c->n_put_stat = a->n_put_stat - b->n_put_stat;
+
+ bcopy(a, b, sizeof(DB_stat));
+ return;
+}
+
+/*
+ * look up a dba in the data base returns number of dbas found , and
+ * whether there were more than requested.
+ */
+
+kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
+ char *dba_name; /* could have wild card */
+ char *dba_inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ *more = 0;
+ return (0);
+}
+
+kerb_db_iterate (func, arg)
+ int (*func)();
+ char *arg; /* void *, really */
+{
+ datum key, contents;
+ Principal *principal;
+ int code;
+ DBM *db;
+
+ kerb_db_init(); /* initialize and open the database */
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return code;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
+ contents = dbm_fetch (db, key);
+ /* XXX may not be properly aligned */
+ principal = (Principal *) contents.dptr;
+ if ((code = (*func)(arg, principal)) != 0)
+ return code;
+ }
+ dbm_close(db);
+ kerb_dbl_unlock();
+ return 0;
+}
+
+static int dblfd = -1;
+static int mylock = 0;
+static int inited = 0;
+
+static kerb_dbl_init()
+{
+ if (!inited) {
+ char *filename = gen_dbsuffix (current_db_name, ".ok");
+ if ((dblfd = open(filename, 0)) < 0) {
+ fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
+ fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+ free(filename);
+ inited++;
+ }
+ return (0);
+}
+
+static void kerb_dbl_fini()
+{
+ close(dblfd);
+ dblfd = -1;
+ inited = 0;
+ mylock = 0;
+}
+
+static int kerb_dbl_lock(mode)
+ int mode;
+{
+ int flock_mode;
+
+ if (!inited)
+ kerb_dbl_init();
+ if (mylock) { /* Detect lock call when lock already
+ * locked */
+ fprintf(stderr, "Kerberos locking error (mylock)\n");
+ fflush(stderr);
+ exit(1);
+ }
+ switch (mode) {
+ case KERB_DBL_EXCLUSIVE:
+ flock_mode = LOCK_EX;
+ break;
+ case KERB_DBL_SHARED:
+ flock_mode = LOCK_SH;
+ break;
+ default:
+ fprintf(stderr, "invalid lock mode %d\n", mode);
+ abort();
+ }
+ if (non_blocking)
+ flock_mode |= LOCK_NB;
+
+ if (flock(dblfd, flock_mode) < 0)
+ return errno;
+ mylock++;
+ return 0;
+}
+
+static void kerb_dbl_unlock()
+{
+ if (!mylock) { /* lock already unlocked */
+ fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
+ fflush(stderr);
+ exit(1);
+ }
+ if (flock(dblfd, LOCK_UN) < 0) {
+ fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
+ fflush(stderr);
+ perror("flock");
+ exit(1);
+ }
+ mylock = 0;
+}
+
+int kerb_db_set_lockmode(mode)
+ int mode;
+{
+ int old = non_blocking;
+ non_blocking = mode;
+ return old;
+}
diff --git a/eBones/lib/libkdb/krb_kdb_utils.c b/eBones/lib/libkdb/krb_kdb_utils.c
new file mode 100644
index 0000000..5fccc53
--- /dev/null
+++ b/eBones/lib/libkdb/krb_kdb_utils.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Utility routines for Kerberos programs which directly access
+ * the database. This code was duplicated in too many places
+ * before I gathered it here.
+ *
+ * Jon Rochlis, MIT Telecom, March 1988
+ *
+ * from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $
+ * $Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_kdb_utils.c,v 1.2 1994/07/19 19:23:38 g89r4222 Exp $";
+#endif lint
+
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <kdc.h>
+#include <stdio.h>
+#include <sys/file.h>
+
+long kdb_get_master_key(prompt, master_key, master_key_sched)
+ int prompt;
+ C_Block master_key;
+ Key_schedule master_key_sched;
+{
+ int kfile;
+
+ if (prompt) {
+#ifdef NOENCRYPTION
+ placebo_read_password(master_key,
+ "\nEnter Kerberos master key: ", 0);
+#else
+ des_read_password(master_key,
+ "\nEnter Kerberos master key: ", 0);
+#endif
+ printf ("\n");
+ }
+ else {
+ kfile = open(MKEYFILE, O_RDONLY, 0600);
+ if (kfile < 0) {
+ /* oh, for com_err_ */
+ return (-1);
+ }
+ if (read(kfile, (char *) master_key, 8) != 8) {
+ return (-1);
+ }
+ close(kfile);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(master_key,master_key_sched);
+#endif
+ return (0);
+}
+
+/* The caller is reasponsible for cleaning up the master key and sched,
+ even if we can't verify the master key */
+
+/* Returns master key version if successful, otherwise -1 */
+
+long kdb_verify_master_key (master_key, master_key_sched, out)
+ C_Block master_key;
+ Key_schedule master_key_sched;
+ FILE *out; /* setting this to non-null be do output */
+{
+ C_Block key_from_db;
+ Principal principal_data[1];
+ int n, more = 0;
+ long master_key_version;
+
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ if (out != (FILE *) NULL)
+ fprintf(out,
+ "verify_master_key: %s, %d found.\n",
+ "Kerberos error on master key version lookup",
+ n);
+ return (-1);
+ }
+
+ master_key_version = (long) principal_data[0].key_version;
+
+ /* set up the master key */
+ if (out != (FILE *) NULL) /* should we punt this? */
+ fprintf(out, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt the key in the db, had better
+ * be the same!
+ */
+ bcopy(&principal_data[0].key_low, key_from_db, 4);
+ bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
+ kdb_encrypt_key (key_from_db, key_from_db,
+ master_key, master_key_sched, DECRYPT);
+
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ /* this used to zero the master key here! */
+ bzero(key_from_db, sizeof(key_from_db));
+ bzero(principal_data, sizeof (principal_data));
+
+ if (n && (out != (FILE *) NULL)) {
+ fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
+ fprintf(out, "does not match database.\n");
+ return (-1);
+ }
+ if (out != (FILE *) NULL) {
+ fprintf(out, "\nMaster key entered. BEWARE!\07\07\n");
+ fflush(out);
+ }
+
+ return (master_key_version);
+}
+
+/* The old algorithm used the key schedule as the initial vector which
+ was byte order depedent ... */
+
+kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
+ C_Block in, out, master_key;
+ Key_schedule master_key_sched;
+ int e_d_flag;
+{
+
+#ifdef NOENCRYPTION
+ bcopy(in, out, sizeof(C_Block));
+#else
+ pcbc_encrypt(in,out,(long)sizeof(C_Block),master_key_sched,master_key,
+ e_d_flag);
+#endif
+}
diff --git a/eBones/lib/libkdb/krb_lib.c b/eBones/lib/libkdb/krb_lib.c
new file mode 100644
index 0000000..f0f1f6f
--- /dev/null
+++ b/eBones/lib/libkdb/krb_lib.c
@@ -0,0 +1,242 @@
+/*
+ * $Source: /home/CVS/src/eBones/kdb/krb_lib.c,v $
+ * $Author: g89r4222 $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_lib.c,v 1.2 1994/07/19 19:23:39 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#ifdef DEBUG
+extern int debug;
+extern char *progname;
+long kerb_debug;
+#endif
+
+extern char *strncpy();
+extern char *ctime();
+extern char *getenv();
+
+static init = 0;
+
+/*
+ * initialization routine for data base
+ */
+
+int
+kerb_init()
+{
+#ifdef DEBUG
+ if (!init) {
+ char *dbg = getenv("KERB_DBG");
+ if (dbg)
+ sscanf(dbg, "%d", &kerb_debug);
+ init = 1;
+ }
+#endif
+ kerb_db_init();
+
+#ifdef CACHE
+ kerb_cache_init();
+#endif
+
+ /* successful init, return 0, else errcode */
+ return (0);
+}
+
+/*
+ * finalization routine for database -- NOTE: MUST be called by any
+ * program using kerb_init. ALSO will have to be modified to finalize
+ * caches, if they're ever really implemented.
+ */
+
+int
+kerb_fini()
+{
+ kerb_db_fini();
+}
+
+/*
+ * look up a principal in the cache or data base returns number of
+ * principals found
+ */
+
+int
+kerb_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the principal area */
+ bzero((char *) principal, max * sizeof(Principal));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_principal(name, inst, principal, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_principal(name, inst, principal, max, more);
+ /* try to insert principal(s) into cache if it was found */
+#ifdef CACHE
+ if (found) {
+ kerb_cache_put_principal(principal, found);
+ }
+#endif
+ return (found);
+}
+
+/* principals */
+kerb_put_principal(principal, n)
+ Principal *principal;
+ unsigned int n; /* number of principal structs to write */
+{
+ long time();
+ struct tm *tp, *localtime();
+
+ /* set mod date */
+ principal->mod_date = time((long *)0);
+ /* and mod date string */
+
+ tp = localtime(&principal->mod_date);
+ (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ int i;
+ fprintf(stderr, "\nkerb_put_principal...");
+ for (i = 0; i < n; i++) {
+ krb_print_principal(&principal[i]);
+ }
+ }
+#endif
+ /* write database */
+ if (kerb_db_put_principal(principal, n) < 0) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_db_put_principal err", progname);
+ /* watch out for cache */
+#endif
+ return -1;
+ }
+#ifdef CACHE
+ /* write cache */
+ if (!kerb_cache_put_principal(principal, n)) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname);
+#endif
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int
+kerb_get_dba(name, inst, dba, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the dba area */
+ bzero((char *) dba, max * sizeof(Dba));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_dba(name, inst, dba, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_dba(name, inst, dba, max, more);
+#ifdef CACHE
+ /* try to insert dba(s) into cache if it was found */
+ if (found) {
+ kerb_cache_put_dba(dba, found);
+ }
+#endif
+ return (found);
+}
diff --git a/eBones/lib/libkdb/print_princ.c b/eBones/lib/libkdb/print_princ.c
new file mode 100644
index 0000000..730cfb7
--- /dev/null
+++ b/eBones/lib/libkdb/print_princ.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: $Header: /home/CVS/src/eBones/kdb/print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $
+ * $Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: print_princ.c,v 1.2 1994/07/19 19:23:41 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <strings.h>
+#include <krb.h>
+#include <krb_db.h>
+
+extern int debug;
+extern char *strncpy();
+extern char *ctime();
+extern struct tm *localtime();
+struct tm *time_p;
+
+long kerb_debug;
+
+krb_print_principal(a_n)
+ Principal *a_n;
+{
+ /* run-time database does not contain string versions */
+ time_p = localtime(&(a_n->exp_date));
+
+ fprintf(stderr,
+ "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x",
+ a_n->name, a_n->instance,
+ time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900,
+ time_p->tm_mon + 1, time_p->tm_mday,
+ time_p->tm_hour, time_p->tm_min,
+ a_n->max_life, 5 * a_n->max_life, a_n->attributes);
+
+ fprintf(stderr,
+ "\n\tkey_ver %d k_low 0x%08x k_high 0x%08x akv %d exists %d\n",
+ a_n->key_version, a_n->key_low, a_n->key_high,
+ a_n->kdc_key_ver, a_n->old);
+
+ fflush(stderr);
+}
diff --git a/eBones/lib/libkrb/Makefile b/eBones/lib/libkrb/Makefile
new file mode 100644
index 0000000..8336132
--- /dev/null
+++ b/eBones/lib/libkrb/Makefile
@@ -0,0 +1,31 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1994/09/07 16:10:17 g89r4222 Exp $
+
+LIB= krb
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42
+SRCS= create_auth_reply.c create_ciph.c \
+ create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
+ des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \
+ get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \
+ get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \
+ get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \
+ k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \
+ krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \
+ mk_priv.c mk_req.c mk_safe.c month_sname.c \
+ netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \
+ rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \
+ save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \
+ tkt_string.c util.c
+
+TDIR= ${.CURDIR}/..
+krb_err.et.c: ${COMPILE_ET}
+ (cd ${TDIR}/compile_et; make)
+ ${COMPILE_ET} ${.CURDIR}/krb_err.et -n
+
+beforedepend: krb_err.et.c
+
+CLEANFILES+= krb_err.et.c krb_err.h
+
+.include <bsd.lib.mk>
diff --git a/eBones/lib/libkrb/add_ticket.c b/eBones/lib/libkrb/add_ticket.c
new file mode 100644
index 0000000..cb79a18
--- /dev/null
+++ b/eBones/lib/libkrb/add_ticket.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $
+ * $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is now obsolete. It used to be possible to request
+ * more than one ticket at a time from the authentication server, and
+ * it looks like this routine was used by the server to package the
+ * tickets to be returned to the client.
+ */
+
+/*
+ * This routine adds a new ticket to the ciphertext to be returned to
+ * the client. The routine takes the ciphertext (which doesn't get
+ * encrypted till later), the number of the ticket (i.e. 1st, 2nd,
+ * etc) the session key which goes in the ticket and is sent back to
+ * the user, the lifetime for the ticket, the service name, the
+ * instance, the realm, the key version number, and the ticket itself.
+ *
+ * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on
+ * failure. On failure, which occurs when there isn't enough room
+ * for the ticket, a 0 length ticket is added.
+ *
+ * Notes: This routine must be called with successive values of n.
+ * i.e. the ticket must be added in order. The corresponding routine
+ * on the client side is extract ticket.
+ */
+
+/* XXX they aren't all used; to avoid incompatible changes we will
+ * fool lint for the moment */
+/*ARGSUSED */
+add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket)
+ KTEXT cipher; /* Ciphertext info for ticket */
+ char *sname; /* Service name */
+ char *instance; /* Instance */
+ int n; /* Relative position of this ticket */
+ char *session; /* Session key for this tkt */
+ int lifetime; /* Lifetime of this ticket */
+ char *realm; /* Realm in which ticket is valid */
+ int kvno; /* Key version number of service key */
+ KTEXT ticket; /* The ticket itself */
+{
+
+ /* Note, the 42 is a temporary hack; it will have to be changed. */
+
+ /* Begin check of ticket length */
+ if ((cipher->length + ticket->length + 4 + 42 +
+ (*(cipher->dat)+1-n)*(11+strlen(realm))) >
+ MAX_KTXT_LEN) {
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ *(cipher->dat+n) = 0;
+ return(KFAILURE);
+ }
+ /* End check of ticket length */
+
+ /* Add the session key, lifetime, kvno, ticket to the ciphertext */
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length),
+ ticket->length);
+ cipher->length += ticket->length;
+
+ /* Set the ticket length at beginning of ciphertext */
+ *(cipher->dat+n) = ticket->length;
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/create_auth_reply.c b/eBones/lib/libkrb/create_auth_reply.c
new file mode 100644
index 0000000..e47d4df
--- /dev/null
+++ b/eBones/lib/libkrb/create_auth_reply.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $
+ * $Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_auth_reply.c,v 1.2 1994/07/19 19:24:56 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is called by the Kerberos authentication server
+ * to create a reply to an authentication request. The routine
+ * takes the user's name, instance, and realm, the client's
+ * timestamp, the number of tickets, the user's key version
+ * number and the ciphertext containing the tickets themselves.
+ * It constructs a packet and returns a pointer to it.
+ *
+ * Notes: The packet returned by this routine is static. Thus, if you
+ * intend to keep the result beyond the next call to this routine, you
+ * must copy it elsewhere.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_KDC_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned char n number of tickets
+ *
+ * unsigned long x_date expiration date
+ *
+ * unsigned char kvno master key version
+ *
+ * short w_1 cipher length
+ *
+ * --- cipher->dat cipher data
+ */
+
+KTEXT
+create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long time_ws; /* Workstation time */
+ int n; /* Number of tickets */
+ unsigned long x_date; /* Principal's expiration date */
+ int kvno; /* Principal's key version number */
+ KTEXT cipher; /* Cipher text with tickets and
+ * session keys */
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ unsigned char *v = pkt->dat; /* Prot vers number */
+ unsigned char *t = (pkt->dat+1); /* Prot message type */
+ short w_l; /* Cipher length */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ if (n != 0)
+ *v = 3;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2), pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* Workstation timestamp */
+ bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+ /* Expiration date */
+ bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+
+ /* Now send the ciphertext and info to help decode it */
+ *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
+ w_l = (short) cipher->length;
+ bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
+ pkt->length += 2;
+ bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
+ cipher->length);
+ pkt->length += cipher->length;
+
+ /* And return the packet */
+ return pkt;
+}
diff --git a/eBones/lib/libkrb/create_ciph.c b/eBones/lib/libkrb/create_ciph.c
new file mode 100644
index 0000000..c3bc0db
--- /dev/null
+++ b/eBones/lib/libkrb/create_ciph.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $
+ * $Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_ciph.c,v 1.2 1994/07/19 19:24:58 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <strings.h>
+
+/*
+ * This routine is used by the authentication server to create
+ * a packet for its client, containing a ticket for the requested
+ * service (given in "tkt"), and some information about the ticket,
+ *
+ * Returns KSUCCESS no matter what.
+ *
+ * The length of the cipher is stored in c->length; the format of
+ * c->dat is as follows:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ *
+ * 8 bytes session session key for client, service
+ *
+ * string service service name
+ *
+ * string instance service instance
+ *
+ * string realm KDC realm
+ *
+ * unsigned char life ticket lifetime
+ *
+ * unsigned char kvno service key version number
+ *
+ * unsigned char tkt->length length of following ticket
+ *
+ * data tkt->dat ticket for service
+ *
+ * 4 bytes kdc_time KDC's timestamp
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+create_ciph(c, session, service, instance, realm, life, kvno, tkt,
+ kdc_time, key)
+ KTEXT c; /* Text block to hold ciphertext */
+ C_Block session; /* Session key to send to user */
+ char *service; /* Service name on ticket */
+ char *instance; /* Instance name on ticket */
+ char *realm; /* Realm of this KDC */
+ unsigned long life; /* Lifetime of the ticket */
+ int kvno; /* Key version number for service */
+ KTEXT tkt; /* The ticket for the service */
+ unsigned long kdc_time; /* KDC time */
+ C_Block key; /* Key to encrypt ciphertext with */
+{
+ char *ptr;
+ Key_schedule key_s;
+
+ ptr = (char *) c->dat;
+
+ bcopy((char *) session, ptr, 8);
+ ptr += 8;
+
+ (void) strcpy(ptr,service);
+ ptr += strlen(service) + 1;
+
+ (void) strcpy(ptr,instance);
+ ptr += strlen(instance) + 1;
+
+ (void) strcpy(ptr,realm);
+ ptr += strlen(realm) + 1;
+
+ *(ptr++) = (unsigned char) life;
+ *(ptr++) = (unsigned char) kvno;
+ *(ptr++) = (unsigned char) tkt->length;
+
+ bcopy((char *)(tkt->dat),ptr,tkt->length);
+ ptr += tkt->length;
+
+ bcopy((char *) &kdc_time,ptr,4);
+ ptr += 4;
+
+ /* guarantee null padded encrypted data to multiple of 8 bytes */
+ bzero(ptr, 7);
+
+ c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s,
+ key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/create_death_packet.c b/eBones/lib/libkrb/create_death_packet.c
new file mode 100644
index 0000000..f747d6b
--- /dev/null
+++ b/eBones/lib/libkrb/create_death_packet.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $
+ * $Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: create_death_packet.c,v 1.2 1994/07/19 19:24:59 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a packet to type AUTH_MSG_DIE which is sent to
+ * the Kerberos server to make it shut down. It is used only in the
+ * development environment.
+ *
+ * It takes a string "a_name" which is sent in the packet. A pointer
+ * to the packet is returned.
+ *
+ * The format of the killer packet is:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_DIE message type
+ *
+ * [least significant HOST_BYTE_ORDER byte order of sender
+ * bit of above field]
+ *
+ * string a_name presumably, name of
+ * principal sending killer
+ * packet
+ */
+
+#ifdef DEBUG
+KTEXT
+krb_create_death_packet(a_name)
+ char *a_name;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+
+ unsigned char *v = pkt->dat;
+ unsigned char *t = (pkt->dat+1);
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_DIE;
+ *t |= HOST_BYTE_ORDER;
+ (void) strcpy((char *) (pkt->dat+2),a_name);
+ pkt->length = 3 + strlen(a_name);
+ return pkt;
+}
+#endif /* DEBUG */
diff --git a/eBones/lib/libkrb/create_ticket.c b/eBones/lib/libkrb/create_ticket.c
new file mode 100644
index 0000000..984d8e9
--- /dev/null
+++ b/eBones/lib/libkrb/create_ticket.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $
+ * $Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: create_ticket.c,v 1.2 1994/07/19 19:25:01 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed. It then constructs a ticket and returns, leaving the
+ * newly created ticket in tkt.
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket. When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * tkt->length length of ticket (multiple of 8 bytes)
+ *
+ * tkt->dat:
+ *
+ * unsigned char flags namely, HOST_BYTE_ORDER
+ *
+ * string pname client's name
+ *
+ * string pinstance client's instance
+ *
+ * string prealm client's realm
+ *
+ * 4 bytes paddress client's address
+ *
+ * 8 bytes session session key
+ *
+ * 1 byte life ticket lifetime
+ *
+ * 4 bytes time_sec KDC timestamp
+ *
+ * string sname service's name
+ *
+ * string sinstance service's instance
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+{
+ Key_schedule key_s;
+ register char *data; /* running index into ticket */
+
+ tkt->length = 0; /* Clear previous data */
+ flags |= HOST_BYTE_ORDER; /* ticket byte order */
+ bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
+ data = ((char *)tkt->dat) + sizeof(flags);
+ (void) strcpy(data, pname);
+ data += 1 + strlen(pname);
+ (void) strcpy(data, pinstance);
+ data += 1 + strlen(pinstance);
+ (void) strcpy(data, prealm);
+ data += 1 + strlen(prealm);
+ bcopy((char *) &paddress, data, 4);
+ data += 4;
+
+ bcopy((char *) session, data, 8);
+ data += 8;
+ *(data++) = (char) life;
+ /* issue time */
+ bcopy((char *) &time_sec, data, 4);
+ data += 4;
+ (void) strcpy(data, sname);
+ data += 1 + strlen(sname);
+ (void) strcpy(data, sinstance);
+ data += 1 + strlen(sinstance);
+
+ /* guarantee null padded ticket to multiple of 8 bytes */
+ bzero(data, 7);
+ tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+ /* Check length of ticket */
+ if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+ bzero(tkt->dat, tkt->length);
+ tkt->length = 0;
+ return KFAILURE /* XXX */;
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,ENCRYPT);
+#endif
+ return 0;
+}
diff --git a/eBones/lib/libkrb/debug_decl.c b/eBones/lib/libkrb/debug_decl.c
new file mode 100644
index 0000000..1a0f6df
--- /dev/null
+++ b/eBones/lib/libkrb/debug_decl.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $
+ * $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $";
+#endif lint
+
+/* Declare global debugging variables. */
+
+int krb_ap_req_debug = 0;
+int krb_debug = 0;
diff --git a/eBones/lib/libkrb/decomp_ticket.c b/eBones/lib/libkrb/decomp_ticket.c
new file mode 100644
index 0000000..181864c
--- /dev/null
+++ b/eBones/lib/libkrb/decomp_ticket.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $
+ * $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine takes a ticket and pointers to the variables that
+ * should be filled in based on the information in the ticket. It
+ * fills in values for its arguments.
+ *
+ * Note: if the client realm field in the ticket is the null string,
+ * then the "prealm" variable is filled in with the local realm (as
+ * defined by KRB_REALM).
+ *
+ * If the ticket byte order is different than the host's byte order
+ * (as indicated by the byte order bit of the "flags" field), then
+ * the KDC timestamp "time_sec" is byte-swapped. The other fields
+ * potentially affected by byte order, "paddress" and "session" are
+ * not byte-swapped.
+ *
+ * The routine returns KFAILURE if any of the "pname", "pinstance",
+ * or "prealm" fields is too big, otherwise it returns KSUCCESS.
+ *
+ * The corresponding routine to generate tickets is create_ticket.
+ * When changes are made to this routine, the corresponding changes
+ * should also be made to that file.
+ *
+ * See create_ticket.c for the format of the ticket packet.
+ */
+
+decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
+ life, time_sec, sname, sinstance, key, key_s)
+ KTEXT tkt; /* The ticket to be decoded */
+ unsigned char *flags; /* Kerberos ticket flags */
+ char *pname; /* Authentication name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ unsigned long *paddress; /* Net address of entity
+ * requesting ticket */
+ C_Block session; /* Session key inserted in ticket */
+ int *life; /* Lifetime of the ticket */
+ unsigned long *time_sec; /* Issue time and date */
+ char *sname; /* Service name */
+ char *sinstance; /* Service instance */
+ C_Block key; /* Service's secret key
+ * (to decrypt the ticket) */
+ Key_schedule key_s; /* The precomputed key schedule */
+{
+ static int tkt_swap_bytes;
+ unsigned char *uptr;
+ char *ptr = (char *)tkt->dat;
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,key,DECRYPT);
+#endif /* ! NOENCRYPTION */
+
+ *flags = *ptr; /* get flags byte */
+ ptr += sizeof(*flags);
+ tkt_swap_bytes = 0;
+ if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
+ tkt_swap_bytes++;
+
+ if (strlen(ptr) > ANAME_SZ)
+ return(KFAILURE);
+ (void) strcpy(pname,ptr); /* pname */
+ ptr += strlen(pname) + 1;
+
+ if (strlen(ptr) > INST_SZ)
+ return(KFAILURE);
+ (void) strcpy(pinstance,ptr); /* instance */
+ ptr += strlen(pinstance) + 1;
+
+ if (strlen(ptr) > REALM_SZ)
+ return(KFAILURE);
+ (void) strcpy(prealm,ptr); /* realm */
+ ptr += strlen(prealm) + 1;
+ /* temporary hack until realms are dealt with properly */
+ if (*prealm == 0)
+ (void) strcpy(prealm,KRB_REALM);
+
+ bcopy(ptr,(char *)paddress,4); /* net address */
+ ptr += 4;
+
+ bcopy(ptr,(char *)session,8); /* session key */
+ ptr+= 8;
+#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
+ if (tkt_swap_bytes)
+ swap_C_Block(session);
+#endif
+
+ /* get lifetime, being certain we don't get negative lifetimes */
+ uptr = (unsigned char *) ptr++;
+ *life = (int) *uptr;
+
+ bcopy(ptr,(char *) time_sec,4); /* issue time */
+ ptr += 4;
+ if (tkt_swap_bytes)
+ swap_u_long(*time_sec);
+
+ (void) strcpy(sname,ptr); /* service name */
+ ptr += 1 + strlen(sname);
+
+ (void) strcpy(sinstance,ptr); /* instance */
+ ptr += 1 + strlen(sinstance);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/des_rw.c b/eBones/lib/libkrb/des_rw.c
new file mode 100644
index 0000000..c958355
--- /dev/null
+++ b/eBones/lib/libkrb/des_rw.c
@@ -0,0 +1,265 @@
+/* -
+ * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
+ * All rights reserved.
+ *
+ * This code is derived from a specification based on software
+ * which forms part of the 4.4BSD-Lite distribution, which was developed
+ * by the University of California and its contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the entire comment,
+ * including the above copyright notice, this list of conditions
+ * and the following disclaimer, verbatim, at the beginning of
+ * the source file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Geoffrey M. Rehmet
+ * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $
+ */
+
+/*
+ *
+ * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED.
+ *
+ */
+
+/*
+ * Routines for reading and writing DES encrypted messages onto sockets.
+ * (These routines will fail if non-blocking I/O is used.)
+ *
+ * When a message is written, its length is first transmitted as an int,
+ * in network byte order. The encrypted message is then transmitted,
+ * to a multiple of 8 bytes. Messages shorter than 8 bytes are right
+ * justified into a buffer of length 8 bytes, and the remainder of the
+ * buffer is filled with random garbage (before encryption):
+ *
+ * DDD -------->--+--------+
+ * | |
+ * +--+--+--+--+--+--+--+--+
+ * |x |x |x |x |x |D |D |D |
+ * +--+--+--+--+--+--+--+--+
+ * | garbage | data |
+ * | |
+ * +-----------------------+----> des_pcbc_encrypt() -->
+ *
+ * (Note that the length field sent before the actual message specifies
+ * the number of data bytes, not the length of the entire padded message.
+ *
+ * When data is read, if the message received is longer than the number
+ * of bytes requested, then the remaining bytes are stored until the
+ * following call to des_read(). If the number of bytes received is
+ * less then the number of bytes received, then only the number of bytes
+ * actually received is returned.
+ *
+ * This interface corresponds with the original des_rw.c, except for the
+ * bugs in des_read() in the original 4.4BSD version. (One bug is
+ * normally not visible, due to undocumented behaviour of
+ * des_pcbc_encrypt() in the original MIT libdes.)
+ *
+ * XXX Todo:
+ * 1) Give better error returns on writes
+ * 2) Improve error checking on reads
+ * 3) Get rid of need for extern decl. of krb_net_read()
+ * 4) Tidy garbage generation a bit
+ * 5) Make the above comment more readable
+ */
+
+#ifdef CRYPT
+#ifdef KERBEROS
+
+#ifndef BUFFER_LEN
+#define BUFFER_LEN 10240
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+
+extern int krb_net_read(int fd, void * data, size_t length);
+extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output,
+ register long length,
+ des_key_schedule schedule,
+ des_cblock *ivec,
+ int encrypt);
+
+static bit_64 des_key;
+static des_key_schedule key_sched;
+
+/*
+ * Buffer for storing extra data when more data is received, then was
+ * actually requested in des_read().
+ */
+static u_char des_buff[BUFFER_LEN];
+static u_char buffer[BUFFER_LEN];
+static unsigned stored = 0;
+static u_char *buff_ptr = buffer;
+
+/*
+ * Set the encryption key for des_read() and des_write().
+ * inkey is the initial vector for the DES encryption, while insched is
+ * the DES key, in unwrapped form.
+ */
+void des_set_key(inkey, insched)
+ bit_64 *inkey;
+ u_char *insched;
+{
+ bcopy(inkey, &des_key, sizeof(bit_64));
+ bcopy(insched, &key_sched, sizeof(des_key_schedule));
+}
+
+/*
+ * Clear the key schedule, and initial vector, which were previously
+ * stored in static vars by des_set_key().
+ */
+void des_clear_key()
+{
+ bzero(&des_key, sizeof(des_cblock));
+ bzero(&key_sched, sizeof(des_key_schedule));
+}
+
+int des_read(fd, buf, len)
+ int fd;
+ register char * buf;
+ int len;
+{
+ int msg_length; /* length of actual message data */
+ int pad_length; /* length of padded message */
+ int nread; /* number of bytes actually read */
+ int nreturned = 0;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ return(len);
+ } else {
+ if (stored) {
+ bcopy(buff_ptr, buf, stored);
+ nreturned = stored;
+ len -= stored;
+ stored = 0;
+ buff_ptr = buffer;
+ } else {
+ nreturned = 0;
+ buff_ptr = buffer;
+ }
+ }
+
+ nread = krb_net_read(fd, &msg_length, sizeof(msg_length));
+ if(nread != (int)(sizeof(msg_length)))
+ return(0);
+
+ msg_length = ntohl(msg_length);
+ pad_length = roundup(msg_length, 8);
+
+ nread = krb_net_read(fd, des_buff, pad_length);
+ if(nread != pad_length)
+ return(0);
+
+ des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr,
+ (msg_length < 8 ? 8 : msg_length),
+ key_sched, (des_cblock*) &des_key, DES_DECRYPT);
+
+
+ if(msg_length < 8)
+ buff_ptr += (8 - msg_length);
+ stored = msg_length;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ nreturned += len;
+ } else {
+ bcopy(buff_ptr, buf, stored);
+ nreturned += stored;
+ stored = 0;
+ }
+
+ return(nreturned);
+}
+
+
+/*
+ * Write a message onto a file descriptor (generally a socket), using
+ * DES to encrypt the message.
+ */
+int des_write(fd, buf, len)
+ int fd;
+ char * buf;
+ int len;
+{
+ static int seeded = 0;
+ char garbage[8];
+ long rnd;
+ int pad_len;
+ int write_len;
+ int nwritten = 0;
+ int i;
+ char *data;
+
+ if(len < 8) {
+ /*
+ * Right justify the message in 8 bytes of random garbage.
+ */
+ if(!seeded) {
+ seeded = 1;
+ srandom((unsigned)time(NULL));
+ }
+
+ for(i = 0 ; i < 8 ; i+= sizeof(long)) {
+ rnd = random();
+ bcopy(&rnd, garbage+i,
+ (i <= (8 - sizeof(long)))?sizeof(long):(8-i));
+ }
+ bcopy(buf, garbage + 8 - len, len);
+ data = garbage;
+ pad_len = 8;
+ } else {
+ data = buf;
+ pad_len = roundup(len, 8);
+ }
+
+ des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff,
+ (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT);
+
+
+ write_len = htonl(len);
+ if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len))
+ return(-1);
+ if(write(fd, des_buff, pad_len) != pad_len)
+ return(-1);
+
+ return(len);
+}
+
+#endif /* KERBEROS */
+#endif /* CRYPT */
diff --git a/eBones/lib/libkrb/dest_tkt.c b/eBones/lib/libkrb/dest_tkt.c
new file mode 100644
index 0000000..17c7855
--- /dev/null
+++ b/eBones/lib/libkrb/dest_tkt.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $
+ * $Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: dest_tkt.c,v 1.2 1994/07/19 19:25:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+#include <errno.h>
+
+/*
+ * dest_tkt() is used to destroy the ticket store upon logout.
+ * If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
+ * Otherwise the function returns RET_OK on success, KFAILURE on
+ * failure.
+ *
+ * The ticket file (TKT_FILE) is defined in "krb.h".
+ */
+
+dest_tkt()
+{
+ char *file = TKT_FILE;
+ int i,fd;
+ extern int errno;
+ struct stat statb;
+ char buf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ errno = 0;
+ if (lstat(file,&statb) < 0)
+ goto out;
+
+ if (!(statb.st_mode & S_IFREG)
+#ifdef notdef
+ || statb.st_mode & 077
+#endif
+ )
+ goto out;
+
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out;
+
+ bzero(buf, BUFSIZ);
+
+ for (i = 0; i < statb.st_size; i += BUFSIZ)
+ if (write(fd, buf, BUFSIZ) != BUFSIZ) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+
+ (void) unlink(file);
+
+out:
+ if (errno == ENOENT) return RET_TKFIL;
+ else if (errno != 0) return KFAILURE;
+#ifdef TKT_SHMEM
+ /*
+ * handle the shared memory case
+ */
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
+ return(i);
+#endif /* TKT_SHMEM */
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/extract_ticket.c b/eBones/lib/libkrb/extract_ticket.c
new file mode 100644
index 0000000..571d5da
--- /dev/null
+++ b/eBones/lib/libkrb/extract_ticket.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $
+ * $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is obsolete.
+ *
+ * This routine accepts the ciphertext returned by kerberos and
+ * extracts the nth ticket. It also fills in the variables passed as
+ * session, liftime and kvno.
+ */
+
+extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket)
+ KTEXT cipher; /* The ciphertext */
+ int n; /* Which ticket */
+ char *session; /* The session key for this tkt */
+ int *lifetime; /* The life of this ticket */
+ int *kvno; /* The kvno for the service */
+ char *realm; /* Realm in which tkt issued */
+ KTEXT ticket; /* The ticket itself */
+{
+ char *ptr;
+ int i;
+
+ /* Start after the ticket lengths */
+ ptr = (char *) cipher->dat;
+ ptr = ptr + 1 + (int) *(cipher->dat);
+
+ /* Step through earlier tickets */
+ for (i = 1; i < n; i++)
+ ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
+ bcopy(ptr, (char *) session, 8); /* Save the session key */
+ ptr += 8;
+ *lifetime = *(ptr++); /* Save the life of the ticket */
+ *kvno = *(ptr++); /* Save the kvno */
+ (void) strcpy(realm,ptr); /* instance */
+ ptr += strlen(realm) + 1;
+
+ /* Save the ticket if its length is non zero */
+ ticket->length = *(cipher->dat+n);
+ if (ticket->length)
+ bcopy(ptr, (char *) (ticket->dat), ticket->length);
+}
diff --git a/eBones/lib/libkrb/fgetst.c b/eBones/lib/libkrb/fgetst.c
new file mode 100644
index 0000000..d938013
--- /dev/null
+++ b/eBones/lib/libkrb/fgetst.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $
+ * $Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: fgetst.c,v 1.2 1994/07/19 19:25:10 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+
+/*
+ * fgetst takes a file descriptor, a character pointer, and a count.
+ * It reads from the file it has either read "count" characters, or
+ * until it reads a null byte. When finished, what has been read exists
+ * in "s". If "count" characters were actually read, the last is changed
+ * to a null, so the returned string is always null-terminated. fgetst
+ * returns the number of characters read, including the null terminator.
+ */
+
+fgetst(f, s, n)
+ FILE *f;
+ register char *s;
+ int n;
+{
+ register count = n;
+ int ch; /* NOT char; otherwise you don't see EOF */
+
+ while ((ch = getc(f)) != EOF && ch && --count) {
+ *s++ = ch;
+ }
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/lib/libkrb/get_ad_tkt.c b/eBones/lib/libkrb/get_ad_tkt.c
new file mode 100644
index 0000000..d8e1283
--- /dev/null
+++ b/eBones/lib/libkrb/get_ad_tkt.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $
+ * $Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_ad_tkt.c,v 1.2 1994/07/19 19:25:11 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+#include <strings.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+extern int krb_debug;
+
+struct timeval tt_local = { 0, 0 };
+
+int swap_bytes;
+unsigned long rep_err_code;
+
+/*
+ * get_ad_tkt obtains a new service ticket from Kerberos, using
+ * the ticket-granting ticket which must be in the ticket file.
+ * It is typically called by krb_mk_req() when the client side
+ * of an application is creating authentication information to be
+ * sent to the server side.
+ *
+ * get_ad_tkt takes four arguments: three pointers to strings which
+ * contain the name, instance, and realm of the service for which the
+ * ticket is to be obtained; and an integer indicating the desired
+ * lifetime of the ticket.
+ *
+ * It returns an error status if the ticket couldn't be obtained,
+ * or AD_OK if all went well. The ticket is stored in the ticket
+ * cache.
+ *
+ * The request sent to the Kerberos ticket-granting service looks
+ * like this:
+ *
+ * pkt->dat
+ *
+ * TEXT original contents of authenticator+ticket
+ * pkt->dat built in krb_mk_req call
+ *
+ * 4 bytes time_ws always 0 (?)
+ * char lifetime lifetime argument passed
+ * string service service name argument
+ * string sinstance service instance arg.
+ *
+ * See "prot.h" for the reply packet layout and definitions of the
+ * extraction macros like pkt_version(), pkt_msg_type(), etc.
+ */
+
+get_ad_tkt(service,sinstance,realm,lifetime)
+ char *service;
+ char *sinstance;
+ char *realm;
+ int lifetime;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = & pkt_st; /* Packet to KDC */
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ static KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ static KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ CREDENTIALS cr;
+ int kvno; /* Kvno for session key */
+ char lrealm[REALM_SZ];
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ long time_ws = 0;
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ int msg_byte_order;
+ int kerror;
+ char rlm[REALM_SZ];
+ char *ptr;
+
+ unsigned long kdc_time; /* KDC time */
+
+ if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+ return(kerror);
+
+ /* Create skeleton of packet to be sent */
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+
+ pkt->length = 0;
+
+ /*
+ * Look for the session key (and other stuff we don't need)
+ * in the ticket file for krbtgt.realm@lrealm where "realm"
+ * is the service's realm (passed in "realm" argument) and
+ * lrealm is the realm of our initial ticket. If we don't
+ * have this, we will try to get it.
+ */
+
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+ /*
+ * If realm == lrealm, we have no hope, so let's not even try.
+ */
+ if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
+ return(AD_NOTGT);
+ else{
+ if ((kerror =
+ get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
+ return(kerror);
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
+ return(kerror);
+ }
+ }
+
+ /*
+ * Make up a request packet to the "krbtgt.realm@lrealm".
+ * Start by calling krb_mk_req() which puts ticket+authenticator
+ * into "pkt". Then tack other stuff on the end.
+ */
+
+ kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+
+ if (kerror)
+ return(AD_NOTGT);
+
+ /* timestamp */
+ bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (char) lifetime;
+ (void) strcpy((char *) (pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* Send the request to the local ticket-granting server */
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION )
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
+ if (swap_bytes)
+ swap_u_long(rep_err_code);
+ return(rep_err_code);
+
+ default:
+ return(INTK_PROT);
+ }
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length,
+ key_s,cr.session,DECRYPT);
+#endif
+ /* Get rid of all traces of key */
+ bzero((char *) cr.session, sizeof(key));
+ bzero((char *) key_s, sizeof(key_s));
+
+ ptr = (char *) cip->dat;
+
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ lifetime = (unsigned long) ptr[0];
+ kvno = (unsigned long) ptr[1];
+ tkt->length = (int) ptr[2];
+ ptr += 3;
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+ if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
+ kvno,tkt,tt_local.tv_sec))
+ return(kerror);
+
+ return(AD_OK);
+}
diff --git a/eBones/lib/libkrb/get_admhst.c b/eBones/lib/libkrb/get_admhst.c
new file mode 100644
index 0000000..c36e997
--- /dev/null
+++ b/eBones/lib/libkrb/get_admhst.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $
+ * $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <string.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos database
+ * administration server can be found.
+ *
+ * krb_get_admhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer n, and
+ * returns (in h) the nth administrative host entry from the configuration
+ * file (KRB_CONF, defined in "krb.h") associated with the specified realm.
+ *
+ * On error, get_admhst returns KFAILURE. If all goes well, the routine
+ * returns KSUCCESS.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * a Kerberos admin server. In the long run, this functionality will be
+ * provided by a nameserver.
+ */
+
+krb_get_admhst(h, r, n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char scratch[64];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ return(KFAILURE);
+ }
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ /* error reading */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (!index(linebuf, '\n')) {
+ /* didn't all fit into buffer, punt */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ for (i = 0; i < n; ) {
+ /* run through the file, looking for admin host */
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ /* need to scan for a token after 'admin' to make sure that
+ admin matched correctly */
+ if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_cred.c b/eBones/lib/libkrb/get_cred.c
new file mode 100644
index 0000000..baf7ae2
--- /dev/null
+++ b/eBones/lib/libkrb/get_cred.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $
+ * $Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_cred.c,v 1.2 1994/07/19 19:25:14 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * krb_get_cred takes a service name, instance, and realm, and a
+ * structure of type CREDENTIALS to be filled in with ticket
+ * information. It then searches the ticket file for the appropriate
+ * ticket and fills in the structure with the corresponding
+ * information from the file. If successful, it returns KSUCCESS.
+ * On failure it returns a Kerberos error code.
+ */
+
+krb_get_cred(service,instance,realm,c)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ CREDENTIALS *c; /* Credentials struct */
+{
+ int tf_status; /* return value of tf function calls */
+
+ /* Open ticket file and lock it for shared reading */
+ if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Copy principal's name and instance into the CREDENTIALS struc c */
+
+ if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
+ (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
+ return (tf_status);
+
+ /* Search for requested service credentials and copy into c */
+
+ while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
+ /* Is this the right ticket? */
+ if ((strcmp(c->service,service) == 0) &&
+ (strcmp(c->instance,instance) == 0) &&
+ (strcmp(c->realm,realm) == 0))
+ break;
+ }
+ (void) tf_close();
+
+ if (tf_status == EOF)
+ return (GC_NOTKT);
+ return(tf_status);
+}
diff --git a/eBones/lib/libkrb/get_in_tkt.c b/eBones/lib/libkrb/get_in_tkt.c
new file mode 100644
index 0000000..5fb1560
--- /dev/null
+++ b/eBones/lib/libkrb/get_in_tkt.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $
+ * $Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: passwd_to_key() converts
+ * a password into a DES key (prompting for the password if
+ * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
+ * a user.
+ */
+
+/*
+ * passwd_to_key(): given a password, return a DES key.
+ * There are extra arguments here which (used to be?)
+ * used by srvtab_to_key().
+ *
+ * If the "passwd" argument is not null, generate a DES
+ * key from it, using string_to_key().
+ *
+ * If the "passwd" argument is null, call des_read_password()
+ * to prompt for a password and then convert it into a DES key.
+ *
+ * In either case, the resulting key is put in the "key" argument,
+ * and 0 is returned.
+ */
+
+/*ARGSUSED */
+static int passwd_to_key(user,instance,realm,passwd,key)
+ char *user, *instance, *realm, *passwd;
+ C_Block key;
+{
+#ifdef NOENCRYPTION
+ if (!passwd)
+ placebo_read_password(key, "Password: ", 0);
+#else
+ if (passwd)
+ string_to_key(passwd,key);
+ else
+ des_read_password(key,"Password: ",0);
+#endif
+ return (0);
+}
+
+/*
+ * krb_get_pw_in_tkt() takes the name of the server for which the initial
+ * ticket is to be obtained, the name of the principal the ticket is
+ * for, the desired lifetime of the ticket, and the user's password.
+ * It passes its arguments on to krb_get_in_tkt(), which contacts
+ * Kerberos to get the ticket, decrypts it using the password provided,
+ * and stores it away for future use.
+ *
+ * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
+ * the name of a routine (passwd_to_key()) to be used to get the
+ * password in case the "password" argument is null and NULL for the
+ * decryption procedure indicating that krb_get_in_tkt should use the
+ * default method of decrypting the response from the KDC.
+ *
+ * The result of the call to krb_get_in_tkt() is returned.
+ */
+
+krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return(krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+ passwd_to_key, NULL, password));
+}
+
+#ifdef NOENCRYPTION
+/*
+ * $Source: /home/CVS/src/eBones/krb/get_in_tkt.c,v $
+ * $Author: g89r4222 $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine prints the supplied string to standard
+ * output as a prompt, and reads a password string without
+ * echoing.
+ */
+
+#ifndef lint
+static char rcsid_read_password_c[] =
+"Bones$Header: /home/CVS/src/eBones/krb/get_in_tkt.c,v 1.2 1994/07/19 19:25:16 g89r4222 Exp $";
+#endif lint
+
+#include <des.h>
+#include "conf.h"
+
+#include <stdio.h>
+#ifdef BSDUNIX
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+#else
+char *strcpy();
+int strcmp();
+#endif
+
+#ifdef BSDUNIX
+static jmp_buf env;
+#endif
+
+#ifdef BSDUNIX
+static void sig_restore();
+static push_signals(), pop_signals();
+int placebo_read_pw_string();
+#endif
+
+/*** Routines ****************************************************** */
+int
+placebo_read_password(k,prompt,verify)
+ des_cblock *k;
+ char *prompt;
+ int verify;
+{
+ int ok;
+ char key_string[BUFSIZ];
+
+#ifdef BSDUNIX
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+#endif
+
+ ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
+ if (ok == 0)
+ bzero(k, sizeof(C_Block));
+
+lose:
+ bzero(key_string, sizeof (key_string));
+ return ok;
+}
+
+/*
+ * This version just returns the string, doesn't map to key.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int
+placebo_read_pw_string(s,max,prompt,verify)
+ char *s;
+ int max;
+ char *prompt;
+ int verify;
+{
+ int ok = 0;
+ char *ptr;
+
+#ifdef BSDUNIX
+ jmp_buf old_env;
+ struct sgttyb tty_state;
+#endif
+ char key_string[BUFSIZ];
+
+ if (max > BUFSIZ) {
+ return -1;
+ }
+
+#ifdef BSDUNIX
+ bcopy(old_env, env, sizeof(env));
+ if (setjmp(env))
+ goto lose;
+
+ /* save terminal state*/
+ if (ioctl(0,TIOCGETP,&tty_state) == -1)
+ return -1;
+
+ push_signals();
+ /* Turn off echo */
+ tty_state.sg_flags &= ~ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state) == -1)
+ return -1;
+#endif
+ while (!ok) {
+ printf(prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(s,sizeof(s),0);
+ if (!strlen(s))
+ continue;
+#else
+ if (!fgets(s, max, stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(s, '\n')))
+ *ptr = '\0';
+#endif
+ if (verify) {
+ printf("\nVerifying, please re-enter %s",prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(key_string,sizeof(key_string),0);
+ if (!strlen(key_string))
+ continue;
+#else
+ if (!fgets(key_string, sizeof(key_string), stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(key_string, '\n')))
+ *ptr = '\0';
+#endif
+ if (strcmp(s,key_string)) {
+ printf("\n\07\07Mismatch - try again\n");
+ fflush(stdout);
+ continue;
+ }
+ }
+ ok = 1;
+ }
+
+#ifdef BSDUNIX
+lose:
+ if (!ok)
+ bzero(s, max);
+ printf("\n");
+ /* turn echo back on */
+ tty_state.sg_flags |= ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state))
+ ok = 0;
+ pop_signals();
+ bcopy(env, old_env, sizeof(env));
+#endif
+ if (verify)
+ bzero(key_string, sizeof (key_string));
+ s[max-1] = 0; /* force termination */
+ return !ok; /* return nonzero if not okay */
+}
+
+#ifdef BSDUNIX
+/*
+ * this can be static since we should never have more than
+ * one set saved....
+ */
+#ifdef POSIX
+static void (*old_sigfunc[NSIG])();
+#else
+static int (*old_sigfunc[NSIG])();
+#endif POSIX
+
+static push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}
+#endif
+#endif /* NOENCRYPTION */
diff --git a/eBones/lib/libkrb/get_krbhst.c b/eBones/lib/libkrb/get_krbhst.c
new file mode 100644
index 0000000..16c4ff2
--- /dev/null
+++ b/eBones/lib/libkrb/get_krbhst.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $
+ * $Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbhst.c,v 1.2 1994/07/19 19:25:17 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos authenti-
+ * cation server can be found.
+ *
+ * krb_get_krbhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer, n, and
+ * returns (in h) the nth entry from the configuration file (KRB_CONF,
+ * defined in "krb.h") associated with the specified realm.
+ *
+ * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the
+ * configuration file does not exist, krb_get_krbhst will return KRB_HOST
+ * (also defined in "krb.h"). If all goes well, the routine returnes
+ * KSUCCESS.
+ *
+ * The KRB_CONF file contains the name of the local realm in the first
+ * line (not used by this routine), followed by lines indicating realm/host
+ * entries. The words "admin server" following the hostname indicate that
+ * the host provides an administrative database server.
+ *
+ * For example:
+ *
+ * ATHENA.MIT.EDU
+ * ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ * ATHENA.MIT.EDU kerberos-2.mit.edu
+ * LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * kerberos. In the long run, this functionality will be provided by a
+ * nameserver.
+ */
+
+krb_get_krbhst(h,r,n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ if (n==1) {
+ (void) strcpy(h,KRB_HOST);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+ if (fscanf(cnffile,"%s",tr) == EOF)
+ return(KFAILURE);
+ /* run through the file, looking for the nth server for this realm */
+ for (i = 1; i <= n;) {
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (sscanf(linebuf, "%s %s", tr, h) != 2)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_krbrlm.c b/eBones/lib/libkrb/get_krbrlm.c
new file mode 100644
index 0000000..7df073d
--- /dev/null
+++ b/eBones/lib/libkrb/get_krbrlm.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $
+ * $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_get_lrealm takes a pointer to a string, and a number, n. It fills
+ * in the string, r, with the name of the nth realm specified on the
+ * first line of the kerberos config file (KRB_CONF, defined in "krb.h").
+ * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the
+ * config file does not exist, and if n=1, a successful return will occur
+ * with r = KRB_REALM (also defined in "krb.h").
+ *
+ * NOTE: for archaic & compatibility reasons, this routine will only return
+ * valid results when n = 1.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ */
+
+krb_get_lrealm(r,n)
+ char *r;
+ int n;
+{
+ FILE *cnffile, *fopen();
+
+ if (n > 1)
+ return(KFAILURE); /* Temporary restriction */
+
+ if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+ if (n == 1) {
+ (void) strcpy(r, KRB_REALM);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+
+ if (fscanf(cnffile,"%s",r) != 1) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_phost.c b/eBones/lib/libkrb/get_phost.c
new file mode 100644
index 0000000..9b12d10
--- /dev/null
+++ b/eBones/lib/libkrb/get_phost.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $
+ * $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+
+char *index();
+
+/*
+ * This routine takes an alias for a host name and returns the first
+ * field, lower case, of its domain name. For example, if "menel" is
+ * an alias for host officially named "menelaus" (in /etc/hosts), for
+ * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
+ * is returned.
+ *
+ * This is done for historical Athena reasons: the Kerberos name of
+ * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
+ * where "host"is the lowercase for of the host name ("menelaus").
+ * This should go away: the instance should be the domain name
+ * (MENELAUS.MIT.EDU). But for now we need this routine...
+ *
+ * A pointer to the name is returned, if found, otherwise a pointer
+ * to the original "alias" argument is returned.
+ */
+
+char * krb_get_phost(alias)
+ char *alias;
+{
+ struct hostent *h;
+ char *phost = alias;
+ if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
+ char *p = index( h->h_name, '.' );
+ if (p)
+ *p = NULL;
+ p = phost = h->h_name;
+ do {
+ if (isupper(*p)) *p=tolower(*p);
+ } while (*p++);
+ }
+ return(phost);
+}
diff --git a/eBones/lib/libkrb/get_pw_tkt.c b/eBones/lib/libkrb/get_pw_tkt.c
new file mode 100644
index 0000000..48a003c
--- /dev/null
+++ b/eBones/lib/libkrb/get_pw_tkt.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $
+ * $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $";
+#endif /* lint */
+
+
+#include <krb.h>
+
+/*
+ * Get a ticket for the password-changing server ("changepw.KRB_MASTER").
+ *
+ * Given the name, instance, realm, and current password of the
+ * principal for which the user wants a password-changing-ticket,
+ * return either:
+ *
+ * GT_PW_BADPW if current password was wrong,
+ * GT_PW_NULL if principal had a NULL password,
+ * or the result of the krb_get_pw_in_tkt() call.
+ *
+ * First, try to get a ticket for "user.instance@realm" to use the
+ * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
+ * The requested lifetime for the ticket is "1", and the current
+ * password is the "cpw" argument given.
+ *
+ * If the password was bad, give up.
+ *
+ * If the principal had a NULL password in the Kerberos database
+ * (indicating that the principal is known to Kerberos, but hasn't
+ * got a password yet), try instead to get a ticket for the principal
+ * "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
+ * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL
+ * if all goes well, otherwise the error.
+ *
+ * If this routine succeeds, a ticket and session key for either the
+ * principal "user.instance@realm" or "default.changepw@realm" to use
+ * the password-changing server will be in the user's ticket file.
+ */
+
+get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ int kerror;
+
+ kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
+ KRB_MASTER, 1, cpw);
+
+ if (kerror == INTK_BADPW)
+ return(GT_PW_BADPW);
+
+ if (kerror == KDC_NULL_KEY) {
+ kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
+ KRB_MASTER,1,"changepwkrb");
+ if (kerror)
+ return(kerror);
+ return(GT_PW_NULL);
+ }
+
+ return(kerror);
+}
diff --git a/eBones/lib/libkrb/get_request.c b/eBones/lib/libkrb/get_request.c
new file mode 100644
index 0000000..131ffd5
--- /dev/null
+++ b/eBones/lib/libkrb/get_request.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $
+ * $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * This procedure is obsolete. It is used in the kerberos_slave
+ * code for Version 3 tickets.
+ *
+ * This procedure sets s_name, and instance to point to
+ * the corresponding fields from tne nth request in the packet.
+ * it returns the lifetime requested. Garbage will be returned
+ * if there are less than n requests in the packet.
+ */
+
+get_request(pkt, n, s_name, instance)
+ KTEXT pkt; /* The packet itself */
+ int n; /* Which request do we want */
+ char **s_name; /* Service name to be filled in */
+ char **instance; /* Instance name to be filled in */
+{
+ /* Go to the beginning of the request list */
+ char *ptr = (char *) pkt_a_realm(pkt) + 6 +
+ strlen((char *)pkt_a_realm(pkt));
+
+ /* Read requests until we hit the right one */
+ while (n-- > 1) {
+ ptr++;
+ ptr += 1 + strlen(ptr);
+ ptr += 1 + strlen(ptr);
+ }
+
+ /* Set the arguments to point to the right place */
+ *s_name = 1 + ptr;
+ *instance = 2 + ptr + strlen(*s_name);
+
+ /* Return the requested lifetime */
+ return((int) *ptr);
+}
diff --git a/eBones/lib/libkrb/get_svc_in_tkt.c b/eBones/lib/libkrb/get_svc_in_tkt.c
new file mode 100644
index 0000000..6d9702f
--- /dev/null
+++ b/eBones/lib/libkrb/get_svc_in_tkt.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $
+ * $Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_svc_in_tkt.c,v 1.2 1994/07/19 19:25:26 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: srvtab_to_key(), which gets
+ * a server's key from a srvtab file, and krb_get_svc_in_tkt() which
+ * gets an initial ticket for a server.
+ */
+
+/*
+ * srvtab_to_key(): given a "srvtab" file (where the keys for the
+ * service on a host are stored), return the private key of the
+ * given service (user.instance@realm).
+ *
+ * srvtab_to_key() passes its arguments on to read_service_key(),
+ * plus one additional argument, the key version number.
+ * (Currently, the key version number is always 0; this value
+ * is treated as a wildcard by read_service_key().)
+ *
+ * If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
+ * is passed in its place.
+ *
+ * It returns the return value of the read_service_key() call.
+ * The service key is placed in "key".
+ */
+
+static int srvtab_to_key(user, instance, realm, srvtab, key)
+ char *user, *instance, *realm, *srvtab;
+ C_Block key;
+{
+ if (!srvtab)
+ srvtab = KEYFILE;
+
+ return(read_service_key(user, instance, realm, 0, srvtab,
+ (char *)key));
+}
+
+/*
+ * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
+ * plus two additional arguments: a pointer to the srvtab_to_key()
+ * function to be used to get the key from the key file and a NULL
+ * for the decryption procedure indicating that krb_get_in_tkt should
+ * use the default method of decrypting the response from the KDC.
+ *
+ * It returns the return value of the krb_get_in_tkt() call.
+ */
+
+krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return(krb_get_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab_to_key, NULL, srvtab));
+}
diff --git a/eBones/lib/libkrb/get_tf_fullname.c b/eBones/lib/libkrb/get_tf_fullname.c
new file mode 100644
index 0000000..753ad1e
--- /dev/null
+++ b/eBones/lib/libkrb/get_tf_fullname.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $
+ * $Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_fullname.c,v 1.2 1994/07/19 19:25:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+#include <stdio.h>
+
+/*
+ * This file contains a routine to extract the fullname of a user
+ * from the ticket file.
+ */
+
+/*
+ * krb_get_tf_fullname() takes four arguments: the name of the
+ * ticket file, and variables for name, instance, and realm to be
+ * returned in. Since the realm of a ticket file is not really fully
+ * supported, the realm used will be that of the the first ticket in
+ * the file as this is the one that was obtained with a password by
+ * krb_get_in_tkt().
+ */
+
+krb_get_tf_fullname(ticket_file, name, instance, realm)
+ char *ticket_file;
+ char *name;
+ char *instance;
+ char *realm;
+{
+ int tf_status;
+ CREDENTIALS c;
+
+ if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
+ ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
+ return (tf_status);
+
+ if (name)
+ strcpy(name, c.pname);
+ if (instance)
+ strcpy(instance, c.pinst);
+ if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
+ if (realm)
+ strcpy(realm, c.realm);
+ }
+ else {
+ if (tf_status == EOF)
+ return(KFAILURE);
+ else
+ return(tf_status);
+ }
+ (void) tf_close();
+
+ return(tf_status);
+}
diff --git a/eBones/lib/libkrb/get_tf_realm.c b/eBones/lib/libkrb/get_tf_realm.c
new file mode 100644
index 0000000..f405dcb
--- /dev/null
+++ b/eBones/lib/libkrb/get_tf_realm.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $
+ * $Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_realm.c,v 1.2 1994/07/19 19:25:30 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * This file contains a routine to extract the realm of a kerberos
+ * ticket file.
+ */
+
+/*
+ * krb_get_tf_realm() takes two arguments: the name of a ticket
+ * and a variable to store the name of the realm in.
+ *
+ */
+
+krb_get_tf_realm(ticket_file, realm)
+ char *ticket_file;
+ char *realm;
+{
+ return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
+}
diff --git a/eBones/lib/libkrb/getrealm.c b/eBones/lib/libkrb/getrealm.c
new file mode 100644
index 0000000..96e9588
--- /dev/null
+++ b/eBones/lib/libkrb/getrealm.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * routine to convert hostname into realm name.
+ *
+ * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $
+ * $Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getrealm.c,v 1.2 1994/07/19 19:25:31 g89r4222 Exp $";
+#endif lint
+
+#include <strings.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <krb.h>
+#include <sys/param.h>
+
+/* for Ultrix and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+/*
+ * krb_realmofhost.
+ * Given a fully-qualified domain-style primary host name,
+ * return the name of the Kerberos realm for the host.
+ * If the hostname contains no discernable domain, or an error occurs,
+ * return the local realm name, as supplied by get_krbrlm().
+ * If the hostname contains a domain, but no translation is found,
+ * the hostname's domain is converted to upper-case and returned.
+ *
+ * The format of each line of the translation file is:
+ * domain_name kerberos_realm
+ * -or-
+ * host_name kerberos_realm
+ *
+ * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
+ * host names should be in the usual form (e.g. FOO.BAR.BAZ)
+ */
+
+static char ret_realm[REALM_SZ+1];
+
+char *
+krb_realmofhost(host)
+char *host;
+{
+ char *domain;
+ FILE *trans_file;
+ char trans_host[MAXHOSTNAMELEN+1];
+ char trans_realm[REALM_SZ+1];
+ int retval;
+
+ domain = index(host, '.');
+
+ /* prepare default */
+ if (domain) {
+ char *cp;
+
+ strncpy(ret_realm, &domain[1], REALM_SZ);
+ ret_realm[REALM_SZ] = '\0';
+ /* Upper-case realm */
+ for (cp = ret_realm; *cp; cp++)
+ if (islower(*cp))
+ *cp = toupper(*cp);
+ } else {
+ krb_get_lrealm(ret_realm, 1);
+ }
+
+ if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
+ /* krb_errno = KRB_NO_TRANS */
+ return(ret_realm);
+ }
+ while (1) {
+ if ((retval = fscanf(trans_file, "%s %s",
+ trans_host, trans_realm)) != 2) {
+ if (retval == EOF) {
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ continue; /* ignore broken lines */
+ }
+ trans_host[MAXHOSTNAMELEN] = '\0';
+ trans_realm[REALM_SZ] = '\0';
+ if (!strcasecmp(trans_host, host)) {
+ /* exact match of hostname, so return the realm */
+ (void) strcpy(ret_realm, trans_realm);
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ if ((trans_host[0] == '.') && domain) {
+ /* this is a domain match */
+ if (!strcasecmp(trans_host, domain)) {
+ /* domain match, save for later */
+ (void) strcpy(ret_realm, trans_realm);
+ continue;
+ }
+ }
+ }
+}
diff --git a/eBones/lib/libkrb/getst.c b/eBones/lib/libkrb/getst.c
new file mode 100644
index 0000000..edd55ec
--- /dev/null
+++ b/eBones/lib/libkrb/getst.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $
+ * $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $";
+#endif /* lint */
+
+/*
+ * getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. getst() returns the number of characters read, including
+ * the null terminator.
+ */
+
+getst(fd, s, n)
+ int fd;
+ register char *s;
+{
+ register count = n;
+ while (read(fd, s, 1) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/lib/libkrb/in_tkt.c b/eBones/lib/libkrb/in_tkt.c
new file mode 100644
index 0000000..53510da
--- /dev/null
+++ b/eBones/lib/libkrb/in_tkt.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $
+ * $Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: in_tkt.c,v 1.5 1994/09/24 14:30:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+extern int krb_debug;
+
+/*
+ * in_tkt() is used to initialize the ticket store. It creates the
+ * file to contain the tickets and writes the given user's name "pname"
+ * and instance "pinst" in the file. in_tkt() returns KSUCCESS on
+ * success, or KFAILURE if something goes wrong.
+ */
+
+in_tkt(pname,pinst)
+ char *pname;
+ char *pinst;
+{
+ int tktfile;
+ uid_t me, metoo;
+ struct stat buf;
+ int count;
+ char *file = TKT_FILE;
+ int fd;
+ register int i;
+ char charbuf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ me = getuid ();
+ metoo = geteuid();
+ if (lstat(file,&buf) == 0) {
+ if (buf.st_uid != me && me == 0) {
+ unlink(file);
+ } else {
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",file);
+ return(KFAILURE);
+ }
+ /* file already exists, and permissions appear ok, so nuke it */
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out; /* can't zero it, but we can still try truncating it */
+
+ bzero(charbuf, sizeof(charbuf));
+
+ for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+ if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+ }
+ }
+ out:
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary).
+ This isn't a security problem, since the ticket file, if it already
+ exists, has the right uid (== ruid) and mode. */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid2");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+ if (lstat(file,&buf) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ count = strlen(pname)+1;
+ if (write(tktfile,pname,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ count = strlen(pinst)+1;
+ if (write(tktfile,pinst,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ (void) close(tktfile);
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ return(krb_shm_create(shmidname));
+#else /* !TKT_SHMEM */
+ return(KSUCCESS);
+#endif /* TKT_SHMEM */
+}
diff --git a/eBones/lib/libkrb/k_gethostname.c b/eBones/lib/libkrb/k_gethostname.c
new file mode 100644
index 0000000..e5c11ca
--- /dev/null
+++ b/eBones/lib/libkrb/k_gethostname.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $
+ * $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $";
+#endif /* lint */
+
+#ifndef PC
+#ifndef BSD42
+/* teach me how to k_gethostname for your system here */
+#endif
+#endif
+
+#ifdef PC
+#include <stdio.h>
+typedef long in_name;
+#include "custom.h" /* where is this file? */
+extern get_custom();
+#define LEN 64 /* just a guess */
+#endif /* PC */
+
+/*
+ * Return the local host's name in "name", up to "namelen" characters.
+ * "name" will be null-terminated if "namelen" is big enough.
+ * The return code is 0 on success, -1 on failure. (The calling
+ * interface is identical to gethostname(2).)
+ *
+ * Currently defined for BSD 4.2 and PC. The BSD version just calls
+ * gethostname(); the PC code was taken from "kinit.c", and may or may
+ * not work.
+ */
+
+k_gethostname(name, namelen)
+ char *name;
+{
+#ifdef BSD42
+ return gethostname(name, namelen);
+#endif
+
+#ifdef PC
+ char buf[LEN];
+ char b1, b2, b3, b4;
+ register char *ptr;
+
+ get_custom(); /* should check for errors,
+ * return -1 on failure */
+ ptr = (char *) &(custom.c_me);
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr;
+ (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4);
+ if (strlen(buf) > namelen)
+ fprintf(stderr, "gethostname: namelen too small; truncating");
+ strnpcy(name, buf, namelen);
+ return 0;
+#endif
+}
diff --git a/eBones/lib/libkrb/klog.c b/eBones/lib/libkrb/klog.c
new file mode 100644
index 0000000..b530e8b
--- /dev/null
+++ b/eBones/lib/libkrb/klog.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $
+ * $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static int is_open;
+static char logtxt[1000];
+
+/*
+ * This file contains two logging routines: kset_logfile()
+ * to determine the file to which log entries should be written;
+ * and klog() to write log entries to the file.
+ */
+
+/*
+ * klog() is used to add entries to the logfile (see kset_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format" string.
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * If the given log type "type" is unknown, or if the log file
+ * cannot be opened, no entry is made to the log file.
+ *
+ * The return value is always a pointer to the formatted log
+ * text string "logtxt".
+ */
+
+char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ int type;
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ char *month_sname();
+ struct tm *tm;
+ static int logtype_array[NLOGTYPE] = {0,0};
+ static int array_initialized;
+
+ if (!(array_initialized++)) {
+ logtype_array[L_NET_ERR] = 1;
+ logtype_array[L_KRB_PERR] = 1;
+ logtype_array[L_KRB_PWARN] = 1;
+ logtype_array[L_APPL_REQ] = 1;
+ logtype_array[L_INI_REQ] = 1;
+ logtype_array[L_DEATH_REQ] = 1;
+ logtype_array[L_NTGT_INTK] = 1;
+ logtype_array[L_ERR_SEXP] = 1;
+ logtype_array[L_ERR_MKV] = 1;
+ logtype_array[L_ERR_NKY] = 1;
+ logtype_array[L_ERR_NUN] = 1;
+ logtype_array[L_ERR_UNK] = 1;
+ }
+
+ (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+
+ if (!logtype_array[type])
+ return(logtxt);
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return(logtxt);
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,"%s\n",logtxt);
+ (void) fclose(logfile);
+ return(logtxt);
+}
+
+/*
+ * kset_logfile() changes the name of the file to which
+ * messages are logged. If kset_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+kset_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
diff --git a/eBones/lib/libkrb/kname_parse.c b/eBones/lib/libkrb/kname_parse.c
new file mode 100644
index 0000000..dd5fe0b
--- /dev/null
+++ b/eBones/lib/libkrb/kname_parse.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $
+ * $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/* max size of full name */
+#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
+
+#define NAME 0 /* which field are we in? */
+#define INST 1
+#define REALM 2
+
+extern char *krb_err_txt[];
+
+/*
+ * This file contains four routines for handling Kerberos names.
+ *
+ * kname_parse() breaks a Kerberos name into its name, instance,
+ * and realm components.
+ *
+ * k_isname(), k_isinst(), and k_isrealm() check a given string to see if
+ * it's a syntactically legitimate respective part of a Kerberos name,
+ * returning 1 if it is, 0 if it isn't.
+ *
+ * Definition of "syntactically legitimate" names is according to
+ * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
+ * names", version dated 21 Dec 1987.
+ * /
+
+/*
+ * kname_parse() takes a Kerberos name "fullname" of the form:
+ *
+ * username[.instance][@realm]
+ *
+ * and returns the three components ("name", "instance", and "realm"
+ * in the example above) in the given arguments "np", "ip", and "rp".
+ *
+ * If successful, it returns KSUCCESS. If there was an error,
+ * KNAME_FMT is returned.
+ */
+
+kname_parse(np, ip, rp, fullname)
+ char *np, *ip, *rp, *fullname;
+{
+ static char buf[FULL_SZ];
+ char *rnext, *wnext; /* next char to read, write */
+ register char c;
+ int backslash;
+ int field;
+
+ backslash = 0;
+ rnext = buf;
+ wnext = np;
+ field = NAME;
+
+ if (strlen(fullname) > FULL_SZ)
+ return KNAME_FMT;
+ (void) strcpy(buf, fullname);
+
+ while (c = *rnext++) {
+ if (backslash) {
+ *wnext++ = c;
+ backslash = 0;
+ continue;
+ }
+ switch (c) {
+ case '\\':
+ backslash++;
+ break;
+ case '.':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *wnext = '\0';
+ field = INST;
+ wnext = ip;
+ break;
+ case INST:
+ return KNAME_FMT;
+ /* break; */
+ case REALM:
+ *wnext++ = c;
+ break;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ case '@':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *ip = '\0';
+ /* fall through */
+ case INST:
+ *wnext = '\0';
+ field = REALM;
+ wnext = rp;
+ break;
+ case REALM:
+ return KNAME_FMT;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ default:
+ *wnext++ = c;
+ }
+ }
+ *wnext = '\0';
+ if ((strlen(np) > ANAME_SZ - 1) ||
+ (strlen(ip) > INST_SZ - 1) ||
+ (strlen(rp) > REALM_SZ - 1))
+ return KNAME_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * k_isname() returns 1 if the given name is a syntactically legitimate
+ * Kerberos name; returns 0 if it's not.
+ */
+
+k_isname(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > ANAME_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * k_isinst() returns 1 if the given name is a syntactically legitimate
+ * Kerberos instance; returns 0 if it's not.
+ */
+
+k_isinst(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (strlen(s) > INST_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+/*
+ * k_isrealm() returns 1 if the given name is a syntactically legitimate
+ * Kerberos realm; returns 0 if it's not.
+ */
+
+k_isrealm(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > REALM_SZ - 1)
+ return 0;
+ while(c = *s++) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
diff --git a/eBones/lib/libkrb/kntoln.c b/eBones/lib/libkrb/kntoln.c
new file mode 100644
index 0000000..62ec1b5
--- /dev/null
+++ b/eBones/lib/libkrb/kntoln.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $
+ * $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_kntoln converts an auth name into a local name by looking up
+ * the auth name in the /etc/aname file. The format of the aname
+ * file is:
+ *
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | anl | inl | rll | lnl | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | 1by | 1by | 1by | 1by | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ *
+ * If the /etc/aname file can not be opened it will set the
+ * local name to the auth name. Thus, in this case it performs as
+ * the identity function.
+ *
+ * The name instance and realm are passed to krb_kntoln through
+ * the AUTH_DAT structure (ad).
+ *
+ * Now here's what it *really* does:
+ *
+ * Given a Kerberos name in an AUTH_DAT structure, check that the
+ * instance is null, and that the realm is the same as the local
+ * realm, and return the principal's name in "lname". Return
+ * KSUCCESS if all goes well, otherwise KFAILURE.
+ */
+
+krb_kntoln(ad,lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ static char lrealm[REALM_SZ] = "";
+
+ if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
+ return(KFAILURE);
+
+ if (strcmp(ad->pinst,""))
+ return(KFAILURE);
+ if (strcmp(ad->prealm,lrealm))
+ return(KFAILURE);
+ (void) strcpy(lname,ad->pname);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/kparse.c b/eBones/lib/libkrb/kparse.c
new file mode 100644
index 0000000..d79f1cf
--- /dev/null
+++ b/eBones/lib/libkrb/kparse.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Purpose:
+ * This module was developed to parse the "~/.klogin" files for
+ * Kerberos-authenticated rlogin/rcp/rsh services. However, it is
+ * general purpose and can be used to parse any such parameter file.
+ *
+ * The parameter file should consist of one or more entries, with each
+ * entry on a separate line and consisting of zero or more
+ * "keyword=value" combinations. The keyword is case insensitive, but
+ * the value is not. Any string may be enclosed in quotes, and
+ * c-style "\" literals are supported. A comma may be used to
+ * separate the k/v combinations, and multiple commas are ignored.
+ * Whitespace (blank or tab) may be used freely and is ignored.
+ *
+ * Full error processing is available. When PS_BAD_KEYWORD or
+ * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
+ * contains a meaningful error message.
+ *
+ * Keywords and their default values are programmed by an external
+ * table.
+ *
+ * Routines:
+ * fGetParameterSet() parse one line of the parameter file
+ * fGetKeywordValue() parse one "keyword=value" combo
+ * fGetToken() parse one token
+ *
+ *
+ * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
+ * $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <ctype.h>
+#include <kparse.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define void int
+
+#define MAXKEY 80
+#define MAXVALUE 80
+
+char *malloc();
+char *strcpy();
+
+int LineNbr=1; /* current line nbr in parameter file */
+char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX,
+ * or PS_BAD_KEYWORD is returned by
+ * fGetKeywordValue or fGetParameterSet */
+
+int fGetParameterSet( fp,parm,parmcount )
+ FILE *fp;
+ parmtable parm[];
+ int parmcount;
+{
+ int rc,i;
+ char keyword[MAXKEY];
+ char value[MAXVALUE];
+
+ while (TRUE) {
+ rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
+
+ switch (rc) {
+
+ case KV_EOF:
+ return(PS_EOF);
+
+ case KV_EOL:
+ return(PS_OKAY);
+
+ case KV_SYNTAX:
+ return(PS_SYNTAX);
+
+ case KV_OKAY:
+ /*
+ * got a reasonable keyword/value pair. Search the
+ * parameter table to see if we recognize the keyword; if
+ * not, return an error. If we DO recognize it, make sure
+ * it has not already been given. If not already given,
+ * save the value.
+ */
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(strutol(keyword),parm[i].keyword)==0) {
+ if (parm[i].value) {
+ sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ parm[i].value = strsave( value );
+ break;
+ }
+ }
+ if (i >= parmcount) {
+ sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ break;
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ break;
+ }
+ }
+}
+
+/*
+ * Routine: ParmCompare
+ *
+ * Purpose:
+ * ParmCompare checks a specified value for a particular keyword.
+ * fails if keyword not found or keyword found but the value was
+ * different. Like strcmp, ParmCompare returns 0 for a match found, -1
+ * otherwise
+ */
+int ParmCompare( parm, parmcount, keyword, value )
+ parmtable parm[];
+ int parmcount;
+ char *keyword;
+ char *value;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(parm[i].keyword,keyword)==0) {
+ if (parm[i].value) {
+ return(strcmp(parm[i].value,value));
+ } else {
+ return(strcmp(parm[i].defvalue,value));
+ }
+ }
+ }
+ return(-1);
+}
+
+void FreeParameterSet(parm,parmcount)
+ parmtable parm[];
+ int parmcount;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (parm[i].value) {
+ free(parm[i].value);
+ parm[i].value = (char *)NULL;
+ }
+ }
+}
+
+int fGetKeywordValue( fp, keyword, klen, value, vlen )
+ FILE *fp;
+ char *keyword;
+ int klen;
+ char *value;
+ int vlen;
+{
+ int rc;
+ int gotit;
+
+ *keyword = *value = '\0'; /* preset strings to NULL */
+
+ /*
+ * Looking for a keyword.
+ * return an exception for EOF or BAD_QSTRING
+ * ignore leading WHITEspace
+ * ignore any number of leading commas
+ * newline means we have all the parms for this
+ * statement; give an indication that there is
+ * nothing more on this line.
+ * stop looking if we find QSTRING, STRING, or NUMBER
+ * return syntax error for any other PUNKtuation
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,keyword,klen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ return(KV_EOF);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",keyword)==0) {
+ return(KV_EOL);
+ } else if (strcmp(",",keyword)!=0) {
+ sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ break;
+
+ default:
+ sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while (!gotit);
+
+ /*
+ * now we expect an equal sign.
+ * skip any whitespace
+ * stop looking if we find an equal sign
+ * anything else causes a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,
+ "expecting \'=\', found unterminated string \"%s",
+ value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("=",value)==0) {
+ gotit = TRUE;
+ } else {
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting \"=\", found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",keyword);
+ }
+ return(KV_SYNTAX);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
+ return(KV_SYNTAX);
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting \'=\', found EOF");
+ return(KV_SYNTAX);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+
+ /*
+ * got the keyword and equal sign, now get a value.
+ * ignore any whitespace
+ * any punctuation is a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting rvalue, found EOF");
+ return(KV_SYNTAX);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting rvalue, found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",value);
+ }
+ return(KV_SYNTAX);
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ return(KV_OKAY);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+ /*NOTREACHED*/
+}
+
+/*
+ * Routine Name: fGetToken
+ *
+ * Function: read the next token from the specified file.
+ * A token is defined as a group of characters
+ * terminated by a white space char (SPACE, CR,
+ * LF, FF, TAB). The token returned is stripped of
+ * both leading and trailing white space, and is
+ * terminated by a NULL terminator. An alternate
+ * definition of a token is a string enclosed in
+ * single or double quotes.
+ *
+ * Explicit Parameters:
+ * fp pointer to the input FILE
+ * dest pointer to destination buffer
+ * maxlen length of the destination buffer. The buffer
+ * length INCLUDES the NULL terminator.
+ *
+ * Implicit Parameters: stderr where the "token too long" message goes
+ *
+ * External Procedures: fgetc
+ *
+ * Side Effects: None
+ *
+ * Return Value: A token classification value, as
+ * defined in kparse.h. Note that the
+ * classification for end of file is
+ * always zero.
+ */
+int fGetToken(fp, dest, maxlen)
+ FILE *fp;
+ char *dest;
+ int maxlen;
+{
+ int ch='\0';
+ int len=0;
+ char *p = dest;
+ int digits;
+
+ ch=fGetChar(fp);
+
+ /*
+ * check for a quoted string. If found, take all characters
+ * that fit until a closing quote is found. Note that this
+ * algorithm will not behave well for a string which is too long.
+ */
+ if (ISQUOTE(ch)) {
+ int done = FALSE;
+ do {
+ ch = fGetChar(fp);
+ done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
+ ||ISQUOTE(ch));
+ if (ch=='\\')
+ ch = fGetLiteral(fp);
+ if (!done)
+ *p++ = ch;
+ else if ((ch!=EOF) && !ISQUOTE(ch))
+ fUngetChar(ch,fp);
+ } while (!done);
+ *p = '\0';
+ if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
+ return(GTOK_QSTRING);
+ }
+
+ /*
+ * Not a quoted string. If its a token character (rules are
+ * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
+ * token chars following it until we run out of space.
+ */
+ digits=TRUE;
+ if (ISTOKENCHAR(ch)) {
+ while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
+ if (!isdigit(ch)) digits=FALSE;
+ *p++ = ch;
+ len++;
+ ch = fGetChar(fp);
+ };
+ *p = '\0';
+
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ if (digits) {
+ return(GTOK_NUMBER);
+ } else {
+ return(GTOK_STRING);
+ }
+ }
+
+ /*
+ * Neither a quoted string nor a token character. Return a string
+ * with just that one character in it.
+ */
+ if (ch==EOF) {
+ return(GTOK_EOF);
+ }
+ if (!ISWHITESPACE(ch)) {
+ *p++ = ch;
+ *p='\0';
+ } else {
+ *p++ = ' '; /* white space is always the
+ * blank character */
+ *p='\0';
+ /*
+ * The character is a white space. Flush all additional white
+ * space.
+ */
+ while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
+ ;
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ return(GTOK_WHITE);
+ }
+ return(GTOK_PUNK);
+}
+
+/*
+ * fGetLiteral is called after we find a '\' in the input stream. A
+ * string of numbers following the backslash are converted to the
+ * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
+ * are all supported. If the char after the \ is not a number, we
+ * special case certain values (\n, \f, \r, \b) or return a literal
+ * otherwise (useful for \", for example).
+ */
+fGetLiteral(fp)
+ FILE *fp;
+{
+ int ch;
+ int n=0;
+ int base;
+
+ ch = fGetChar(fp);
+
+ if (!isdigit(ch)) {
+ switch (ch) {
+ case 'n': return('\n');
+ case 'f': return('\f');
+ case 'r': return('\r');
+ case 'b': return('\b');
+ default: return(ch);
+ }
+ }
+
+ /*
+ * got a number. might be decimal (no prefix), octal (prefix 0),
+ * or hexadecimal (prefix 0x). Set the base appropriately.
+ */
+ if (ch!='0') {
+ base=10; /* its a decimal number */
+ } else {
+ /*
+ * found a zero, its either hex or octal
+ */
+ ch = fGetChar(fp);
+ if ((ch!='x') && (ch!='X')) {
+ base=010;
+ } else {
+ ch = fGetChar(fp);
+ base=0x10;
+ }
+ }
+
+ switch (base) {
+
+ case 010: /* octal */
+ while (ISOCTAL(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+
+ case 10: /* decimal */
+ while (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+ case 0x10: /* hexadecimal */
+ while (isxdigit(ch)) {
+ if (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ } else {
+ n = (n*base) + toupper(ch) - 'A' + 0xA ;
+ }
+ ch = fGetChar(fp);
+ }
+ break;
+ default:
+ fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
+ exit(1);
+ break;
+ }
+ fUngetChar(ch,fp);
+ return(n);
+}
+
+/*
+ * exactly the same as ungetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fUngetChar(ch,fp)
+ int ch;
+ FILE *fp;
+{
+ if (ch=='\n') LineNbr--;
+ return(ungetc(ch,fp));
+}
+
+
+/*
+ * exactly the same as fgetc(3) except that the line number of the
+ * input file is maintained.
+ */
+fGetChar(fp)
+ FILE *fp;
+{
+ int ch = fgetc(fp);
+ if (ch=='\n') LineNbr++;
+ return(ch);
+}
+
+
+/*
+ * Routine Name: strsave
+ *
+ * Function: return a pointer to a saved copy of the
+ * input string. the copy will be allocated
+ * as large as necessary.
+ *
+ * Explicit Parameters: pointer to string to save
+ *
+ * Implicit Parameters: None
+ *
+ * External Procedures: malloc,strcpy,strlen
+ *
+ * Side Effects: None
+ *
+ * Return Value: pointer to copied string
+ *
+ */
+char * strsave(p)
+ char *p;
+{
+ return(strcpy(malloc(strlen(p)+1),p));
+}
+
+
+/*
+ * strutol changes all characters in a string to lower case, in place.
+ * the pointer to the beginning of the string is returned.
+ */
+
+char * strutol( start )
+ char *start;
+{
+ char *q;
+ for (q=start; *q; q++)
+ if (isupper(*q))
+ *q=tolower(*q);
+ return(start);
+}
+
+#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
+
+#define MAXTOKEN 100
+
+char *pgm = "gettoken";
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char *p;
+ int type;
+ FILE *fp;
+
+ if (--argc) {
+ fp = fopen(*++argv,"ra");
+ if (fp == (FILE *)NULL) {
+ fprintf(stderr,"can\'t open \"%s\"\n",*argv);
+ }
+ } else
+ fp = stdin;
+
+ p = malloc(MAXTOKEN);
+ while (type = fGetToken(fp,p,MAXTOKEN)) {
+ switch(type) {
+ case GTOK_BAD_QSTRING:
+ printf("BAD QSTRING!\t");
+ break;
+ case GTOK_EOF:
+ printf("EOF!\t");
+ break;
+ case GTOK_QSTRING:
+ printf("QSTRING\t");
+ break;
+ case GTOK_STRING:
+ printf("STRING\t");
+ break;
+ case GTOK_NUMBER:
+ printf("NUMBER\t");
+ break;
+ case GTOK_PUNK:
+ printf("PUNK\t");
+ break;
+ case GTOK_WHITE:
+ printf("WHITE\t");
+ break;
+ default:
+ printf("HUH?\t");
+ break;
+ }
+ if (*p=='\n')
+ printf("\\n\n");
+ else
+ printf("%s\n",p);
+ }
+ exit(0);
+}
+#endif
+
+#ifdef KVTEST
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,ch;
+ FILE *fp;
+ char key[MAXKEY],valu[MAXVALUE];
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
+
+ switch (rc) {
+
+ case KV_EOL:
+ printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
+ break;
+
+ case KV_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case KV_OKAY:
+ printf("%s, line %d: okay, %s=\"%s\"\n",
+ filename,LineNbr,key,valu);
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
+ break;
+ }
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
+
+#ifdef PSTEST
+
+parmtable kparm[] = {
+ /* keyword, default, found value */
+ { "user", "", (char *)NULL },
+ { "realm", "Athena", (char *)NULL },
+ { "instance", "", (char *)NULL }
+};
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,i,ch;
+ FILE *fp;
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
+
+ switch (rc) {
+
+ case PS_BAD_KEYWORD:
+ printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_OKAY:
+ printf("%s, line %d: valid parameter set found:\n",
+ filename,LineNbr-1);
+ for (i=0; i<PARMCOUNT(kparm); i++) {
+ printf("\t%s = \"%s\"\n",kparm[i].keyword,
+ (kparm[i].value ? kparm[i].value
+ : kparm[i].defvalue));
+ }
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetParameterSet\n",rc);
+ break;
+ }
+ FreeParameterSet(kparm,PARMCOUNT(kparm));
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
diff --git a/eBones/lib/libkrb/krb_err.et b/eBones/lib/libkrb/krb_err.et
new file mode 100644
index 0000000..2c6830b
--- /dev/null
+++ b/eBones/lib/libkrb/krb_err.et
@@ -0,0 +1,257 @@
+# Copyright 1987,1988 Massachusetts Institute of Technology
+# For copying and distribution information, see the file
+# "Copyright.MIT".
+#
+# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $
+# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $
+#
+ error_table krb
+
+ ec KRBET_KSUCCESS,
+ "Kerberos successful"
+
+ ec KRBET_KDC_NAME_EXP,
+ "Kerberos principal expired"
+
+ ec KRBET_KDC_SERVICE_EXP,
+ "Kerberos service expired"
+
+ ec KRBET_KDC_AUTH_EXP,
+ "Kerberos auth expired"
+
+ ec KRBET_KDC_PKT_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_P_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_S_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_BYTE_ORDER,
+ "Kerberos error: byte order unknown"
+
+ ec KRBET_KDC_PR_UNKNOWN,
+ "Kerberos principal unknown"
+
+ ec KRBET_KDC_PR_N_UNIQUE,
+ "Kerberos principal not unique"
+
+ ec KRBET_KDC_NULL_KEY,
+ "Kerberos principal has null key"
+
+ ec KRBET_KRB_RES11,
+ "Reserved 11"
+
+ ec KRBET_KRB_RES12,
+ "Reserved 12"
+
+ ec KRBET_KRB_RES13,
+ "Reserved 13"
+
+ ec KRBET_KRB_RES14,
+ "Reserved 14"
+
+ ec KRBET_KRB_RES15,
+ "Reserved 15"
+
+ ec KRBET_KRB_RES16,
+ "Reserved 16"
+
+ ec KRBET_KRB_RES17,
+ "Reserved 17"
+
+ ec KRBET_KRB_RES18,
+ "Reserved 18"
+
+ ec KRBET_KRB_RES19,
+ "Reserved 19"
+
+ ec KRBET_KDC_GEN_ERR,
+ "Generic error from Kerberos KDC"
+
+ ec KRBET_GC_TKFIL,
+ "Can't read Kerberos ticket file"
+
+ ec KRBET_GC_NOTKT,
+ "Can't find Kerberos ticket or TGT"
+
+ ec KRBET_KRB_RES23,
+ "Reserved 23"
+
+ ec KRBET_KRB_RES24,
+ "Reserved 24"
+
+ ec KRBET_KRB_RES25,
+ "Reserved 25"
+
+ ec KRBET_MK_AP_TGTEXP,
+ "Kerberos TGT Expired"
+
+ ec KRBET_KRB_RES27,
+ "Reserved 27"
+
+ ec KRBET_KRB_RES28,
+ "Reserved 28"
+
+ ec KRBET_KRB_RES29,
+ "Reserved 29"
+
+ ec KRBET_KRB_RES30,
+ "Reserved 30"
+
+ ec KRBET_RD_AP_UNDEC,
+ "Kerberos error: Can't decode authenticator"
+
+ ec KRBET_RD_AP_EXP,
+ "Kerberos ticket expired"
+
+ ec KRBET_RD_AP_NYV,
+ "Kerberos ticket not yet valid"
+
+ ec KRBET_RD_AP_REPEAT,
+ "Kerberos error: Repeated request"
+
+ ec KRBET_RD_AP_NOT_US,
+ "The kerberos ticket isn't for us"
+
+ ec KRBET_RD_AP_INCON,
+ "Kerberos request inconsistent"
+
+ ec KRBET_RD_AP_TIME,
+ "Kerberos error: delta_t too big"
+
+ ec KRBET_RD_AP_BADD,
+ "Kerberos error: incorrect net address"
+
+ ec KRBET_RD_AP_VERSION,
+ "Kerberos protocol version mismatch"
+
+ ec KRBET_RD_AP_MSG_TYPE,
+ "Kerberos error: invalid msg type"
+
+ ec KRBET_RD_AP_MODIFIED,
+ "Kerberos error: message stream modified"
+
+ ec KRBET_RD_AP_ORDER,
+ "Kerberos error: message out of order"
+
+ ec KRBET_RD_AP_UNAUTHOR,
+ "Kerberos error: unauthorized request"
+
+ ec KRBET_KRB_RES44,
+ "Reserved 44"
+
+ ec KRBET_KRB_RES45,
+ "Reserved 45"
+
+ ec KRBET_KRB_RES46,
+ "Reserved 46"
+
+ ec KRBET_KRB_RES47,
+ "Reserved 47"
+
+ ec KRBET_KRB_RES48,
+ "Reserved 48"
+
+ ec KRBET_KRB_RES49,
+ "Reserved 49"
+
+ ec KRBET_KRB_RES50,
+ "Reserved 50"
+
+ ec KRBET_GT_PW_NULL,
+ "Kerberos error: current PW is null"
+
+ ec KRBET_GT_PW_BADPW,
+ "Kerberos error: Incorrect current password"
+
+ ec KRBET_GT_PW_PROT,
+ "Kerberos protocol error"
+
+ ec KRBET_GT_PW_KDCERR,
+ "Error returned by Kerberos KDC"
+
+ ec KRBET_GT_PW_NULLTKT,
+ "Null Kerberos ticket returned by KDC"
+
+ ec KRBET_SKDC_RETRY,
+ "Kerberos error: Retry count exceeded"
+
+ ec KRBET_SKDC_CANT,
+ "Kerberos error: Can't send request"
+
+ ec KRBET_KRB_RES58,
+ "Reserved 58"
+
+ ec KRBET_KRB_RES59,
+ "Reserved 59"
+
+ ec KRBET_KRB_RES60,
+ "Reserved 60"
+
+ ec KRBET_INTK_W_NOTALL,
+ "Kerberos error: not all tickets returned"
+
+ ec KRBET_INTK_BADPW,
+ "Kerberos error: incorrect password"
+
+ ec KRBET_INTK_PROT,
+ "Kerberos error: Protocol Error"
+
+ ec KRBET_KRB_RES64,
+ "Reserved 64"
+
+ ec KRBET_KRB_RES65,
+ "Reserved 65"
+
+ ec KRBET_KRB_RES66,
+ "Reserved 66"
+
+ ec KRBET_KRB_RES67,
+ "Reserved 67"
+
+ ec KRBET_KRB_RES68,
+ "Reserved 68"
+
+ ec KRBET_KRB_RES69,
+ "Reserved 69"
+
+ ec KRBET_INTK_ERR,
+ "Other error"
+
+ ec KRBET_AD_NOTGT,
+ "Don't have Kerberos ticket-granting ticket"
+
+ ec KRBET_KRB_RES72,
+ "Reserved 72"
+
+ ec KRBET_KRB_RES73,
+ "Reserved 73"
+
+ ec KRBET_KRB_RES74,
+ "Reserved 74"
+
+ ec KRBET_KRB_RES75,
+ "Reserved 75"
+
+ ec KRBET_NO_TKT_FIL,
+ "No ticket file found"
+
+ ec KRBET_TKT_FIL_ACC,
+ "Couldn't access ticket file"
+
+ ec KRBET_TKT_FIL_LCK,
+ "Couldn't lock ticket file"
+
+ ec KRBET_TKT_FIL_FMT,
+ "Bad ticket file format"
+
+ ec KRBET_TKT_FIL_INI,
+ "tf_init not called first"
+
+ ec KRBET_KNAME_FMT,
+ "Bad Kerberos name format"
+
+ end
+
diff --git a/eBones/lib/libkrb/krb_err_txt.c b/eBones/lib/libkrb/krb_err_txt.c
new file mode 100644
index 0000000..785563f
--- /dev/null
+++ b/eBones/lib/libkrb/krb_err_txt.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $
+ * $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $";
+#endif lint
+
+/*
+ * This file contains an array of error text strings.
+ * The associated error codes (which are defined in "krb.h")
+ * follow the string in the comments at the end of each line.
+ */
+
+char *krb_err_txt[256] = {
+ "OK", /* 000 */
+ "Principal expired (kerberos)", /* 001 */
+ "Service expired (kerberos)", /* 002 */
+ "Authentication expired (kerberos)", /* 003 */
+ "Unknown protocol version number (kerberos)", /* 004 */
+ "Principal: Incorrect master key version (kerberos)", /* 005 */
+ "Service: Incorrect master key version (kerberos)", /* 006 */
+ "Bad byte order (kerberos)", /* 007 */
+ "Principal unknown (kerberos)", /* 008 */
+ "Principal not unique (kerberos)", /* 009 */
+ "Principal has null key (kerberos)", /* 010 */
+ "Reserved error message 11 (kerberos)", /* 011 */
+ "Reserved error message 12 (kerberos)", /* 012 */
+ "Reserved error message 13 (kerberos)", /* 013 */
+ "Reserved error message 14 (kerberos)", /* 014 */
+ "Reserved error message 15 (kerberos)", /* 015 */
+ "Reserved error message 16 (kerberos)", /* 016 */
+ "Reserved error message 17 (kerberos)", /* 017 */
+ "Reserved error message 18 (kerberos)", /* 018 */
+ "Reserved error message 19 (kerberos)", /* 019 */
+ "Permission Denied (kerberos)", /* 020 */
+ "Can't read ticket file (krb_get_cred)", /* 021 */
+ "Can't find ticket (krb_get_cred)", /* 022 */
+ "Reserved error message 23 (krb_get_cred)", /* 023 */
+ "Reserved error message 24 (krb_get_cred)", /* 024 */
+ "Reserved error message 25 (krb_get_cred)", /* 025 */
+ "Ticket granting ticket expired (krb_mk_req)", /* 026 */
+ "Reserved error message 27 (krb_mk_req)", /* 027 */
+ "Reserved error message 28 (krb_mk_req)", /* 028 */
+ "Reserved error message 29 (krb_mk_req)", /* 029 */
+ "Reserved error message 30 (krb_mk_req)", /* 030 */
+ "Can't decode authenticator (krb_rd_req)", /* 031 */
+ "Ticket expired (krb_rd_req)", /* 032 */
+ "Ticket issue date too far in the future (krb_rd_req)",/* 033 */
+ "Repeat request (krb_rd_req)", /* 034 */
+ "Ticket for wrong server (krb_rd_req)", /* 035 */
+ "Request inconsistent (krb_rd_req)", /* 036 */
+ "Time is out of bounds (krb_rd_req)", /* 037 */
+ "Incorrect network address (krb_rd_req)", /* 038 */
+ "Protocol version mismatch (krb_rd_req)", /* 039 */
+ "Illegal message type (krb_rd_req)", /* 040 */
+ "Message integrity error (krb_rd_req)", /* 041 */
+ "Message duplicate or out of order (krb_rd_req)", /* 042 */
+ "Unauthorized request (krb_rd_req)", /* 043 */
+ "Reserved error message 44 (krb_rd_req)", /* 044 */
+ "Reserved error message 45 (krb_rd_req)", /* 045 */
+ "Reserved error message 46 (krb_rd_req)", /* 046 */
+ "Reserved error message 47 (krb_rd_req)", /* 047 */
+ "Reserved error message 48 (krb_rd_req)", /* 048 */
+ "Reserved error message 49 (krb_rd_req)", /* 049 */
+ "Reserved error message 50 (krb_rd_req)", /* 050 */
+ "Current password is NULL (get_pw_tkt)", /* 051 */
+ "Current password incorrect (get_pw_tkt)", /* 052 */
+ "Protocol error (gt_pw_tkt)", /* 053 */
+ "Error returned by KDC (gt_pw_tkt)", /* 054 */
+ "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */
+ "Retry count exceeded (send_to_kdc)", /* 056 */
+ "Can't send request (send_to_kdc)", /* 057 */
+ "Reserved error message 58 (send_to_kdc)", /* 058 */
+ "Reserved error message 59 (send_to_kdc)", /* 059 */
+ "Reserved error message 60 (send_to_kdc)", /* 060 */
+ "Warning: Not ALL tickets returned", /* 061 */
+ "Password incorrect", /* 062 */
+ "Protocol error (get_intkt)", /* 063 */
+ "Reserved error message 64 (get_in_tkt)", /* 064 */
+ "Reserved error message 65 (get_in_tkt)", /* 065 */
+ "Reserved error message 66 (get_in_tkt)", /* 066 */
+ "Reserved error message 67 (get_in_tkt)", /* 067 */
+ "Reserved error message 68 (get_in_tkt)", /* 068 */
+ "Reserved error message 69 (get_in_tkt)", /* 069 */
+ "Generic error (get_intkt)", /* 070 */
+ "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */
+ "Reserved error message 72 (get_ad_tkt)", /* 072 */
+ "Reserved error message 73 (get_ad_tkt)", /* 073 */
+ "Reserved error message 74 (get_ad_tkt)", /* 074 */
+ "Reserved error message 75 (get_ad_tkt)", /* 075 */
+ "No ticket file (tf_util)", /* 076 */
+ "Can't access ticket file (tf_util)", /* 077 */
+ "Can't lock ticket file; try later (tf_util)", /* 078 */
+ "Bad ticket file format (tf_util)", /* 079 */
+ "Read ticket file before tf_init (tf_util)", /* 080 */
+ "Bad Kerberos name format (kname_parse)", /* 081 */
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "Generic kerberos error (kfailure)", /* 255 */
+};
diff --git a/eBones/lib/libkrb/krb_get_in_tkt.c b/eBones/lib/libkrb/krb_get_in_tkt.c
new file mode 100644
index 0000000..a37bb60
--- /dev/null
+++ b/eBones/lib/libkrb/krb_get_in_tkt.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $
+ * $Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: krb_get_in_tkt.c,v 1.2 1994/07/19 19:25:47 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+int swap_bytes;
+
+/*
+ * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
+ * and the cipher text sent from the KDC, decrypt the cipher text
+ * using the key returned by key_proc.
+ */
+
+static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+
+#ifndef NOENCRYPTION
+ /* Attempt to decrypt it */
+#endif
+
+ /* generate a key */
+
+ {
+ register int rc;
+ rc = (*key_proc)(user,instance,realm,arg,key);
+ if (rc)
+ return(rc);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length,key_s,key,DES_DECRYPT);
+#endif /* !NOENCRYPTION */
+ /* Get rid of all traces of key */
+ bzero((char *)key,sizeof(key));
+ bzero((char *)key_s,sizeof(key_s));
+
+ return(0);
+}
+
+/*
+ * krb_get_in_tkt() gets a ticket for a given principal to use a given
+ * service and stores the returned ticket and session key for future
+ * use.
+ *
+ * The "user", "instance", and "realm" arguments give the identity of
+ * the client who will use the ticket. The "service" and "sinstance"
+ * arguments give the identity of the server that the client wishes
+ * to use. (The realm of the server is the same as the Kerberos server
+ * to whom the request is sent.) The "life" argument indicates the
+ * desired lifetime of the ticket; the "key_proc" argument is a pointer
+ * to the routine used for getting the client's private key to decrypt
+ * the reply from Kerberos. The "decrypt_proc" argument is a pointer
+ * to the routine used to decrypt the reply from Kerberos; and "arg"
+ * is an argument to be passed on to the "key_proc" routine.
+ *
+ * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
+ * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned
+ * by Kerberos, then the error code it contains is returned. Other
+ * error codes returned by this routine include INTK_PROT to indicate
+ * wrong protocol version, INTK_BADPW to indicate bad password (if
+ * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
+ * the wrong server or the ticket store couldn't be initialized.
+ *
+ * The format of the message sent to Kerberos is as follows:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_KDC_REQUEST | message type
+ * HOST_BYTE_ORDER local byte order in lsb
+ * string user client's name
+ * string instance client's instance
+ * string realm client's realm
+ * 4 bytes tlocal.tv_sec timestamp in seconds
+ * 1 byte life desired lifetime
+ * string service service's name
+ * string sinstance service's instance
+ */
+
+krb_get_in_tkt(user, instance, realm, service, sinstance, life,
+ key_proc, decrypt_proc, arg)
+ char *user;
+ char *instance;
+ char *realm;
+ char *service;
+ char *sinstance;
+ int life;
+ int (*key_proc)();
+ int (*decrypt_proc)();
+ char *arg;
+{
+ KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st; /* Packet to KDC */
+ KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ int kvno; /* Kvno for session key */
+ unsigned char *v = pkt->dat; /* Prot vers no */
+ unsigned char *t = (pkt->dat+1); /* Prot msg type */
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ char rlm[REALM_SZ];
+ int lifetime;
+ int msg_byte_order;
+ int kerror;
+ unsigned long exp_date;
+ char *ptr;
+
+ struct timeval t_local;
+
+ unsigned long rep_err_code;
+
+ unsigned long kdc_time; /* KDC time */
+
+ /* BUILD REQUEST PACKET */
+
+ /* Set up the fixed part of the packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Now for the variable info */
+ (void) strcpy((char *)(pkt->dat+2),user); /* aname */
+ pkt->length = 3 + strlen(user);
+ (void) strcpy((char *)(pkt->dat+pkt->length),
+ instance); /* instance */
+ pkt->length += 1 + strlen(instance);
+ (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
+ pkt->length += 1 + strlen(realm);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ /* timestamp */
+ bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+
+ *(pkt->dat+(pkt->length)++) = (char) life;
+ (void) strcpy((char *)(pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+
+ if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION)
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
+ if (swap_bytes) swap_u_long(rep_err_code);
+ return((int)rep_err_code);
+ default:
+ return(INTK_PROT);
+ }
+
+ /* EXTRACT INFORMATION FROM RETURN PACKET */
+
+ /* get the principal's expiration date */
+ bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
+ if (swap_bytes) swap_u_long(exp_date);
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
+ return(INTK_ERR); /* no appropriate error code
+ currently defined for INTK_ */
+ /* copy information from return packet into "cip" */
+ bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
+
+ /* Attempt to decrypt the reply. */
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+ (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
+
+ ptr = (char *) cip->dat;
+
+ /* extract session key */
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's name */
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's instance */
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's realm */
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ /* extract ticket lifetime, server key version, ticket length */
+ /* be sure to avoid sign extension on lifetime! */
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
+ ptr += 3;
+
+ if ((tkt->length < 0) ||
+ ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
+ return(INTK_BADPW);
+
+ /* extract ticket itself */
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ /* initialize ticket cache */
+ if (in_tkt(user,instance) != KSUCCESS)
+ return(INTK_ERR);
+
+ /* stash ticket, session key, etc. for future use */
+ if (kerror = save_credentials(s_name, s_instance, rlm, ses,
+ lifetime, kvno, tkt, t_local.tv_sec))
+ return(kerror);
+
+ return(INTK_OK);
+}
diff --git a/eBones/lib/libkrb/krb_realmofhost.3 b/eBones/lib/libkrb/krb_realmofhost.3
new file mode 100644
index 0000000..f284069
--- /dev/null
+++ b/eBones/lib/libkrb/krb_realmofhost.3
@@ -0,0 +1,161 @@
+.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
+.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question. In order to prevent certain security attacks, this routine
+must either have
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+The configuration file is described by
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned. If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports
+.I n
+= 1. It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/eBones/lib/libkrb/krb_sendauth.3 b/eBones/lib/libkrb/krb_sendauth.3
new file mode 100644
index 0000000..f5e95b7
--- /dev/null
+++ b/eBones/lib/libkrb/krb_sendauth.3
@@ -0,0 +1,348 @@
+.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
+.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated. They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters. It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <mit-copyright.h>.
diff --git a/eBones/lib/libkrb/krb_set_tkt_string.3 b/eBones/lib/libkrb/krb_set_tkt_string.3
new file mode 100644
index 0000000..c9f3dcf
--- /dev/null
+++ b/eBones/lib/libkrb/krb_set_tkt_string.3
@@ -0,0 +1,43 @@
+.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $
+.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_set_tkt_string \- set Kerberos ticket cache file name
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+void krb_set_tkt_string(filename)
+char *filename;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_set_tkt_string
+sets the name of the file that holds the user's
+cache of Kerberos server tickets and associated session keys.
+.PP
+The string
+.I filename
+passed in is copied into local storage.
+Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
+copied in for use as the cache file name.
+.PP
+This routine should be called during initialization, before other
+Kerberos routines are called; otherwise the routines which fetch the
+ticket cache file name may be called and return an undesired ticket file
+name until this routine is called.
+.SH FILES
+.TP 20n
+/tmp/tkt[uid]
+default ticket file name, unless the environment variable KRBTKFILE is set.
+[uid] denotes the user's uid, in decimal.
+.SH SEE ALSO
+kerberos(3), setenv(3)
diff --git a/eBones/lib/libkrb/krbglue.c b/eBones/lib/libkrb/krbglue.c
new file mode 100644
index 0000000..8e864c1
--- /dev/null
+++ b/eBones/lib/libkrb/krbglue.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $
+ * $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $";
+#endif lint
+
+#ifndef NCOMPAT
+/*
+ * glue together new libraries and old clients
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "des.h"
+#include "krb.h"
+
+/* These definitions should be in krb.h, no? */
+#if defined(__HIGHC__)
+#undef __STDC__
+#endif
+#ifdef __STDC__
+extern int krb_mk_req (KTEXT, char *, char *, char *, long);
+extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *);
+extern int krb_kntoln (AUTH_DAT *, char *);
+extern int krb_set_key (char *, int);
+extern int krb_get_cred (char *, char *, char *, CREDENTIALS *);
+extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *);
+extern long krb_rd_priv (u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *, MSG_DAT *);
+extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *);
+extern long krb_rd_safe (u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *,
+ MSG_DAT *);
+extern long krb_mk_err (u_char *, long, char *);
+extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *);
+extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_pw_tkt (char *, char *, char *, char *);
+extern int krb_get_lrealm (char *, char *);
+extern int krb_realmofhost (char *);
+extern char *krb_get_phost (char *);
+extern int krb_get_krbhst (char *, char *, int);
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet (char *);
+#endif /* DEBUG */
+#else
+extern int krb_mk_req ();
+extern int krb_rd_req ();
+extern int krb_kntoln ();
+extern int krb_set_key ();
+extern int krb_get_cred ();
+extern long krb_mk_priv ();
+extern long krb_rd_priv ();
+extern long krb_mk_safe ();
+extern long krb_rd_safe ();
+extern long krb_mk_err ();
+extern int krb_rd_err ();
+extern int krb_get_pw_in_tkt ();
+extern int krb_get_svc_in_tkt ();
+extern int krb_get_pw_tkt ();
+extern int krb_get_lrealm ();
+extern int krb_realmofhost ();
+extern char *krb_get_phost ();
+extern int krb_get_krbhst ();
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet ();
+#endif /* DEBUG */
+#endif /* STDC */
+int mk_ap_req(authent, service, instance, realm, checksum)
+ KTEXT authent;
+ char *service, *instance, *realm;
+ u_long checksum;
+{
+ return krb_mk_req(authent,service,instance,realm,checksum);
+}
+
+int rd_ap_req(authent, service, instance, from_addr, ad, fn)
+ KTEXT authent;
+ char *service, *instance;
+ u_long from_addr;
+ AUTH_DAT *ad;
+ char *fn;
+{
+ return krb_rd_req(authent,service,instance,from_addr,ad,fn);
+}
+
+int an_to_ln(ad, lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ return krb_kntoln (ad,lname);
+}
+
+int set_serv_key (key, cvt)
+ char *key;
+ int cvt;
+{
+ return krb_set_key(key,cvt);
+}
+
+int get_credentials (svc,inst,rlm,cred)
+ char *svc, *inst, *rlm;
+ CREDENTIALS *cred;
+{
+ return krb_get_cred (svc, inst, rlm, cred);
+}
+
+long mk_private_msg (in,out,in_length,schedule,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver);
+}
+
+long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data);
+}
+
+long mk_safe_msg (in,out,in_length,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_safe (in,out,in_length,key,sender,receiver);
+}
+
+long rd_safe_msg (in,length,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_safe (in,length,key,sender,receiver,msg_data);
+}
+
+long mk_appl_err_msg (out,code,string)
+ u_char *out;
+ long code;
+ char *string;
+{
+ return krb_mk_err (out,code,string);
+}
+
+long rd_appl_err_msg (in,length,code,msg_data)
+ u_char *in;
+ u_long length;
+ long *code;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_err (in,length,code,msg_data);
+}
+
+int get_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return krb_get_pw_in_tkt(user,instance,realm,service,sinstance,
+ life,password);
+}
+
+int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return krb_get_svc_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab);
+}
+
+int get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ return krb_get_pw_tkt(user,instance,realm,cpw);
+}
+
+int
+get_krbrlm (r, n)
+char *r;
+int n;
+{
+ return krb_get_lream(r,n);
+}
+
+int
+krb_getrealm (host)
+{
+ return krb_realmofhost(host);
+}
+
+char *
+get_phost (host)
+char *host
+{
+ return krb_get_phost(host);
+}
+
+int
+get_krbhst (h, r, n)
+char *h;
+char *r;
+int n;
+{
+ return krb_get_krbhst(h,r,n);
+}
+#ifdef DEBUG
+struct ktext *create_death_packet(a_name)
+ char *a_name;
+{
+ return krb_create_death_packet(a_name);
+}
+#endif /* DEBUG */
+
+#if 0
+extern int krb_ck_repl ();
+
+int check_replay ()
+{
+ return krb_ck_repl ();
+}
+#endif
+#endif /* NCOMPAT */
diff --git a/eBones/lib/libkrb/kuserok.3 b/eBones/lib/libkrb/kuserok.3
new file mode 100644
index 0000000..36968ba
--- /dev/null
+++ b/eBones/lib/libkrb/kuserok.3
@@ -0,0 +1,63 @@
+.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $
+.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kuserok \- Kerberos version of ruserok
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+kuserok(kdata, localuser)
+AUTH_DAT *auth_data;
+char *localuser;
+.fi
+.ft R
+.SH DESCRIPTION
+.I kuserok
+determines whether a Kerberos principal described by the structure
+.I auth_data
+is authorized to login as user
+.I localuser
+according to the authorization file
+("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized,
+1 (one) if not authorized.
+.PP
+If there is no account for
+.I localuser
+on the local machine, authorization is not granted.
+If there is no authorization file, and the Kerberos principal described
+by
+.I auth_data
+translates to
+.I localuser
+(using
+.IR krb_kntoln (3)),
+authorization is granted.
+If the authorization file
+can't be accessed, or the file is not owned by
+.IR localuser,
+authorization is denied. Otherwise, the file is searched for
+a matching principal name, instance, and realm. If a match is found,
+authorization is granted, else authorization is denied.
+.PP
+The file entries are in the format:
+.nf
+.in +5n
+ name.instance@realm
+.in -5n
+.fi
+with one entry per line.
+.SH SEE ALSO
+kerberos(3), ruserok(3), krb_kntoln(3)
+.SH FILES
+.TP 20n
+~\fIlocaluser\fR/.klogin
+authorization list
diff --git a/eBones/lib/libkrb/kuserok.c b/eBones/lib/libkrb/kuserok.c
new file mode 100644
index 0000000..cb1f708
--- /dev/null
+++ b/eBones/lib/libkrb/kuserok.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * kuserok: check if a kerberos principal has
+ * access to a local account
+ *
+ * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $
+ * $Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kuserok.c,v 1.2 1994/07/19 19:25:50 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <strings.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "kdata", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default). Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK. If there is no authorization file, and the given Kerberos
+ * name "kdata" translates to the same name as "luser" (using
+ * krb_kntoln()), returns OK. Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK. Otherwise, the file is read for
+ * a matching principal name, instance, and realm. If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format:
+ *
+ * name.instance@realm
+ *
+ * one entry per line.
+ *
+ * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
+ * file entries. See the file "kparse.c".
+ */
+
+#ifdef ATHENA_COMPAT
+
+#include <kparse.h>
+
+/*
+ * The parmtable defines the keywords we will recognize with their
+ * default values, and keeps a pointer to the found value. The found
+ * value should be filled in with strsave(), since FreeParameterSet()
+ * will release memory for all non-NULL found strings.
+ *
+*** NOTE WELL! ***
+ *
+ * The table below is very nice, but we cannot hard-code a default for the
+ * realm: we have to get the realm via krb_get_lrealm(). Even though the
+ * default shows as "from krb_get_lrealm, below", it gets changed in
+ * kuserok to whatever krb_get_lrealm() tells us. That code assumes that
+ * the realm will be the entry number in the table below, so if you
+ * change the order of the entries below, you have to change the
+ * #definition of REALM_SCRIPT to reflect it.
+ */
+#define REALM_SUBSCRIPT 1
+parmtable kparm[] = {
+
+/* keyword default found value */
+{"user", "", (char *) NULL},
+{"realm", "see krb_get_lrealm, below", (char *) NULL},
+{"instance", "", (char *) NULL},
+};
+#define KPARMS kparm,PARMCOUNT(kparm)
+#endif ATHENA_COMPAT
+
+kuserok(kdata, luser)
+ AUTH_DAT *kdata;
+ char *luser;
+{
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+ int isok = NOTOK, rc;
+ FILE *fp;
+ char kuser[MAX_USERNAME];
+ char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char *newline;
+ int gobble;
+#ifdef ATHENA_COMPAT
+ char local_realm[REALM_SZ];
+#endif ATHENA_COMPAT
+
+ /* no account => no access */
+ if ((pwd = getpwnam(luser)) == NULL) {
+ return(NOTOK);
+ }
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, "/.klogin");
+
+ if (access(pbuf, F_OK)) { /* not accessible */
+ /*
+ * if he's trying to log in as himself, and there is no .klogin file,
+ * let him. To find out, call
+ * krb_kntoln to convert the triple in kdata to a name which we can
+ * string compare.
+ */
+ if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
+ return(OK);
+ }
+ }
+ /* open ~/.klogin */
+ if ((fp = fopen(pbuf, "r")) == NULL) {
+ return(NOTOK);
+ }
+ /*
+ * security: if the user does not own his own .klogin file,
+ * do not grant access
+ */
+ if (fstat(fileno(fp), &sbuf)) {
+ fclose(fp);
+ return(NOTOK);
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ fclose(fp);
+ return(NOTOK);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* Accept old-style .klogin files */
+
+ /*
+ * change the default realm from the hard-coded value to the
+ * accepted realm that Kerberos specifies.
+ */
+ rc = krb_get_lrealm(local_realm, 1);
+ if (rc == KSUCCESS)
+ kparm[REALM_SUBSCRIPT].defvalue = local_realm;
+ else
+ return (rc);
+
+ /* check each line */
+ while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
+ switch (rc) {
+ case PS_BAD_KEYWORD:
+ case PS_SYNTAX:
+ while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
+ break;
+
+ case PS_OKAY:
+ isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
+ ParmCompare(KPARMS, "instance", kdata->pinst) ||
+ ParmCompare(KPARMS, "realm", kdata->prealm));
+ break;
+
+ default:
+ break;
+ }
+ FreeParameterSet(kparm, PARMCOUNT(kparm));
+ }
+ /* reset the stream for parsing new-style names, if necessary */
+ rewind(fp);
+#endif ATHENA_COMPAT
+
+ /* check each line */
+ while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+ /* null-terminate the input string */
+ linebuf[BUFSIZ-1] = '\0';
+ newline = NULL;
+ /* nuke the newline if it exists */
+ if (newline = index(linebuf, '\n'))
+ *newline = '\0';
+ rc = kname_parse(principal, inst, realm, linebuf);
+ if (rc == KSUCCESS) {
+ isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
+ strncmp(kdata->pinst, inst, INST_SZ) ||
+ strncmp(kdata->prealm, realm, REALM_SZ));
+ }
+ /* clean up the rest of the line if necessary */
+ if (!newline)
+ while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+ }
+ fclose(fp);
+ return(isok);
+}
diff --git a/eBones/lib/libkrb/log.c b/eBones/lib/libkrb/log.c
new file mode 100644
index 0000000..42fccfb
--- /dev/null
+++ b/eBones/lib/libkrb/log.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $
+ * $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static is_open;
+
+/*
+ * This file contains three logging routines: set_logfile()
+ * to determine the file that log entries should be written to;
+ * and log() and new_log() to write log entries to the file.
+ */
+
+/*
+ * log() is used to add entries to the logfile (see set_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format".
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * The return value is undefined.
+ */
+
+__BEGIN_DECLS
+char *month_sname __P((int));
+__END_DECLS
+
+
+/*VARARGS1 */
+void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ struct tm *tm;
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return;
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+ fprintf(logfile,"\n");
+ (void) fclose(logfile);
+ return;
+}
+
+/*
+ * set_logfile() changes the name of the file to which
+ * messages are logged. If set_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+set_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
+
+/*
+ * new_log() appends a log entry containing the give time "t" and the
+ * string "string" to the logfile (see set_logfile() above). The file
+ * is opened once and left open. The routine returns 1 on failure, 0
+ * on success.
+ */
+
+new_log(t,string)
+ long t;
+ char *string;
+{
+ static FILE *logfile;
+
+ long time();
+ struct tm *tm;
+
+ if (!is_open) {
+ if ((logfile = fopen(log_name,"a")) == NULL) return(1);
+ is_open = 1;
+ }
+
+ if (t) {
+ tm = localtime(&t);
+
+ fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, string);
+ }
+ else {
+ fprintf(logfile,"\n%20s%s","",string);
+ }
+
+ (void) fflush(logfile);
+ return(0);
+}
diff --git a/eBones/lib/libkrb/mk_err.c b/eBones/lib/libkrb/mk_err.c
new file mode 100644
index 0000000..331cba9
--- /dev/null
+++ b/eBones/lib/libkrb/mk_err.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $
+ * $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a general purpose error reply message. It
+ * doesn't use KTEXT because application protocol may have long
+ * messages, and may want this part of buffer contiguous to other
+ * stuff.
+ *
+ * The error reply is built in "p", using the error code "e" and
+ * error text "e_string" given. The length of the error reply is
+ * returned.
+ *
+ * The error reply is in the following format:
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_ERR message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte order
+ * 4 bytes e given error code
+ * string e_string given error text
+ */
+
+long krb_mk_err(p,e,e_string)
+ u_char *p; /* Where to build error packet */
+ long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *start;
+
+ start = p;
+
+ /* Create fixed part of packet */
+ *p++ = (unsigned char) KRB_PROT_VERSION;
+ *p = (unsigned char) AUTH_MSG_APPL_ERR;
+ *p++ |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ bcopy((char *)&e,(char *)p,4); /* err code */
+ p += sizeof(e);
+ (void) strcpy((char *)p,e_string); /* err text */
+ p += strlen(e_string);
+
+ /* And return the length */
+ return p-start;
+}
diff --git a/eBones/lib/libkrb/mk_priv.c b/eBones/lib/libkrb/mk_priv.c
new file mode 100644
index 0000000..3bae4ed
--- /dev/null
+++ b/eBones/lib/libkrb/mk_priv.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'private msg', i.e.
+ * cryptographically sealed with a private session key.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT.
+ *
+ * Note-- It's too bad that it did a long int compare on the RT before.
+ *
+ * Returns either < 0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $
+ * $Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_priv.c,v 1.2 1994/07/19 19:25:56 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+
+static u_long c_length;
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+#ifndef NOENCRYTION
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+#endif
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum. Also, the protocol version
+ * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte private_msg_ver protocol version number
+ * 1 byte AUTH_MSG_PRIVATE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * 4 bytes c_length length of data
+#ifndef NOENCRYPT
+ * we encrypt from here with pcbc_encrypt
+#endif
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * 0<=n<=7 bytes pad to 8 byte multiple zeroes
+ */
+
+long krb_mk_priv(in,out,length,schedule,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /* put msg here, leave room for
+ * header! breaks if in and out
+ * (header stuff) overlap */
+ u_long length; /* of in data */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+ static u_char *c_length_ptr;
+ extern int private_msg_ver; /* in krb_rd_priv.c */
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = private_msg_ver;
+ *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+
+ /* calculate cipher length */
+ c_length_ptr = p;
+ p += sizeof(c_length);
+
+ q = p;
+
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+#ifdef NOENCRYPTION
+ /* make all the stuff contiguous for checksum */
+#else
+ /* make all the stuff contiguous for checksum and encryption */
+#endif
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok
+ * until 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+#ifdef notdef
+ /*
+ * calculate the checksum of the length, address, sequence, and
+ * inp data
+ */
+ cksum = quad_cksum(q,NULL,p-q,0,key);
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+ /* stuff checksum */
+ bcopy((char *) &cksum,(char *) p,sizeof(cksum));
+ p += sizeof(cksum);
+#endif
+
+ /*
+ * All the data have been assembled, compute length
+ */
+
+ c_length = p - q;
+ c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
+ sizeof(C_Block);
+ /* stuff the length */
+ bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return (q - out + c_length); /* resulting size */
+}
diff --git a/eBones/lib/libkrb/mk_req.c b/eBones/lib/libkrb/mk_req.c
new file mode 100644
index 0000000..bb0f097
--- /dev/null
+++ b/eBones/lib/libkrb/mk_req.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $
+ * $Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: mk_req.c,v 1.2 1994/07/19 19:25:57 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+#include <des.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+static struct timeval tv_local = { 0, 0 };
+static int lifetime = DEFAULT_TKT_LIFE;
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum. It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument. krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req. When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_REQUEST message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte ordering
+ * unsigned char kvno from ticket server's key version
+ * string realm server's realm
+ * unsigned char tl ticket length
+ * unsigned char idl request id length
+ * text ticket->dat ticket for server
+ * text req_id->dat request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos. The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string cr.pname {name, instance, and
+ * string cr.pinst realm of principal
+ * string myrealm making this request}
+ * 4 bytes checksum checksum argument given
+ * unsigned char tv_local.tf_usec time (milliseconds)
+ * 4 bytes tv_local.tv_sec time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ * all rounded up to multiple of 8.
+ */
+
+krb_mk_req(authent,service,instance,realm,checksum)
+ register KTEXT authent; /* Place to build the authenticator */
+ char *service; /* Name of the service */
+ char *instance; /* Service instance */
+ char *realm; /* Authentication domain of service */
+ long checksum; /* Checksum of data (optional) */
+{
+ static KTEXT_ST req_st; /* Temp storage for req id */
+ register KTEXT req_id = &req_st;
+ unsigned char *v = authent->dat; /* Prot version number */
+ unsigned char *t = (authent->dat+1); /* Message type */
+ unsigned char *kv = (authent->dat+2); /* Key version no */
+ unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
+ unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
+ CREDENTIALS cr; /* Credentials used by retr */
+ register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+ int retval; /* Returned by krb_get_cred */
+ static Key_schedule key_s;
+ char myrealm[REALM_SZ];
+
+ /* The fixed parts of the authenticator */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Get the ticket and move it into the authenticator */
+ if (krb_ap_req_debug)
+ printf("Realm: %s\n",realm);
+ /*
+ * Determine realm of these tickets. We will send this to the
+ * KDC from which we are requesting tickets so it knows what to
+ * with our session key.
+ */
+ if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
+ return(retval);
+
+ retval = krb_get_cred(service,instance,realm,&cr);
+
+ if (retval == RET_NOTKT) {
+ if (retval = get_ad_tkt(service,instance,realm,lifetime))
+ return(retval);
+ if (retval = krb_get_cred(service,instance,realm,&cr))
+ return(retval);
+ }
+
+ if (retval != KSUCCESS) return (retval);
+
+ if (krb_ap_req_debug)
+ printf("%s %s %s %s %s\n", service, instance, realm,
+ cr.pname, cr.pinst);
+ *kv = (unsigned char) cr.kvno;
+ (void) strcpy((char *)(authent->dat+3),realm);
+ *tl = (unsigned char) ticket->length;
+ bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
+ ticket->length);
+ authent->length = 6 + strlen(realm) + ticket->length;
+ if (krb_ap_req_debug)
+ printf("Ticket->length = %d\n",ticket->length);
+ if (krb_ap_req_debug)
+ printf("Issue date: %d\n",cr.issue_date);
+
+ /* Build request id */
+ (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
+ req_id->length = strlen(cr.pname)+1;
+ /* Principal's instance */
+ (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
+ req_id->length += strlen(cr.pinst)+1;
+ /* Authentication domain */
+ (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
+ req_id->length += strlen(myrealm)+1;
+ /* Checksum */
+ bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
+ req_id->length += 4;
+
+ /* Fill in the times on the request id */
+ (void) gettimeofday(&tv_local,(struct timezone *) 0);
+ *(req_id->dat+(req_id->length)++) =
+ (unsigned char) tv_local.tv_usec;
+ /* Time (coarse) */
+ bcopy((char *)&(tv_local.tv_sec),
+ (char *)(req_id->dat+req_id->length), 4);
+ req_id->length += 4;
+
+ /* Fill to a multiple of 8 bytes for DES */
+ req_id->length = ((req_id->length+7)/8)*8;
+
+#ifndef NOENCRYPTION
+ key_sched(cr.session,key_s);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,key_s,cr.session,ENCRYPT);
+ bzero((char *) key_s, sizeof(key_s));
+#endif /* NOENCRYPTION */
+
+ /* Copy it into the authenticator */
+ bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
+ req_id->length);
+ authent->length += req_id->length;
+ /* And set the id length */
+ *idl = (unsigned char) req_id->length;
+ /* clean up */
+ bzero((char *)req_id, sizeof(*req_id));
+
+ if (krb_ap_req_debug)
+ printf("Authent->length = %d\n",authent->length);
+ if (krb_ap_req_debug)
+ printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
+
+ return(KSUCCESS);
+}
+
+/*
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ *
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(newval)
+int newval;
+{
+ int olife = lifetime;
+
+ lifetime = newval;
+ return(olife);
+}
diff --git a/eBones/lib/libkrb/mk_safe.c b/eBones/lib/libkrb/mk_safe.c
new file mode 100644
index 0000000..567004b
--- /dev/null
+++ b/eBones/lib/libkrb/mk_safe.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'safe msg', i.e. authenticated
+ * using a private session key to seed a checksum. Msg is NOT
+ * encrypted.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT
+ *
+ * Returns either <0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $
+ * $Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_safe.c,v 1.2 1994/07/19 19:25:59 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long cksum;
+static C_Block big_cksum[2];
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key". The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_SAFE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes big_cksum quadratic checksum of
+ * above using "key"
+ */
+
+long krb_mk_safe(in,out,length,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /*
+ * put msg here, leave room for header!
+ * breaks if in and out (header stuff)
+ * overlap
+ */
+ u_long length; /* of in data */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = KRB_PROT_VERSION;
+ *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+
+ q = p; /* start for checksum stuff */
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+ /* make all the stuff contiguous for checksum */
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok until
+ * 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /*
+ * all that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+#ifdef NOENCRYPTION
+ cksum = 0;
+ bzero(big_cksum, sizeof(big_cksum));
+#else
+ cksum=quad_cksum(q,big_cksum,p-q,2,key);
+#endif
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+
+ /* stuff checksum */
+ bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
+ p += sizeof(big_cksum);
+
+ return ((long)(p - out)); /* resulting size */
+
+}
diff --git a/eBones/lib/libkrb/month_sname.c b/eBones/lib/libkrb/month_sname.c
new file mode 100644
index 0000000..e7a63ec
--- /dev/null
+++ b/eBones/lib/libkrb/month_sname.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $
+ * $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $";
+#endif /* lint */
+
+
+/*
+ * Given an integer 1-12, month_sname() returns a string
+ * containing the first three letters of the corresponding
+ * month. Returns 0 if the argument is out of range.
+ */
+
+char *month_sname(n)
+ int n;
+{
+ static char *name[] = {
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+ };
+ return((n < 1 || n > 12) ? 0 : name [n-1]);
+}
diff --git a/eBones/lib/libkrb/netread.c b/eBones/lib/libkrb/netread.c
new file mode 100644
index 0000000..eb86327
--- /dev/null
+++ b/eBones/lib/libkrb/netread.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $
+ * $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_read() reads from the file descriptor "fd" to the buffer
+ * "buf", until either 1) "len" bytes have been read or 2) cannot
+ * read anymore from "fd". It returns the number of bytes read
+ * or a read() error. (The calling interface is identical to
+ * read(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_read(fd, buf, len)
+int fd;
+register char *buf;
+register int len;
+{
+ int cc, len2 = 0;
+
+ do {
+ cc = read(fd, buf, len);
+ if (cc < 0)
+ return(cc); /* errno is already set */
+ else if (cc == 0) {
+ return(len2);
+ } else {
+ buf += cc;
+ len2 += cc;
+ len -= cc;
+ }
+ } while (len > 0);
+ return(len2);
+}
diff --git a/eBones/lib/libkrb/netwrite.c b/eBones/lib/libkrb/netwrite.c
new file mode 100644
index 0000000..5945ce0
--- /dev/null
+++ b/eBones/lib/libkrb/netwrite.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $";
+ * $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $";
+#endif lint
+
+/*
+ * krb_net_write() writes "len" bytes from "buf" to the file
+ * descriptor "fd". It returns the number of bytes written or
+ * a write() error. (The calling interface is identical to
+ * write(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_write(fd, buf, len)
+int fd;
+register char *buf;
+int len;
+{
+ int cc;
+ register int wrlen = len;
+ do {
+ cc = write(fd, buf, wrlen);
+ if (cc < 0)
+ return(cc);
+ else {
+ buf += cc;
+ wrlen -= cc;
+ }
+ } while (wrlen > 0);
+ return(len);
+}
diff --git a/eBones/lib/libkrb/one.c b/eBones/lib/libkrb/one.c
new file mode 100644
index 0000000..c0e8bc6
--- /dev/null
+++ b/eBones/lib/libkrb/one.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $
+ * $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $";
+#endif lint
+
+/*
+ * definition of variable set to 1.
+ * used in krb_conf.h to determine host byte order.
+ */
+
+int krbONE = 1;
diff --git a/eBones/lib/libkrb/pkt_cipher.c b/eBones/lib/libkrb/pkt_cipher.c
new file mode 100644
index 0000000..6ef870c
--- /dev/null
+++ b/eBones/lib/libkrb/pkt_cipher.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $
+ * $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+
+/*
+ * This routine takes a reply packet from the Kerberos ticket-granting
+ * service and returns a pointer to the beginning of the ciphertext in it.
+ *
+ * See "prot.h" for packet format.
+ */
+
+KTEXT
+pkt_cipher(packet)
+ KTEXT packet;
+{
+ unsigned char *ptr = pkt_a_realm(packet) + 6
+ + strlen((char *)pkt_a_realm(packet));
+ /* Skip a few more fields */
+ ptr += 3 + 4; /* add 4 for exp_date */
+
+ /* And return the pointer */
+ return((KTEXT) ptr);
+}
diff --git a/eBones/lib/libkrb/pkt_clen.c b/eBones/lib/libkrb/pkt_clen.c
new file mode 100644
index 0000000..23ad4c3
--- /dev/null
+++ b/eBones/lib/libkrb/pkt_clen.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $
+ * $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+extern int krb_debug;
+extern int swap_bytes;
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion. The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order. pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+pkt_clen(pkt)
+ KTEXT pkt;
+{
+ static unsigned short temp,temp2;
+ int clen = 0;
+
+ /* Start of ticket list */
+ unsigned char *ptr = pkt_a_realm(pkt) + 10
+ + strlen((char *)pkt_a_realm(pkt));
+
+ /* Finally the length */
+ bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+ if (swap_bytes) {
+ /* assume a short is 2 bytes?? */
+ swab((char *)&temp,(char *)&temp2,2);
+ temp = temp2;
+ }
+
+ clen = (int) temp;
+
+ if (krb_debug)
+ printf("Clen is %d\n",clen);
+ return(clen);
+}
diff --git a/eBones/lib/libkrb/rd_err.c b/eBones/lib/libkrb/rd_err.c
new file mode 100644
index 0000000..e73c47b
--- /dev/null
+++ b/eBones/lib/libkrb/rd_err.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg',
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $
+ * $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
+ * return the error code from the message in "code" and the text in
+ * "m_data" as follows:
+ *
+ * m_data->app_data points to the error text
+ * m_data->app_length points to the length of the error text
+ *
+ * If all goes well, return RD_AP_OK. If the version number
+ * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
+ * type message, return RD_AP_MSG_TYPE.
+ *
+ * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
+ */
+
+int
+krb_rd_err(in,in_length,code,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* of in msg */
+ long *code; /* received error code */
+ MSG_DAT *m_data;
+{
+ register u_char *p;
+ int swap_bytes = 0;
+ p = in; /* beginning of message */
+
+ if (*p++ != KRB_PROT_VERSION)
+ return(RD_AP_VERSION);
+ if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
+ return(RD_AP_MSG_TYPE);
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* safely get code */
+ bcopy((char *)p,(char *)code,sizeof(*code));
+ if (swap_bytes)
+ swap_u_long(*code);
+ p += sizeof(*code); /* skip over */
+
+ m_data->app_data = p; /* we're now at the error text
+ * message */
+ m_data->app_length = in_length;
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/rd_priv.c b/eBones/lib/libkrb/rd_priv.c
new file mode 100644
index 0000000..9adefec
--- /dev/null
+++ b/eBones/lib/libkrb/rd_priv.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'private msg', decrypting it,
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
+ * the return value is RD_AP_TIME, then either the times are too far
+ * out of synch, OR the packet was modified.
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $
+ * $Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[]=
+"$Id: rd_priv.c,v 1.2 1994/07/19 19:26:11 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long c_length;
+static int swap_bytes;
+static struct timeval local_time;
+static long delta_t;
+int private_msg_ver = KRB_PROT_VERSION;
+
+/*
+#ifdef NOENCRPYTION
+ * krb_rd_priv() checks the integrity of an
+#else
+ * krb_rd_priv() decrypts and checks the integrity of an
+#endif
+ * AUTH_MSG_PRIVATE message. Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data". The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender;
+ struct sockaddr_in *receiver;
+ MSG_DAT *m_data; /*various input/output data from msg */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+ return RD_AP_VERSION;
+ private_msg_ver = *(p-1);
+ if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+ return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* get cipher length */
+ bcopy((char *)p,(char *)&c_length,sizeof(c_length));
+ if (swap_bytes)
+ swap_u_long(c_length);
+ p += sizeof(c_length);
+ /* check for rational length so we don't go comatose */
+ if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+ return RD_AP_MODIFIED;
+
+
+ q = p; /* mark start of encrypted stuff */
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT);
+#endif
+
+ /* safely get application data length */
+ bcopy((char *) p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes)
+ swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
+ sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
+ sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
+ > in_length)
+ return RD_AP_MODIFIED;
+
+#ifndef NOENCRYPTION
+ /* we're now at the decrypted application data */
+#endif
+ m_data->app_data = p;
+
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *) p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *) p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes) swap_u_long(m_data->time_sec);
+
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ /*
+ * all that for one tiny bit!
+ * Heaven help those that talk to themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec
+ - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW)
+ return RD_AP_TIME;
+ if (krb_debug)
+ printf("\ndelta_t = %d",delta_t);
+
+ /*
+ * caller must check timestamps for proper order and
+ * replays, since server might have multiple clients
+ * each with its own timestamps and we don't assume
+ * tightly synchronized clocks.
+ */
+
+#ifdef notdef
+ bcopy((char *) p,(char *)&cksum,sizeof(cksum));
+ if (swap_bytes) swap_u_long(cksum)
+ /*
+ * calculate the checksum of the length, sequence,
+ * and input data, on the sending byte order!!
+ */
+ calc_cksum = quad_cksum(q,NULL,p-q,0,key);
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ calc_cksum, cksum);
+ if (cksum != calc_cksum)
+ return RD_AP_MODIFIED;
+#endif
+ return RD_AP_OK; /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/rd_req.c b/eBones/lib/libkrb/rd_req.c
new file mode 100644
index 0000000..22b6540
--- /dev/null
+++ b/eBones/lib/libkrb/rd_req.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $
+ * $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $";
+#endif /* lint */
+
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+
+static struct timeval t_local = { 0, 0 };
+
+/*
+ * Keep the following information around for subsequent calls
+ * to this routine by the same server using the same key.
+ */
+
+static Key_schedule serv_key; /* Key sched to decrypt ticket */
+static C_Block ky; /* Initialization vector */
+static int st_kvno; /* version number for this key */
+static char st_rlm[REALM_SZ]; /* server's realm */
+static char st_nam[ANAME_SZ]; /* service name */
+static char st_inst[INST_SZ]; /* server's instance */
+
+/*
+ * This file contains two functions. krb_set_key() takes a DES
+ * key or password string and returns a DES key (either the original
+ * key, or the password converted into a DES key) and a key schedule
+ * for it.
+ *
+ * krb_rd_req() reads an authentication request and returns information
+ * about the identity of the requestor, or an indication that the
+ * identity information was not authentic.
+ */
+
+/*
+ * krb_set_key() takes as its first argument either a DES key or a
+ * password string. The "cvt" argument indicates how the first
+ * argument "key" is to be interpreted: if "cvt" is null, "key" is
+ * taken to be a DES key; if "cvt" is non-null, "key" is taken to
+ * be a password string, and is converted into a DES key using
+ * string_to_key(). In either case, the resulting key is returned
+ * in the external static variable "ky". A key schedule is
+ * generated for "ky" and returned in the external static variable
+ * "serv_key".
+ *
+ * This routine returns the return value of des_key_sched.
+ *
+ * krb_set_key() needs to be in the same .o file as krb_rd_req() so that
+ * the key set by krb_set_key() is available in private storage for
+ * krb_rd_req().
+ */
+
+int
+krb_set_key(key,cvt)
+ char *key;
+ int cvt;
+{
+#ifdef NOENCRYPTION
+ bzero(ky, sizeof(ky));
+ return KSUCCESS;
+#else
+ if (cvt)
+ string_to_key(key,ky);
+ else
+ bcopy(key,(char *)ky,8);
+ return(des_key_sched(ky,serv_key));
+#endif
+}
+
+
+/*
+ * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
+ * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
+ * checks its integrity and returns a judgement as to the requestor's
+ * identity.
+ *
+ * The "authent" argument is a pointer to the received message.
+ * The "service" and "instance" arguments name the receiving server,
+ * and are used to get the service's ticket to decrypt the ticket
+ * in the message, and to compare against the server name inside the
+ * ticket. "from_addr" is the network address of the host from which
+ * the message was received; this is checked against the network
+ * address in the ticket. If "from_addr" is zero, the check is not
+ * performed. "ad" is an AUTH_DAT structure which is
+ * filled in with information about the sender's identity according
+ * to the authenticator and ticket sent in the message. Finally,
+ * "fn" contains the name of the file containing the server's key.
+ * (If "fn" is NULL, the server's key is assumed to have been set
+ * by krb_set_key(). If "fn" is the null string ("") the default
+ * file KEYFILE, defined in "krb.h", is used.)
+ *
+ * krb_rd_req() returns RD_AP_OK if the authentication information
+ * was genuine, or one of the following error codes (defined in
+ * "krb.h"):
+ *
+ * RD_AP_VERSION - wrong protocol version number
+ * RD_AP_MSG_TYPE - wrong message type
+ * RD_AP_UNDEC - couldn't decipher the message
+ * RD_AP_INCON - inconsistencies found
+ * RD_AP_BADD - wrong network address
+ * RD_AP_TIME - client time (in authenticator)
+ * too far off server time
+ * RD_AP_NYV - Kerberos time (in ticket) too
+ * far off server time
+ * RD_AP_EXP - ticket expired
+ *
+ * For the message format, see krb_mk_req().
+ *
+ * Mutual authentication is not implemented.
+ */
+
+krb_rd_req(authent,service,instance,from_addr,ad,fn)
+ register KTEXT authent; /* The received message */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ long from_addr; /* Net address of originating host */
+ AUTH_DAT *ad; /* Structure to be filled in */
+ char *fn; /* Filename to get keys from */
+{
+ static KTEXT_ST ticket; /* Temp storage for ticket */
+ static KTEXT tkt = &ticket;
+ static KTEXT_ST req_id_st; /* Temp storage for authenticator */
+ register KTEXT req_id = &req_id_st;
+
+ char realm[REALM_SZ]; /* Realm of issuing kerberos */
+ static Key_schedule seskey_sched; /* Key sched for session key */
+ unsigned char skey[KKEY_SZ]; /* Session key from ticket */
+ char sname[SNAME_SZ]; /* Service name from ticket */
+ char iname[INST_SZ]; /* Instance name from ticket */
+ char r_aname[ANAME_SZ]; /* Client name from authenticator */
+ char r_inst[INST_SZ]; /* Client instance from authenticator */
+ char r_realm[REALM_SZ]; /* Client realm from authenticator */
+ unsigned int r_time_ms; /* Fine time from authenticator */
+ unsigned long r_time_sec; /* Coarse time from authenticator */
+ register char *ptr; /* For stepping through */
+ unsigned long delta_t; /* Time in authenticator - local time */
+ long tkt_age; /* Age of ticket */
+ static int swap_bytes; /* Need to swap bytes? */
+ static int mutual; /* Mutual authentication requested? */
+ static unsigned char s_kvno;/* Version number of the server's key
+ * Kerberos used to encrypt ticket */
+ int status;
+
+ if (authent->length <= 0)
+ return(RD_AP_MODIFIED);
+
+ ptr = (char *) authent->dat;
+
+ /* get msg version, type and byte order, and server key version */
+
+ /* check version */
+ if (KRB_PROT_VERSION != (unsigned int) *ptr++)
+ return(RD_AP_VERSION);
+
+ /* byte order */
+ swap_bytes = 0;
+ if ((*ptr & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* check msg type */
+ mutual = 0;
+ switch (*ptr++ & ~1) {
+ case AUTH_MSG_APPL_REQUEST:
+ break;
+ case AUTH_MSG_APPL_REQUEST_MUTUAL:
+ mutual++;
+ break;
+ default:
+ return(RD_AP_MSG_TYPE);
+ }
+
+#ifdef lint
+ /* XXX mutual is set but not used; why??? */
+ /* this is a crock to get lint to shut up */
+ if (mutual)
+ mutual = 0;
+#endif /* lint */
+ s_kvno = *ptr++; /* get server key version */
+ (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
+ ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+
+ /*
+ * If "fn" is NULL, key info should already be set; don't
+ * bother with ticket file. Otherwise, check to see if we
+ * already have key info for the given server and key version
+ * (saved in the static st_* variables). If not, go get it
+ * from the ticket file. If "fn" is the null string, use the
+ * default ticket file.
+ */
+ if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
+ strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+ if (*fn == 0) fn = KEYFILE;
+ st_kvno = s_kvno;
+#ifndef NOENCRYPTION
+ if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey))
+ return(RD_AP_UNDEC);
+ if (status=krb_set_key((char *)skey,0)) return(status);
+#endif
+ (void) strcpy(st_rlm,realm);
+ (void) strcpy(st_nam,service);
+ (void) strcpy(st_inst,instance);
+ }
+
+ /* Get ticket from authenticator */
+ tkt->length = (int) *ptr++;
+ if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
+
+ if (krb_ap_req_debug)
+ log("ticket->length: %d",tkt->length);
+
+#ifndef NOENCRYPTION
+ /* Decrypt and take apart ticket */
+#endif
+
+ if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm,
+ &(ad->address),ad->session, &(ad->life),
+ &(ad->time_sec),sname,iname,ky,serv_key))
+ return(RD_AP_UNDEC);
+
+ if (krb_ap_req_debug) {
+ log("Ticket Contents.");
+ log(" Aname: %s.%s",ad->pname,
+ ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+ log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname);
+ }
+
+ /* Extract the authenticator */
+ req_id->length = (int) *(ptr++);
+ if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
+ authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
+
+#ifndef NOENCRYPTION
+ key_sched(ad->session,seskey_sched);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,seskey_sched,ad->session,DES_DECRYPT);
+#endif /* NOENCRYPTION */
+
+#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
+
+ ptr = (char *) req_id->dat;
+ (void) strcpy(r_aname,ptr); /* Authentication name */
+ ptr += strlen(r_aname)+1;
+ check_ptr();
+ (void) strcpy(r_inst,ptr); /* Authentication instance */
+ ptr += strlen(r_inst)+1;
+ check_ptr();
+ (void) strcpy(r_realm,ptr); /* Authentication name */
+ ptr += strlen(r_realm)+1;
+ check_ptr();
+ bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */
+ ptr += 4;
+ check_ptr();
+ if (swap_bytes) swap_u_long(ad->checksum);
+ r_time_ms = *(ptr++); /* Time (fine) */
+#ifdef lint
+ /* XXX r_time_ms is set but not used. why??? */
+ /* this is a crock to get lint to shut up */
+ if (r_time_ms)
+ r_time_ms = 0;
+#endif /* lint */
+ check_ptr();
+ /* assume sizeof(r_time_sec) == 4 ?? */
+ bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(r_time_sec);
+
+ /* Check for authenticity of the request */
+ if (krb_ap_req_debug)
+ log("Pname: %s %s",ad->pname,r_aname);
+ if (strcmp(ad->pname,r_aname) != 0)
+ return(RD_AP_INCON);
+ if (strcmp(ad->pinst,r_inst) != 0)
+ return(RD_AP_INCON);
+ if (krb_ap_req_debug)
+ log("Realm: %s %s",ad->prealm,r_realm);
+ if ((strcmp(ad->prealm,r_realm) != 0))
+ return(RD_AP_INCON);
+
+ if (krb_ap_req_debug)
+ log("Address: %d %d",ad->address,from_addr);
+ if (from_addr && (ad->address != from_addr))
+ return(RD_AP_BADD);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ delta_t = abs((int)(t_local.tv_sec - r_time_sec));
+ if (delta_t > CLOCK_SKEW) {
+ if (krb_ap_req_debug)
+ log("Time out of range: %d - %d = %d",
+ t_local.tv_sec,r_time_sec,delta_t);
+ return(RD_AP_TIME);
+ }
+
+ /* Now check for expiration of ticket */
+
+ tkt_age = t_local.tv_sec - ad->time_sec;
+ if (krb_ap_req_debug)
+ log("Time: %d Issue Date: %d Diff: %d Life %x",
+ t_local.tv_sec,ad->time_sec,tkt_age,ad->life);
+
+ if (t_local.tv_sec < ad->time_sec) {
+ if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW)
+ return(RD_AP_NYV);
+ }
+ else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life)
+ return(RD_AP_EXP);
+
+ /* All seems OK */
+ ad->reply.length = 0;
+
+ return(RD_AP_OK);
+}
diff --git a/eBones/lib/libkrb/rd_safe.c b/eBones/lib/libkrb/rd_safe.c
new file mode 100644
index 0000000..e500b4d
--- /dev/null
+++ b/eBones/lib/libkrb/rd_safe.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg', checking its
+ * integrity, and returning a pointer to the application data
+ * contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $
+ * $Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_safe.c,v 1.2 1994/07/19 19:26:15 g89r4222 Exp $";
+#endif /* lint */
+
+/* system include files */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static C_Block calc_cksum[2];
+static C_Block big_cksum[2];
+static int swap_bytes;
+static struct timeval local_time;
+static u_long delta_t;
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data". The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender's address */
+ struct sockaddr_in *receiver; /* receiver's address -- me */
+ MSG_DAT *m_data; /* where to put message information */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+ /* Be very conservative */
+ if (sizeof(u_long) != sizeof(struct in_addr)) {
+ fprintf(stderr,"\n\
+krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
+ exit(-1);
+ }
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION;
+ if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+
+ q = p; /* mark start of cksum stuff */
+
+ /* safely get length */
+ bcopy((char *)p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes) swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(in_length)
+ + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
+ + sizeof(big_cksum) + sizeof(src_addr)
+ + VERSION_SZ + MSG_TYPE_SZ > in_length)
+ return(RD_AP_MODIFIED);
+
+ m_data->app_data = p; /* we're now at the application data */
+
+ /* skip app data */
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *)p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
+
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *)p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes)
+ swap_u_long(m_data->time_sec);
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+ /*
+ * caller must check timestamps for proper order and replays, since
+ * server might have multiple clients each with its own timestamps
+ * and we don't assume tightly synchronized clocks.
+ */
+
+ bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
+ if (swap_bytes) swap_u_16(big_cksum);
+
+#ifdef NOENCRYPTION
+ bzero(calc_cksum, sizeof(calc_cksum));
+#else
+ quad_cksum(q,calc_cksum,p-q,2,key);
+#endif
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ (long) calc_cksum[0], (long) big_cksum[0]);
+ if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
+ return(RD_AP_MODIFIED);
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/read_service_key.c b/eBones/lib/libkrb/read_service_key.c
new file mode 100644
index 0000000..4d66710
--- /dev/null
+++ b/eBones/lib/libkrb/read_service_key.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $
+ * $Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: read_service_key.c,v 1.2 1994/07/19 19:26:16 g89r4222 Exp $";
+#endif /* lint */
+
+#include <krb.h>
+#include <stdio.h>
+#include <strings.h>
+
+/*
+ * The private keys for servers on a given host are stored in a
+ * "srvtab" file (typically "/etc/srvtab"). This routine extracts
+ * a given server's key from the file.
+ *
+ * read_service_key() takes the server's name ("service"), "instance",
+ * and "realm" and a key version number "kvno", and looks in the given
+ * "file" for the corresponding entry, and if found, returns the entry's
+ * key field in "key".
+ *
+ * If "instance" contains the string "*", then it will match
+ * any instance, and the chosen instance will be copied to that
+ * string. For this reason it is important that the there is enough
+ * space beyond the "*" to receive the entry.
+ *
+ * If "kvno" is 0, it is treated as a wild card and the first
+ * matching entry regardless of the "vno" field is returned.
+ *
+ * This routine returns KSUCCESS on success, otherwise KFAILURE.
+ *
+ * The format of each "srvtab" entry is as follows:
+ *
+ * Size Variable Field in file
+ * ---- -------- -------------
+ * string serv server name
+ * string inst server instance
+ * string realm server realm
+ * 1 byte vno server key version #
+ * 8 bytes key server's key
+ * ... ... ...
+ */
+
+
+/*ARGSUSED */
+read_service_key(service,instance,realm,kvno,file,key)
+ char *service; /* Service Name */
+ char *instance; /* Instance name or "*" */
+ char *realm; /* Realm */
+ int kvno; /* Key version number */
+ char *file; /* Filename */
+ char *key; /* Pointer to key to be filled in */
+{
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char vno; /* Key version number */
+ int wcard;
+
+ int stab, open();
+
+ if ((stab = open(file, 0, 0)) < NULL)
+ return(KFAILURE);
+
+ wcard = (instance[0] == '*') && (instance[1] == '\0');
+
+ while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
+ (void) getst(stab,inst,INST_SZ); /* Instance */
+ (void) getst(stab,rlm,REALM_SZ); /* Realm */
+ /* Vers number */
+ if (read(stab,(char *)&vno,1) != 1) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Key */
+ if (read(stab,key,8) != 8) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Is this the right service */
+ if (strcmp(serv,service))
+ continue;
+ /* How about instance */
+ if (!wcard && strcmp(inst,instance))
+ continue;
+ if (wcard)
+ (void) strncpy(instance,inst,INST_SZ);
+ /* Is this the right realm */
+#ifdef ATHENA_COMPAT
+ /* XXX For backward compatibility: if keyfile says "Athena"
+ and caller wants "ATHENA.MIT.EDU", call it a match */
+ if (strcmp(rlm,realm) &&
+ (strcmp(rlm,"Athena") ||
+ strcmp(realm,"ATHENA.MIT.EDU")))
+ continue;
+#else /* ! ATHENA_COMPAT */
+ if (strcmp(rlm,realm))
+ continue;
+#endif /* ATHENA_COMPAT */
+
+ /* How about the key version number */
+ if (kvno && kvno != (int) vno)
+ continue;
+
+ (void) close(stab);
+ return(KSUCCESS);
+ }
+
+ /* Can't find the requested service */
+ (void) close(stab);
+ return(KFAILURE);
+}
diff --git a/eBones/lib/libkrb/recvauth.c b/eBones/lib/libkrb/recvauth.c
new file mode 100644
index 0000000..fe26814
--- /dev/null
+++ b/eBones/lib/libkrb/recvauth.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $";
+ * $Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: recvauth.c,v 1.2 1994/07/19 19:26:18 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
+ chars */
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_sendauth.c
+ * be sure to support old versions of krb_sendauth!
+ */
+
+extern int errno;
+
+/*
+ * krb_recvauth() reads (and optionally responds to) a message sent
+ * using krb_sendauth(). The "options" argument is a bit-field of
+ * selected options (see "sendauth.c" for options description).
+ * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
+ * (mutual authentication requested). The "fd" argument supplies
+ * a file descriptor to read from (and write to, if mutual authenti-
+ * cation is requested).
+ *
+ * Part of the received message will be a Kerberos ticket sent by the
+ * client; this is read into the "ticket" argument. The "service" and
+ * "instance" arguments supply the server's Kerberos name. If the
+ * "instance" argument is the string "*", it is treated as a wild card
+ * and filled in during the krb_rd_req() call (see read_service_key()).
+ *
+ * The "faddr" and "laddr" give the sending (client) and receiving
+ * (local server) network addresses. ("laddr" may be left NULL unless
+ * mutual authentication is requested, in which case it must be set.)
+ *
+ * The authentication information extracted from the message is returned
+ * in "kdata". The "filename" argument indicates the file where the
+ * server's key can be found. (It is passed on to krb_rd_req().) If
+ * left null, the default "/etc/srvtab" will be used.
+ *
+ * If mutual authentication is requested, the session key schedule must
+ * be computed in order to reply; this schedule is returned in the
+ * "schedule" argument. A string containing the application version
+ * number from the received message is returned in "version", which
+ * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
+ *
+ * See krb_sendauth() for the format of the received client message.
+ *
+ * This routine supports another client format, for backward
+ * compatibility, consisting of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * string tmp_buf, tkt_len length of ticket, in
+ * ascii
+ *
+ * char ' ' (space char) separator
+ *
+ * tkt_len ticket->dat the ticket
+ *
+ * This old-style version does not support mutual authentication.
+ *
+ * krb_recvauth() first reads the protocol version string from the
+ * given file descriptor. If it doesn't match the current protocol
+ * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In
+ * that case, the string of characters up to the first space is read
+ * and interpreted as the ticket length, then the ticket is read.
+ *
+ * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
+ * next reads the application protocol version string. Then the
+ * ticket length and ticket itself are read.
+ *
+ * The ticket is decrypted and checked by the call to krb_rd_req().
+ * If no mutual authentication is required, the result of the
+ * krb_rd_req() call is retured by this routine. If mutual authenti-
+ * cation is required, a message in the following format is returned
+ * on "fd":
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 4 bytes tkt_len length of ticket or -1
+ * if error occurred
+ *
+ * priv_len tmp_buf "private" message created
+ * by krb_mk_priv() which
+ * contains the incremented
+ * checksum sent by the client
+ * encrypted in the session
+ * key. (This field is not
+ * present in case of error.)
+ *
+ * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
+ * other error code is returned.
+ */
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+int
+krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+ filename, schedule, version)
+long options; /* bit-pattern of options */
+int fd; /* file descr. to read from */
+KTEXT ticket; /* storage for client's ticket */
+char *service; /* service expected */
+char *instance; /* inst expected (may be filled in) */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+struct sockaddr_in *laddr; /* local address */
+AUTH_DAT *kdata; /* kerberos data (returned) */
+char *filename; /* name of file with service keys */
+Key_schedule schedule; /* key schedule (return) */
+char *version; /* version string (filled in) */
+{
+
+ int i, cc, old_vers = 0;
+ char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
+ char *cp;
+ int rem;
+ long tkt_len, priv_len;
+ u_long cksum;
+ u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+ /* read the protocol version number */
+ if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ krb_vers[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* check version string */
+ if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
+ /* Assume the old version of sendkerberosdata: send ascii
+ length, ' ', and ticket. */
+ if (options & KOPT_DO_MUTUAL)
+ return(KFAILURE); /* XXX can't do old style with mutual auth */
+ old_vers = 1;
+
+ /* copy what we have read into tmp_buf */
+ (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
+
+ /* search for space, and make it a null */
+ for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
+ if (tmp_buf[i]== ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+
+ if (i == KRB_SENDAUTH_VLEN)
+ /* didn't find the space, keep reading to find it */
+ for (; i<20; i++) {
+ if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
+ return(KFAILURE);
+ }
+ if (tmp_buf[i] == ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+ }
+
+ tkt_len = (long) atoi((char *) tmp_buf);
+
+ /* sanity check the length */
+ if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
+ return(KFAILURE);
+
+ if (i < KRB_SENDAUTH_VLEN) {
+ /* since we already got the space, and part of the ticket,
+ we read fewer bytes to get the rest of the ticket */
+ if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
+ (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ return(errno);
+ } else {
+ if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
+ (int) tkt_len)
+ return(errno);
+ }
+ ticket->length = tkt_len;
+ /* copy the ticket into the struct */
+ (void) bcopy(cp, (char *) ticket->dat, ticket->length);
+
+ } else {
+ /* read the application version string */
+ if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ version[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* get the length of the ticket */
+ if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+
+ /* sanity check */
+ ticket->length = ntohl((unsigned long)tkt_len);
+ if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+ if (options & KOPT_DO_MUTUAL) {
+ rem = KFAILURE;
+ goto mutual_fail;
+ } else
+ return(KFAILURE); /* XXX there may still be junk on the fd? */
+ }
+
+ /* read the ticket */
+ if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+ != ticket->length)
+ return(errno);
+ }
+ /*
+ * now have the ticket. decrypt it to get the authenticated
+ * data.
+ */
+ rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+ kdata,filename);
+
+ if (old_vers) return(rem); /* XXX can't do mutual with old client */
+
+ /* if we are doing mutual auth, compose a response */
+ if (options & KOPT_DO_MUTUAL) {
+ if (rem != KSUCCESS)
+ /* the krb_rd_req failed */
+ goto mutual_fail;
+
+ /* add one to the (formerly) sealed checksum, and re-seal it
+ for return to the client */
+ cksum = kdata->checksum + 1;
+ cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+ key_sched(kdata->session,schedule);
+#endif
+ priv_len = krb_mk_priv((unsigned char *)&cksum,
+ tmp_buf,
+ (unsigned long) sizeof(cksum),
+ schedule,
+ kdata->session,
+ laddr,
+ faddr);
+ if (priv_len < 0) {
+ /* re-sealing failed; notify the client */
+ rem = KFAILURE; /* XXX */
+mutual_fail:
+ priv_len = -1;
+ tkt_len = htonl((unsigned long) priv_len);
+ /* a length of -1 is interpreted as an authentication
+ failure by the client */
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ return(rem);
+ } else {
+ /* re-sealing succeeded, send the private message */
+ tkt_len = htonl((unsigned long)priv_len);
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+ != (int) priv_len)
+ return(cc);
+ }
+ }
+ return(rem);
+}
diff --git a/eBones/lib/libkrb/save_credentials.c b/eBones/lib/libkrb/save_credentials.c
new file mode 100644
index 0000000..129c912
--- /dev/null
+++ b/eBones/lib/libkrb/save_credentials.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $
+ * $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * This routine takes a ticket and associated info and calls
+ * tf_save_cred() to store them in the ticket cache. The peer
+ * routine for extracting a ticket and associated info from the
+ * ticket cache is krb_get_cred(). When changes are made to
+ * this routine, the corresponding changes should be made
+ * in krb_get_cred() as well.
+ *
+ * Returns KSUCCESS if all goes well, otherwise an error returned
+ * by the tf_init() or tf_save_cred() routines.
+ */
+
+save_credentials(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+ int tf_status; /* return values of the tf_util calls */
+
+ /* Open and lock the ticket file for writing */
+ if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Save credentials by appending to the ticket file */
+ tf_status = tf_save_cred(service, instance, realm, session,
+ lifetime, kvno, ticket, issue_date);
+ (void) tf_close();
+ return (tf_status);
+}
diff --git a/eBones/lib/libkrb/send_to_kdc.c b/eBones/lib/libkrb/send_to_kdc.c
new file mode 100644
index 0000000..aeaf389
--- /dev/null
+++ b/eBones/lib/libkrb/send_to_kdc.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $
+ * $Id: send_to_kdc.c,v 1.2 1994/07/19 19:26:21 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid_send_to_kdc_c[] =
+"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp ";
+#endif /* lint */
+
+#include <krb.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef lint
+#include <sys/uio.h> /* struct iovec to make lint happy */
+#endif /* lint */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <strings.h>
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+extern int errno;
+extern int krb_debug;
+
+extern char *malloc(), *calloc(), *realloc();
+
+int krb_udp_port = 0;
+
+/* CLIENT_KRB_TIMEOUT indicates the time to wait before
+ * retrying a server. It's defined in "krb.h".
+ */
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};
+static char *prog = "send_to_kdc";
+static send_recv();
+
+/*
+ * This file contains two routines, send_to_kdc() and send_recv().
+ * send_recv() is a static routine used by send_to_kdc().
+ */
+
+/*
+ * send_to_kdc() sends a message to the Kerberos authentication
+ * server(s) in the given realm and returns the reply message.
+ * The "pkt" argument points to the message to be sent to Kerberos;
+ * the "rpkt" argument will be filled in with Kerberos' reply.
+ * The "realm" argument indicates the realm of the Kerberos server(s)
+ * to transact with. If the realm is null, the local realm is used.
+ *
+ * If more than one Kerberos server is known for a given realm,
+ * different servers will be queried until one of them replies.
+ * Several attempts (retries) are made for each server before
+ * giving up entirely.
+ *
+ * If an answer was received from a Kerberos host, KSUCCESS is
+ * returned. The following errors can be returned:
+ *
+ * SKDC_CANT - can't get local realm
+ * - can't find "kerberos" in /etc/services database
+ * - can't open socket
+ * - can't bind socket
+ * - all ports in use
+ * - couldn't find any Kerberos host
+ *
+ * SKDC_RETRY - couldn't get an answer from any Kerberos server,
+ * after several retries
+ */
+
+send_to_kdc(pkt,rpkt,realm)
+ KTEXT pkt;
+ KTEXT rpkt;
+ char *realm;
+{
+ int i, f;
+ int no_host; /* was a kerberos host found? */
+ int retry;
+ int n_hosts;
+ int retval;
+ struct sockaddr_in to;
+ struct hostent *host, *hostlist;
+ char *cp;
+ char krbhst[MAX_HSTNM];
+ char lrealm[REALM_SZ];
+
+ /*
+ * If "realm" is non-null, use that, otherwise get the
+ * local realm.
+ */
+ if (realm)
+ (void) strcpy(lrealm, realm);
+ else
+ if (krb_get_lrealm(lrealm,1)) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't get local realm\n", prog);
+ return(SKDC_CANT);
+ }
+ if (krb_debug)
+ printf("lrealm is %s\n", lrealm);
+ if (krb_udp_port == 0) {
+ register struct servent *sp;
+ if ((sp = getservbyname("kerberos","udp")) == 0) {
+ if (krb_debug)
+ fprintf(stderr, "%s: Can't get kerberos/udp service\n",
+ prog);
+ return(SKDC_CANT);
+ }
+ krb_udp_port = sp->s_port;
+ if (krb_debug)
+ printf("krb_udp_port is %d\n", krb_udp_port);
+ }
+ bzero((char *)&to, S_AD_SZ);
+ hostlist = (struct hostent *) malloc(sizeof(struct hostent));
+ if (!hostlist)
+ return (/*errno */SKDC_CANT);
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"%s: Can't open socket\n", prog);
+ return(SKDC_CANT);
+ }
+ /* from now on, exit through rtn label for cleanup */
+
+ no_host = 1;
+ /* get an initial allocation */
+ n_hosts = 0;
+ for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
+ if (krb_debug) {
+ printf("Getting host entry for %s...",krbhst);
+ (void) fflush(stdout);
+ }
+ host = gethostbyname(krbhst);
+ if (krb_debug) {
+ printf("%s.\n",
+ host ? "Got it" : "Didn't get it");
+ (void) fflush(stdout);
+ }
+ if (!host)
+ continue;
+ no_host = 0; /* found at least one */
+ n_hosts++;
+ /* preserve host network address to check later
+ * (would be better to preserve *all* addresses,
+ * take care of that later)
+ */
+ hostlist = (struct hostent *)
+ realloc((char *)hostlist,
+ (unsigned)
+ sizeof(struct hostent)*(n_hosts+1));
+ if (!hostlist)
+ return /*errno */SKDC_CANT;
+ bcopy((char *)host, (char *)&hostlist[n_hosts-1],
+ sizeof(struct hostent));
+ host = &hostlist[n_hosts-1];
+ cp = malloc((unsigned)host->h_length);
+ if (!cp) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+ bcopy((char *)host->h_addr, cp, host->h_length);
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+ (or worse) only return one name ... */
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ host->h_addr_list = (char **)malloc(sizeof(char *));
+ if (!host->h_addr_list) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+#endif /* ULTRIX022 || SunOS */
+ host->h_addr = cp;
+ bzero((char *)&hostlist[n_hosts],
+ sizeof(struct hostent));
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ to.sin_port = krb_udp_port;
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ if (krb_debug) {
+ printf("Timeout, error, or wrong descriptor\n");
+ (void) fflush(stdout);
+ }
+ }
+ if (no_host) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't find any Kerberos host.\n",
+ prog);
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ /* retry each host in sequence */
+ for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
+ for (host = hostlist; host->h_name != (char *)NULL; host++) {
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ }
+ }
+ retval = SKDC_RETRY;
+rtn:
+ (void) close(f);
+ if (hostlist) {
+ register struct hostent *hp;
+ for (hp = hostlist; hp->h_name; hp++)
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ if (hp->h_addr_list) {
+#endif /* ULTRIX022 || SunOS */
+ if (hp->h_addr)
+ free(hp->h_addr);
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ free((char *)hp->h_addr_list);
+ }
+#endif /* ULTRIX022 || SunOS */
+ free((char *)hostlist);
+ }
+ return(retval);
+}
+
+/*
+ * try to send out and receive message.
+ * return 1 on success, 0 on failure
+ */
+
+static send_recv(pkt,rpkt,f,_to,addrs)
+ KTEXT pkt;
+ KTEXT rpkt;
+ int f;
+ struct sockaddr_in *_to;
+ struct hostent *addrs;
+{
+ fd_set readfds;
+ register struct hostent *hp;
+ struct sockaddr_in from;
+ int sin_size;
+ int numsent;
+
+ if (krb_debug) {
+ if (_to->sin_family == AF_INET)
+ printf("Sending message to %s...",
+ inet_ntoa(_to->sin_addr));
+ else
+ printf("Sending message...");
+ (void) fflush(stdout);
+ }
+ if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0,
+ (struct sockaddr *)_to,
+ S_AD_SZ)) != pkt->length) {
+ if (krb_debug)
+ printf("sent only %d/%d\n",numsent, pkt->length);
+ return 0;
+ }
+ if (krb_debug) {
+ printf("Sent\nWaiting for reply...");
+ (void) fflush(stdout);
+ }
+ FD_ZERO(&readfds);
+ FD_SET(f, &readfds);
+ errno = 0;
+ /* select - either recv is ready, or timeout */
+ /* see if timeout or error or wrong descriptor */
+ if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1
+ || !FD_ISSET(f, &readfds)) {
+ if (krb_debug) {
+ fprintf(stderr, "select failed: readfds=%x",
+ readfds);
+ perror("");
+ }
+ return 0;
+ }
+ sin_size = sizeof(from);
+ if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0,
+ (struct sockaddr *)&from, &sin_size)
+ < 0) {
+ if (krb_debug)
+ perror("recvfrom");
+ return 0;
+ }
+ if (krb_debug) {
+ printf("received packet from %s\n", inet_ntoa(from.sin_addr));
+ fflush(stdout);
+ }
+ for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+ if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr,
+ hp->h_length)) {
+ if (krb_debug) {
+ printf("Received it\n");
+ (void) fflush(stdout);
+ }
+ return 1;
+ }
+ if (krb_debug)
+ fprintf(stderr,
+ "packet not from %x\n",
+ hp->h_addr);
+ }
+ if (krb_debug)
+ fprintf(stderr, "%s: received packet from wrong host! (%x)\n",
+ "send_to_kdc(send_rcv)", from.sin_addr.s_addr);
+ return 0;
+}
diff --git a/eBones/lib/libkrb/sendauth.c b/eBones/lib/libkrb/sendauth.c
new file mode 100644
index 0000000..7d798bb
--- /dev/null
+++ b/eBones/lib/libkrb/sendauth.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $
+ * $Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: sendauth.c,v 1.2 1994/07/19 19:26:23 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_recvauth.c
+ */
+
+extern int errno;
+
+extern char *krb_get_phost();
+
+/*
+ * This file contains two routines: krb_sendauth() and krb_sendsrv().
+ *
+ * krb_sendauth() transmits a ticket over a file descriptor for a
+ * desired service, instance, and realm, doing mutual authentication
+ * with the server if desired.
+ *
+ * krb_sendsvc() sends a service name to a remote knetd server.
+ */
+
+/*
+ * The first argument to krb_sendauth() contains a bitfield of
+ * options (the options are defined in "krb.h"):
+ *
+ * KOPT_DONT_CANON Don't canonicalize instance as a hostname.
+ * (If this option is not chosen, krb_get_phost()
+ * is called to canonicalize it.)
+ *
+ * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos.
+ * A ticket must be supplied in the "ticket"
+ * argument.
+ * (If this option is not chosen, and there
+ * is no ticket for the given server in the
+ * ticket cache, one will be fetched using
+ * krb_mk_req() and returned in "ticket".)
+ *
+ * KOPT_DO_MUTUAL Do mutual authentication, requiring that the
+ * receiving server return the checksum+1 encrypted
+ * in the session key. The mutual authentication
+ * is done using krb_mk_priv() on the other side
+ * (see "recvauth.c") and krb_rd_priv() on this
+ * side.
+ *
+ * The "fd" argument is a file descriptor to write to the remote
+ * server on. The "ticket" argument is used to store the new ticket
+ * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
+ * chosen, the ticket must be supplied in the "ticket" argument.
+ * The "service", "inst", and "realm" arguments identify the ticket.
+ * If "realm" is null, the local realm is used.
+ *
+ * The following arguments are only needed if the KOPT_DO_MUTUAL option
+ * is chosen:
+ *
+ * The "checksum" argument is a number that the server will add 1 to
+ * to authenticate itself back to the client; the "msg_data" argument
+ * holds the returned mutual-authentication message from the server
+ * (i.e., the checksum+1); the "cred" structure is used to hold the
+ * session key of the server, extracted from the ticket file, for use
+ * in decrypting the mutual authentication message from the server;
+ * and "schedule" holds the key schedule for that decryption. The
+ * the local and server addresses are given in "laddr" and "faddr".
+ *
+ * The application protocol version number (of up to KRB_SENDAUTH_VLEN
+ * characters) is passed in "version".
+ *
+ * If all goes well, KSUCCESS is returned, otherwise some error code.
+ *
+ * The format of the message sent to the server is:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol
+ * bytes version number
+ *
+ * KRB_SENDAUTH_VLEN version application protocol
+ * bytes version number
+ *
+ * 4 bytes ticket->length length of ticket
+ *
+ * ticket->length ticket->dat ticket itself
+ */
+
+/*
+ * XXX: Note that krb_rd_priv() is coded in such a way that
+ * "msg_data->app_data" will be pointing into "priv_buf", which
+ * will disappear when krb_sendauth() returns.
+ */
+
+int
+krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
+ msg_data, cred, schedule, laddr, faddr, version)
+long options; /* bit-pattern of options */
+int fd; /* file descriptor to write onto */
+KTEXT ticket; /* where to put ticket (return); or
+ * supplied in case of KOPT_DONT_MK_REQ */
+char *service, *inst, *realm; /* service name, instance, realm */
+u_long checksum; /* checksum to include in request */
+MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */
+CREDENTIALS *cred; /* credentials (return) */
+Key_schedule schedule; /* key schedule (return) */
+struct sockaddr_in *laddr; /* local address */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+char *version; /* version string */
+{
+ int rem, i, cc;
+ char srv_inst[INST_SZ];
+ char krb_realm[REALM_SZ];
+ char buf[BUFSIZ];
+ long tkt_len;
+ u_char priv_buf[1024];
+ u_long cksum;
+
+ rem=KSUCCESS;
+
+ /* get current realm if not passed in */
+ if (!realm) {
+ rem = krb_get_lrealm(krb_realm,1);
+ if (rem != KSUCCESS)
+ return(rem);
+ realm = krb_realm;
+ }
+
+ /* copy instance into local storage, canonicalizing if desired */
+ if (options & KOPT_DONT_CANON)
+ (void) strncpy(srv_inst, inst, INST_SZ);
+ else
+ (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
+
+ /* get the ticket if desired */
+ if (!(options & KOPT_DONT_MK_REQ)) {
+ rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
+ if (rem != KSUCCESS)
+ return(rem);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* this is only for compatibility with old servers */
+ if (options & KOPT_DO_OLDSTYLE) {
+ (void) sprintf(buf,"%d ",ticket->length);
+ (void) write(fd, buf, strlen(buf));
+ (void) write(fd, (char *) ticket->dat, ticket->length);
+ return(rem);
+ }
+#endif ATHENA_COMPAT
+ /* if mutual auth, get credentials so we have service session
+ keys for decryption below */
+ if (options & KOPT_DO_MUTUAL)
+ if (cc = krb_get_cred(service, srv_inst, realm, cred))
+ return(cc);
+
+ /* zero the buffer */
+ (void) bzero(buf, BUFSIZ);
+
+ /* insert version strings */
+ (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+ (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
+
+ /* increment past vers strings */
+ i = 2*KRB_SENDAUTH_VLEN;
+
+ /* put ticket length into buffer */
+ tkt_len = htonl((unsigned long) ticket->length);
+ (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
+ i += sizeof(tkt_len);
+
+ /* put ticket into buffer */
+ (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
+ i += ticket->length;
+
+ /* write the request to the server */
+ if ((cc = krb_net_write(fd, buf, i)) != i)
+ return(cc);
+
+ /* mutual authentication, if desired */
+ if (options & KOPT_DO_MUTUAL) {
+ /* get the length of the reply */
+ if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+ tkt_len = ntohl((unsigned long)tkt_len);
+
+ /* if the length is negative, the server failed to recognize us. */
+ if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf)))
+ return(KFAILURE); /* XXX */
+ /* read the reply... */
+ if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
+ return(errno);
+
+ /* ...and decrypt it */
+#ifndef NOENCRYPTION
+ key_sched(cred->session,schedule);
+#endif
+ if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule,
+ cred->session, faddr, laddr, msg_data))
+ return(cc);
+
+ /* fetch the (modified) checksum */
+ (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
+ sizeof(cksum));
+ cksum = ntohl(cksum);
+
+ /* if it doesn't match, fail */
+ if (cksum != checksum + 1)
+ return(KFAILURE); /* XXX */
+ }
+ return(KSUCCESS);
+}
+
+#ifdef ATHENA_COMPAT
+/*
+ * krb_sendsvc
+ */
+
+int
+krb_sendsvc(fd, service)
+int fd;
+char *service;
+{
+ /* write the service name length and then the service name to
+ the fd */
+ long serv_length;
+ int cc;
+
+ serv_length = htonl((unsigned long)strlen(service));
+ if ((cc = krb_net_write(fd, (char *) &serv_length,
+ sizeof(serv_length)))
+ != sizeof(serv_length))
+ return(cc);
+ if ((cc = krb_net_write(fd, service, strlen(service)))
+ != strlen(service))
+ return(cc);
+ return(KSUCCESS);
+}
+#endif ATHENA_COMPAT
diff --git a/eBones/lib/libkrb/stime.c b/eBones/lib/libkrb/stime.c
new file mode 100644
index 0000000..c040374
--- /dev/null
+++ b/eBones/lib/libkrb/stime.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $
+ * $Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: stime.c,v 1.2 1994/07/19 19:26:25 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/time.h>
+#include <stdio.h> /* for sprintf() */
+
+/*
+ * Given a pointer to a long containing the number of seconds
+ * since the beginning of time (midnight 1 Jan 1970 GMT), return
+ * a string containing the local time in the form:
+ *
+ * "25-Jan-88 10:17:56"
+ */
+
+char *stime(t)
+ long *t;
+{
+ static char st_data[40];
+ static char *st = st_data;
+ struct tm *tm;
+ char *month_sname();
+
+ tm = localtime(t);
+ (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return st;
+}
diff --git a/eBones/lib/libkrb/tf_shm.c b/eBones/lib/libkrb/tf_shm.c
new file mode 100644
index 0000000..5548f0d
--- /dev/null
+++ b/eBones/lib/libkrb/tf_shm.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Shared memory segment functions for session keys. Derived from code
+ * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
+ *
+ * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $
+ * $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <krb.h>
+#include <des.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */
+
+extern int errno;
+extern int krb_debug;
+
+/*
+ * krb_create_shmtkt:
+ *
+ * create a shared memory segment for session keys, leaving its id
+ * in the specified filename.
+ */
+
+int
+krb_shm_create(file_name)
+char *file_name;
+{
+ int retval;
+ int shmid;
+ struct shmid_ds shm_buf;
+ FILE *sfile;
+ uid_t me, metoo, getuid(), geteuid();
+
+ (void) krb_shm_dest(file_name); /* nuke it if it exists...
+ this cleans up to make sure we
+ don't slowly lose memory. */
+
+ shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT);
+ if (shmid == -1) {
+ if (krb_debug)
+ perror("krb_shm_create shmget");
+ return(KFAILURE); /* XXX */
+ }
+ me = getuid();
+ metoo = geteuid();
+ /*
+ * now set up the buffer so that we can modify it
+ */
+ shm_buf.shm_perm.uid = me;
+ shm_buf.shm_perm.gid = getgid();
+ shm_buf.shm_perm.mode = 0600;
+ if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */
+ if (krb_debug)
+ perror("krb_shm_create shmctl");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary). */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((sfile = fopen(file_name,"w")) == 0) {
+ if (krb_debug)
+ perror("krb_shm_create file");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (fchmod(fileno(sfile),0600) < 0) {
+ if (krb_debug)
+ perror("krb_shm_create fchmod");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid2");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+
+ (void) fprintf(sfile,"%d",shmid);
+ (void) fflush(sfile);
+ (void) fclose(sfile);
+ return(KSUCCESS);
+}
+
+
+/*
+ * krb_is_diskless:
+ *
+ * check / to see if file .diskless exists. If so it is diskless.
+ * Do it this way now to avoid dependencies on a particular routine.
+ * Choose root file system since that will be private to the client.
+ */
+
+int krb_is_diskless()
+{
+ struct stat buf;
+ if (stat("/.diskless",&buf) < 0)
+ return(0);
+ else return(1);
+}
+
+/*
+ * krb_shm_dest: destroy shared memory segment with session keys, and remove
+ * file pointing to it.
+ */
+
+int krb_shm_dest(file)
+char *file;
+{
+ int shmid;
+ FILE *sfile;
+ struct stat st_buf;
+
+ if (stat(file,&st_buf) == 0) {
+ /* successful stat */
+ if ((sfile = fopen(file,"r")) == 0) {
+ if (krb_debug)
+ perror("cannot open shared memory file");
+ return(KFAILURE); /* XXX */
+ }
+ if (fscanf(sfile,"%d",&shmid) == 1) {
+ if (shmctl(shmid,IPC_RMID,0) != 0) {
+ if (krb_debug)
+ perror("krb_shm_dest: cannot delete shm segment");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ } else {
+ if (krb_debug)
+ fprintf(stderr, "bad format in shmid file\n");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ (void) fclose(sfile);
+ (void) unlink(file);
+ return(KSUCCESS);
+ } else
+ return(RET_TKFIL); /* XXX */
+}
+
+
+
diff --git a/eBones/lib/libkrb/tf_util.3 b/eBones/lib/libkrb/tf_util.3
new file mode 100644
index 0000000..3a9bc94
--- /dev/null
+++ b/eBones/lib/libkrb/tf_util.3
@@ -0,0 +1,151 @@
+.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $
+.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \
+\- Routines for manipulating a Kerberos ticket file
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+tf_init(tf_name, rw)
+char *tf_name;
+int rw;
+.PP
+.ft B
+tf_get_pname(pname)
+char *pname;
+.PP
+.ft B
+tf_get_pinst(pinst)
+char *pinst;
+.PP
+.ft B
+tf_get_cred(c)
+CREDENTIALS *c;
+.PP
+.ft B
+tf_close()
+.PP
+.fi
+.SH DESCRIPTION
+This group of routines are provided to manipulate the Kerberos tickets
+file. A ticket file has the following format:
+.nf
+.in +4
+.sp
+principal's name (null-terminated string)
+principal's instance (null-terminated string)
+CREDENTIAL_1
+CREDENTIAL_2
+ ...
+CREDENTIAL_n
+EOF
+.sp
+.in -4
+.LP
+Where "CREDENTIAL_x" consists of the following fixed-length
+fields from the CREDENTIALS structure (defined in <krb.h>):
+.nf
+.sp
+.in +4
+ char service[ANAME_SZ]
+ char instance[INST_SZ]
+ char realm[REALM_SZ]
+ des_cblock session
+ int lifetime
+ int kvno
+ KTEXT_ST ticket_st
+ long issue_date
+.in -4
+.sp
+.fi
+.PP
+.I tf_init
+must be called before the other ticket file
+routines.
+It takes the name of the ticket file to use,
+and a read/write flag as arguments.
+It tries to open the ticket file, checks the mode and if
+everything is okay, locks the file. If it's opened for
+reading, the lock is shared. If it's opened for writing,
+the lock is exclusive.
+KSUCCESS is returned if all went well, otherwise one of the
+following:
+.nf
+.sp
+NO_TKT_FIL - file wasn't there
+TKT_FIL_ACC - file was in wrong mode, etc.
+TKT_FIL_LCK - couldn't lock the file, even after a retry
+.sp
+.fi
+.PP
+The
+.I tf_get_pname
+reads the principal's name from a ticket file.
+It should only be called after tf_init has been called. The
+principal's name is filled into the
+.I pname
+parameter. If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If the principal's name was null, or EOF was encountered, or the
+name was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+.PP
+The
+.I tf_get_pinst
+reads the principal's instance from a ticket file.
+It should only be called after tf_init and tf_get_pname
+have been called.
+The principal's instance is filled into the
+.I pinst
+parameter.
+If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If EOF was encountered, or the
+name was longer than INST_SZ, TKT_FIL_FMT is returned.
+Note that, unlike the principal name, the instance name may be null.
+.PP
+The
+.I tf_get_cred
+routine reads a CREDENTIALS record from a ticket file and
+fills in the given structure.
+It should only be called after
+tf_init, tf_get_pname, and tf_get_pinst have been called.
+If all goes well, KSUCCESS is returned. Possible error codes
+are:
+.nf
+.sp
+TKT_FIL_INI - tf_init wasn't called first
+TKT_FIL_FMT - bad format
+EOF - end of file encountered
+.sp
+.fi
+.PP
+.I tf_close
+closes the ticket file and releases the lock on it.
+.SH "SEE ALSO"
+krb(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The ticket file routines have to be called in a certain order.
+.SH AUTHORS
+Jennifer Steiner, MIT Project Athena
+.br
+Bill Bryant, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1987 Massachusetts Institute of Technology
diff --git a/eBones/lib/libkrb/tf_util.c b/eBones/lib/libkrb/tf_util.c
new file mode 100644
index 0000000..a9e8551
--- /dev/null
+++ b/eBones/lib/libkrb/tf_util.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $
+ * $Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_util.c,v 1.2 1994/07/19 19:26:28 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <krb.h>
+
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* TKT_SHMEM */
+
+#define TOO_BIG -1
+#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before
+ * retry if ticket file is
+ * locked */
+extern errno;
+extern int krb_debug;
+
+#ifdef TKT_SHMEM
+char *krb_shm_addr = 0;
+static char *tmp_shm_addr = 0;
+static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};
+
+char *shmat();
+#endif /* TKT_SHMEM */
+
+/*
+ * fd must be initialized to something that won't ever occur as a real
+ * file descriptor. Since open(2) returns only non-negative numbers as
+ * valid file descriptors, and tf_init always stuffs the return value
+ * from open in here even if it is an error flag, we must
+ * a. Initialize fd to a negative number, to indicate that it is
+ * not initially valid.
+ * b. When checking for a valid fd, assume that negative values
+ * are invalid (ie. when deciding whether tf_init has been
+ * called.)
+ * c. In tf_close, be sure it gets reinitialized to a negative
+ * number.
+ */
+static fd = -1;
+static curpos; /* Position in tfbfr */
+static lastpos; /* End of tfbfr */
+static char tfbfr[BUFSIZ]; /* Buffer for ticket data */
+
+static tf_gets(), tf_read();
+
+/*
+ * This file contains routines for manipulating the ticket cache file.
+ *
+ * The ticket file is in the following format:
+ *
+ * principal's name (null-terminated string)
+ * principal's instance (null-terminated string)
+ * CREDENTIAL_1
+ * CREDENTIAL_2
+ * ...
+ * CREDENTIAL_n
+ * EOF
+ *
+ * Where "CREDENTIAL_x" consists of the following fixed-length
+ * fields from the CREDENTIALS structure (see "krb.h"):
+ *
+ * char service[ANAME_SZ]
+ * char instance[INST_SZ]
+ * char realm[REALM_SZ]
+ * C_Block session
+ * int lifetime
+ * int kvno
+ * KTEXT_ST ticket_st
+ * long issue_date
+ *
+ * Short description of routines:
+ *
+ * tf_init() opens the ticket file and locks it.
+ *
+ * tf_get_pname() returns the principal's name.
+ *
+ * tf_get_pinst() returns the principal's instance (may be null).
+ *
+ * tf_get_cred() returns the next CREDENTIALS record.
+ *
+ * tf_save_cred() appends a new CREDENTIAL record to the ticket file.
+ *
+ * tf_close() closes the ticket file and releases the lock.
+ *
+ * tf_gets() returns the next null-terminated string. It's an internal
+ * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred().
+ *
+ * tf_read() reads a given number of bytes. It's an internal routine
+ * used by tf_get_cred().
+ */
+
+/*
+ * tf_init() should be called before the other ticket file routines.
+ * It takes the name of the ticket file to use, "tf_name", and a
+ * read/write flag "rw" as arguments.
+ *
+ * It tries to open the ticket file, checks the mode, and if everything
+ * is okay, locks the file. If it's opened for reading, the lock is
+ * shared. If it's opened for writing, the lock is exclusive.
+ *
+ * Returns KSUCCESS if all went well, otherwise one of the following:
+ *
+ * NO_TKT_FIL - file wasn't there
+ * TKT_FIL_ACC - file was in wrong mode, etc.
+ * TKT_FIL_LCK - couldn't lock the file, even after a retry
+ */
+
+tf_init(tf_name, rw)
+ char *tf_name;
+{
+ int wflag;
+ uid_t me, getuid();
+ struct stat stat_buf;
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+ FILE *sfp;
+ int shmid;
+#endif
+
+ switch (rw) {
+ case R_TKT_FIL:
+ wflag = 0;
+ break;
+ case W_TKT_FIL:
+ wflag = 1;
+ break;
+ default:
+ if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");
+ return TKT_FIL_ACC;
+ }
+ if (lstat(tf_name, &stat_buf) < 0)
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ me = getuid();
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, tf_name);
+ (void) strcat(shmidname, ".shm");
+ if (stat(shmidname,&stat_buf) < 0)
+ return(TKT_FIL_ACC);
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#endif /* TKT_SHMEM */
+
+ /*
+ * If "wflag" is set, open the ticket file in append-writeonly mode
+ * and lock the ticket file in exclusive mode. If unable to lock
+ * the file, sleep and try again. If we fail again, return with the
+ * proper error message.
+ */
+
+ curpos = sizeof(tfbfr);
+
+#ifdef TKT_SHMEM
+ sfp = fopen(shmidname, "r"); /* only need read/write on the
+ actual tickets */
+ if (sfp == 0)
+ return TKT_FIL_ACC;
+ shmid = -1;
+ {
+ char buf[BUFSIZ];
+ int val; /* useful for debugging fscanf */
+ /* We provide our own buffer here since some STDIO libraries
+ barf on unbuffered input with fscanf() */
+
+ setbuf(sfp, buf);
+ if ((val = fscanf(sfp,"%d",&shmid)) != 1) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ if (shmid < 0) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ (void) fclose(sfp);
+ }
+ /*
+ * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and
+ * attach the same segment twice so we need this check.
+ */
+ if (!krb_shm_addr) {
+ if ((krb_shm_addr = shmat(shmid,0,0)) == -1){
+ if (krb_debug)
+ fprintf(stderr,
+ "cannot attach shared memory for segment %d\n",
+ shmid);
+ krb_shm_addr = 0; /* reset so we catch further errors */
+ return TKT_FIL_ACC;
+ }
+ }
+ tmp_shm_addr = krb_shm_addr;
+#endif /* TKT_SHMEM */
+
+ if (wflag) {
+ fd = open(tf_name, O_RDWR, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+ }
+ /*
+ * Otherwise "wflag" is not set and the ticket file should be opened
+ * for read-only operations and locked for shared access.
+ */
+
+ fd = open(tf_name, O_RDONLY, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pname() reads the principal's name from the ticket file. It
+ * should only be called after tf_init() has been called. The
+ * principal's name is filled into the "p" parameter. If all goes well,
+ * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is
+ * returned. If the name was null, or EOF was encountered, or the name
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+ */
+
+tf_get_pname(p)
+ char *p;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pname called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pinst() reads the principal's instance from a ticket file.
+ * It should only be called after tf_init() and tf_get_pname() have been
+ * called. The instance is filled into the "inst" parameter. If all
+ * goes well, KSUCCESS is returned. If tf_init() wasn't called,
+ * TKT_FIL_INI is returned. If EOF was encountered, or the instance
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the
+ * instance may be null.
+ */
+
+tf_get_pinst(inst)
+ char *inst;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pinst called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(inst, INST_SZ) < 1)
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills
+ * in the given structure "c". It should only be called after tf_init(),
+ * tf_get_pname(), and tf_get_pinst() have been called. If all goes well,
+ * KSUCCESS is returned. Possible error codes are:
+ *
+ * TKT_FIL_INI - tf_init wasn't called first
+ * TKT_FIL_FMT - bad format
+ * EOF - end of file encountered
+ */
+
+tf_get_cred(c)
+ CREDENTIALS *c;
+{
+ KTEXT ticket = &c->ticket_st; /* pointer to ticket */
+ int k_errno;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
+ switch (k_errno) {
+ case TOO_BIG:
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if (
+ tf_read((char *) (c->session), KEY_SZ) < 1 ||
+ tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
+ tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 ||
+ tf_read((char *) &(ticket->length), sizeof(ticket->length))
+ < 1 ||
+ /* don't try to read a silly amount into ticket->dat */
+ ticket->length > MAX_KTXT_LEN ||
+ tf_read((char *) (ticket->dat), ticket->length) < 1 ||
+ tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
+ ) {
+ tf_close();
+ return TKT_FIL_FMT;
+ }
+#ifdef TKT_SHMEM
+ bcopy(tmp_shm_addr,c->session,KEY_SZ);
+ tmp_shm_addr += KEY_SZ;
+#endif /* TKT_SHMEM */
+ return KSUCCESS;
+}
+
+/*
+ * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is
+ * not a valid file descriptor, it just returns. It also clears the
+ * buffer used to read tickets.
+ *
+ * The return value is not defined.
+ */
+
+tf_close()
+{
+ if (!(fd < 0)) {
+#ifdef TKT_SHMEM
+ if (shmdt(krb_shm_addr)) {
+ /* what kind of error? */
+ if (krb_debug)
+ fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno);
+ } else {
+ krb_shm_addr = 0;
+ }
+#endif TKT_SHMEM
+ (void) flock(fd, LOCK_UN);
+ (void) close(fd);
+ fd = -1; /* see declaration of fd above */
+ }
+ bzero(tfbfr, sizeof(tfbfr));
+}
+
+/*
+ * tf_gets() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until either it has read "n" characters,
+ * or until it reads a null byte. When finished, what has been read exists
+ * in "s". If it encounters EOF or an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read (including null terminator)
+ * when all goes well
+ *
+ * 0 end of file or read error
+ *
+ * TOO_BIG if "count" characters are read and no null is
+ * encountered. This is an indication that the ticket
+ * file is seriously ill.
+ */
+
+static
+tf_gets(s, n)
+ register char *s;
+{
+ register count;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_gets called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ for (count = n - 1; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s = tfbfr[curpos++];
+ if (*s++ == '\0')
+ return (n - count);
+ }
+ tf_close();
+ return TOO_BIG;
+}
+
+/*
+ * tf_read() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until "n" bytes have been read. When
+ * finished, what has been read exists in "s". If it encounters EOF or
+ * an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read when all goes well
+ *
+ * 0 on end of file or read error
+ */
+
+static
+tf_read(s, n)
+ register char *s;
+ register n;
+{
+ register count;
+
+ for (count = n; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s++ = tfbfr[curpos++];
+ }
+ return n;
+}
+
+char *tkt_string();
+
+/*
+ * tf_save_cred() appends an incoming ticket to the end of the ticket
+ * file. You must call tf_init() before calling tf_save_cred().
+ *
+ * The "service", "instance", and "realm" arguments specify the
+ * server's name; "session" contains the session key to be used with
+ * the ticket; "kvno" is the server key version number in which the
+ * ticket is encrypted, "ticket" contains the actual ticket, and
+ * "issue_date" is the time the ticket was requested (local host's time).
+ *
+ * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't
+ * called previously, and KFAILURE for anything else that went wrong.
+ */
+
+tf_save_cred(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+
+ off_t lseek();
+ int count; /* count for write */
+#ifdef TKT_SHMEM
+ int *skey_check;
+#endif /* TKT_SHMEM */
+
+ if (fd < 0) { /* fd is ticket file as set by tf_init */
+ if (krb_debug)
+ fprintf(stderr, "tf_save_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ /* Find the end of the ticket file */
+ (void) lseek(fd, 0L, 2);
+#ifdef TKT_SHMEM
+ /* scan to end of existing keys: pick first 'empty' slot.
+ we assume that no real keys will be completely zero (it's a weak
+ key under DES) */
+
+ skey_check = (int *) krb_shm_addr;
+
+ while (*skey_check && *(skey_check+1))
+ skey_check += 2;
+ tmp_shm_addr = (char *)skey_check;
+#endif /* TKT_SHMEM */
+
+ /* Write the ticket and associated data */
+ /* Service */
+ count = strlen(service) + 1;
+ if (write(fd, service, count) != count)
+ goto bad;
+ /* Instance */
+ count = strlen(instance) + 1;
+ if (write(fd, instance, count) != count)
+ goto bad;
+ /* Realm */
+ count = strlen(realm) + 1;
+ if (write(fd, realm, count) != count)
+ goto bad;
+ /* Session key */
+#ifdef TKT_SHMEM
+ bcopy(session,tmp_shm_addr,8);
+ tmp_shm_addr+=8;
+ if (write(fd,krb_dummy_skey,8) != 8)
+ goto bad;
+#else /* ! TKT_SHMEM */
+ if (write(fd, (char *) session, 8) != 8)
+ goto bad;
+#endif /* TKT_SHMEM */
+ /* Lifetime */
+ if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Key vno */
+ if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Tkt length */
+ if (write(fd, (char *) &(ticket->length), sizeof(int)) !=
+ sizeof(int))
+ goto bad;
+ /* Ticket */
+ count = ticket->length;
+ if (write(fd, (char *) (ticket->dat), count) != count)
+ goto bad;
+ /* Issue date */
+ if (write(fd, (char *) &issue_date, sizeof(long))
+ != sizeof(long))
+ goto bad;
+
+ /* Actually, we should check each write for success */
+ return (KSUCCESS);
+bad:
+ return (KFAILURE);
+}
diff --git a/eBones/lib/libkrb/tkt_string.c b/eBones/lib/libkrb/tkt_string.c
new file mode 100644
index 0000000..ba22db8
--- /dev/null
+++ b/eBones/lib/libkrb/tkt_string.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $
+ * $Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char *rcsid =
+"$Id: tkt_string.c,v 1.2 1994/07/19 19:26:29 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <krb.h>
+#include <string.h>
+#include <sys/param.h>
+
+char *getenv();
+
+/*
+ * This routine is used to generate the name of the file that holds
+ * the user's cache of server tickets and associated session keys.
+ *
+ * If it is set, krb_ticket_string contains the ticket file name.
+ * Otherwise, the filename is constructed as follows:
+ *
+ * If it is set, the environment variable "KRBTKFILE" will be used as
+ * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and
+ * the user's uid are concatenated to produce the ticket file name
+ * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket
+ * file name is returned.
+ */
+
+static char krb_ticket_string[MAXPATHLEN] = "";
+
+char *tkt_string()
+{
+ char *env;
+ uid_t getuid();
+
+ if (!*krb_ticket_string) {
+ if (env = getenv("KRBTKFILE")) {
+ (void) strncpy(krb_ticket_string, env,
+ sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+ } else {
+ /* 32 bits of signed integer will always fit in 11 characters
+ (including the sign), so no need to worry about overflow */
+ (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,getuid());
+ }
+ }
+ return krb_ticket_string;
+}
+
+/*
+ * This routine is used to set the name of the file that holds the user's
+ * cache of server tickets and associated session keys.
+ *
+ * The value passed in is copied into local storage.
+ *
+ * NOTE: This routine should be called during initialization, before other
+ * Kerberos routines are called; otherwise tkt_string() above may be called
+ * and return an undesired ticket file name until this routine is called.
+ */
+
+void
+krb_set_tkt_string(val)
+char *val;
+{
+
+ (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+
+ return;
+}
diff --git a/eBones/lib/libkrb/util.c b/eBones/lib/libkrb/util.c
new file mode 100644
index 0000000..8e48557
--- /dev/null
+++ b/eBones/lib/libkrb/util.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Miscellaneous debug printing utilities
+ *
+ * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $
+ * $Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: util.c,v 1.2 1994/07/19 19:26:31 g89r4222 Exp $";
+#endif lint
+
+#include <krb.h>
+#include <des.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Print some of the contents of the given authenticator structure
+ * (AUTH_DAT defined in "krb.h"). Fields printed are:
+ *
+ * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session
+ */
+
+ad_print(x)
+AUTH_DAT *x;
+{
+ struct in_addr in;
+
+ /* Print the contents of an auth_dat struct. */
+ in.s_addr = x->address;
+ printf("\n%s %s %s %s flags %u cksum 0x%X\n\ttkt_tm 0x%X sess_key",
+ x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags,
+ x->checksum, x->time_sec);
+
+ printf("[8] =");
+#ifdef NOENCRYPTION
+ placebo_cblock_print(x->session);
+#else
+ des_cblock_print_file(x->session,stdout);
+#endif
+ /* skip reply for now */
+}
+
+/*
+ * Print in hex the 8 bytes of the given session key.
+ *
+ * Printed format is: " 0x { x, x, x, x, x, x, x, x }"
+ */
+
+#ifdef NOENCRYPTION
+placebo_cblock_print(x)
+ des_cblock x;
+{
+ unsigned char *y = (unsigned char *) x;
+ register int i = 0;
+
+ printf(" 0x { ");
+
+ while (i++ <8) {
+ printf("%x",*y++);
+ if (i<8) printf(", ");
+ }
+ printf(" }");
+}
+#endif
diff --git a/eBones/libexec/registerd/Makefile b/eBones/libexec/registerd/Makefile
new file mode 100644
index 0000000..bc91577
--- /dev/null
+++ b/eBones/libexec/registerd/Makefile
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 1990 The Regents of the University of California.
+# All rights reserved.
+#
+# %sccs.include.redist.sh
+#
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+#
+# $Id: Makefile,v 1.3 1994/07/20 09:20:51 g89r4222 Exp $
+
+PROG= registerd
+SRCS= registerd.c
+CFLAGS+=-DCRYPT -DKERBEROS -I${.CURDIR}/../register
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= registerd.8
+BINDIR= /usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/eBones/libexec/registerd/registerd.8 b/eBones/libexec/registerd/registerd.8
new file mode 100644
index 0000000..7ceff75
--- /dev/null
+++ b/eBones/libexec/registerd/registerd.8
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)registerd.8 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt REGISTERD 8
+.Os
+.Sh NAME
+.Nm registerd
+.Nd Kerberos registration daemon
+.Sh SYNOPSIS
+.Nm registerd
+.Sh DESCRIPTION
+Act as a registration agent for a Kerberos domain.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keys -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/principal*
+Kerberos database
+.It Pa /etc/kerberosIV/register_keys
+directory containing keys for trusted hosts
+.El
+.Sh SEE ALSO
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh DIAGNOSTICS
+.Dq Already exists ,
+if the user already exists in the Kerberos database.
+.Pp
+.Dq Permission Denied ,
+if the host on which register is being run is untrusted.
+.Sh HISTORY
+The
+.Nm registerd
+utility
+first appeared in 4.4BSD.
+
diff --git a/eBones/libexec/registerd/registerd.c b/eBones/libexec/registerd/registerd.c
new file mode 100644
index 0000000..b62e379
--- /dev/null
+++ b/eBones/libexec/registerd/registerd.c
@@ -0,0 +1,341 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include <stdio.h>
+#include "register_proto.h"
+#include "pathnames.h"
+
+#define KBUFSIZ (sizeof(struct keyfile_data))
+#define RCRYPT 0x00
+#define CLEAR 0x01
+
+char *progname, msgbuf[BUFSIZ];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ static Key_schedule schedule;
+ static struct rlimit rl = { 0, 0 };
+ struct keyfile_data *kfile;
+ u_char code;
+ int kf, retval, sval;
+ struct sockaddr_in sin;
+ char keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
+ void die();
+
+ progname = argv[0]; /* for the library routines */
+
+ openlog("registerd", LOG_PID, LOG_AUTH);
+
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGTSTP, SIG_IGN);
+ (void)signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ syslog(LOG_ERR, "setrlimit: %m");
+ exit(1);
+ }
+
+
+ /* figure out who we are talking to */
+
+ sval = sizeof(sin);
+ if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ exit(1);
+ }
+
+ /* get encryption key */
+
+ (void) sprintf(keyfile, "%s/%s%s",
+ SERVER_KEYDIR,
+ KEYFILE_BASE,
+ inet_ntoa(sin.sin_addr));
+
+ if ((kf = open(keyfile, O_RDONLY)) < 0) {
+ syslog(LOG_ERR,
+ "error opening Kerberos update keyfile (%s): %m", keyfile);
+ (void) sprintf(msgbuf,
+ "couldn't open session keyfile for your host");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+
+ if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
+ syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
+ (void) sprintf(msgbuf,
+ "couldn't read session key from your host's keyfile");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+ (void) sprintf(msgbuf, GOTKEY_MSG);
+ send_packet(msgbuf, CLEAR);
+ kfile = (struct keyfile_data *) keybuf;
+ key_sched(kfile->kf_key, schedule);
+ des_set_key(kfile->kf_key, schedule);
+
+ /* read the command code byte */
+
+ if (des_read(0, &code, 1) == 1) {
+
+ switch(code) {
+ case APPEND_DB:
+ retval = do_append(&sin);
+ break;
+ case ABORT:
+ cleanup();
+ close(0);
+ exit(0);
+ default:
+ retval = KFAILURE;
+ syslog(LOG_NOTICE,
+ "invalid command code on db update (0x%x)",
+ code);
+ }
+
+ } else {
+ retval = KFAILURE;
+ syslog(LOG_ERR,
+ "couldn't read command code on Kerberos update");
+ }
+
+ code = (u_char) retval;
+ if (code != KSUCCESS) {
+ (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
+ send_packet(msgbuf, RCRYPT);
+ } else {
+ (void) sprintf(msgbuf, "Update complete.");
+ send_packet(msgbuf, RCRYPT);
+ }
+ cleanup();
+ close(0);
+ exit(0);
+}
+
+#define MAX_PRINCIPAL 10
+static Principal principal_data[MAX_PRINCIPAL];
+static C_Block key, master_key;
+static Key_schedule master_key_schedule;
+int
+do_append(sinp)
+ struct sockaddr_in *sinp;
+{
+ Principal default_princ;
+ char input_name[ANAME_SZ];
+ char input_instance[INST_SZ];
+ int j,n, more;
+ long mkeyversion;
+
+
+
+ /* get master key from MKEYFILE */
+ if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
+ syslog(LOG_ERR, "couldn't get master key");
+ return(KFAILURE);
+ }
+
+ mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
+ if (mkeyversion < 0) {
+ syslog(LOG_ERR, "couldn't validate master key");
+ return(KFAILURE);
+ }
+
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+
+ if (n != 1) {
+ syslog(LOG_ERR, "couldn't get default principal");
+ return(KFAILURE);
+ }
+
+ /*
+ * get principal name, instance, and password from network.
+ * convert password to key and store it
+ */
+
+ if (net_get_principal(input_name, input_instance, key) != 0) {
+ return(KFAILURE);
+ }
+
+
+ j = kerb_get_principal(
+ input_name,
+ input_instance,
+ principal_data,
+ MAX_PRINCIPAL,
+ &more
+ );
+
+ if (j != 0) {
+ /* already in database, no update */
+ syslog(LOG_NOTICE,
+ "attempt to add duplicate entry for principal %s.%s",
+ input_name, input_instance);
+ return(KDC_PR_N_UNIQUE);
+ }
+
+ /*
+ * set up principal's name, instance
+ */
+
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+
+
+ /* and the expiration date and version #s */
+
+ principal_data[0].exp_date = default_princ.exp_date;
+ strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
+
+
+ /* and the key */
+
+ kdb_encrypt_key(key, key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(key, &principal_data[0].key_low, 4);
+ bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
+ bzero(key, sizeof(key));
+
+ principal_data[0].key_version = 1; /* 1st entry */
+
+ /* and write it to the database */
+
+ if (kerb_put_principal(&principal_data[0], 1)) {
+ syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
+ return(KFAILURE);
+ }
+
+ syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
+ principal_data[0].name,
+ principal_data[0].instance,
+ inet_ntoa(sinp->sin_addr)
+ );
+
+ return(KSUCCESS);
+
+}
+
+send_packet(msg,flag)
+ char *msg;
+ int flag;
+{
+ int len = strlen(msg);
+ msg[len++] = '\n';
+ msg[len] = '\0';
+ if (len > sizeof(msgbuf)) {
+ syslog(LOG_ERR, "send_packet: invalid msg size");
+ return;
+ }
+ if (flag == RCRYPT) {
+ if (des_write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else if (flag == CLEAR) {
+ if (write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else
+ syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
+
+}
+
+net_get_principal(pname, iname, keyp)
+ char *pname, *iname;
+ C_Block *keyp;
+{
+ int cc;
+ static char password[255];
+
+ cc = des_read(0, pname, ANAME_SZ);
+ if (cc != ANAME_SZ) {
+ syslog(LOG_ERR, "couldn't get principal name");
+ return(-1);
+ }
+
+ cc = des_read(0, iname, INST_SZ);
+ if (cc != INST_SZ) {
+ syslog(LOG_ERR, "couldn't get instance name");
+ return(-1);
+ }
+
+ cc = des_read(0, password, 255);
+ if (cc != 255) {
+ syslog(LOG_ERR, "couldn't get password");
+ bzero(password, 255);
+ return(-1);
+ }
+
+ string_to_key(password, *keyp);
+ bzero(password, 255);
+ return(0);
+}
+
+cleanup()
+{
+ bzero(master_key, sizeof(master_key));
+ bzero(key, sizeof(key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+}
+
+void
+die()
+{
+ syslog(LOG_ERR, "remote end died (SIGPIPE)");
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/make_keypair/Makefile b/eBones/make_keypair/Makefile
new file mode 100644
index 0000000..b00048e
--- /dev/null
+++ b/eBones/make_keypair/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+
+PROG= make_keypair
+MAN8= make_keypair.8
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../register
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+
+.include <bsd.prog.mk>
diff --git a/eBones/make_keypair/make_keypair.8 b/eBones/make_keypair/make_keypair.8
new file mode 100644
index 0000000..d0b7b88
--- /dev/null
+++ b/eBones/make_keypair/make_keypair.8
@@ -0,0 +1,87 @@
+.\" Copyright (c) 1988, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)make_keypair.8 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt MAKE_KEYPAIR 8
+.Os
+.Sh NAME
+.Nm make_keypair
+.Nd generate Kerberos host key pair
+.Sh SYNOPSIS
+.Nm make_keypair
+.Ar hostname
+.Op Ar hostname ...
+.Sh DESCRIPTION
+The
+.Nm make_keypair
+command
+is used to create pairs of
+.Tn DES
+keys for
+each
+.Ar hostname .
+The keys are used by privileged programs such as
+.Xr register 1
+to make remote updates to the Kerberos database without
+having to have first acquired a Kerberos ticket granting ticket
+.Pq Tn TGT .
+The keys created by
+.Nm make_keypair
+are placed (by hand) in the filesystems of the
+kerberos server in
+.Pa /etc/kerberosIV/register_keys ,
+and in the root directory of the clients.
+For example, the file
+.Pa /.update.key128.32.130.3
+would
+contain a copy of the key of the client with
+IP address 128.32.130.3.
+These keys provide a shared secret which may be used to establish
+a secure channel between the client hosts and the Kerberos server.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keysxx -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/register_keys
+server's key storage directory
+.El
+.Sh SEE ALSO
+.Xr register 1 ,
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh HISTORY
+The
+.Nm make_keypair
+utility first appeared in 4.4BSD.
diff --git a/eBones/make_keypair/make_keypair.c b/eBones/make_keypair/make_keypair.c
new file mode 100644
index 0000000..c9883ed
--- /dev/null
+++ b/eBones/make_keypair/make_keypair.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+extern void random_key(), herror();
+void make_key(), usage();
+
+char * progname;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ char *addr;
+ int i;
+ struct sockaddr_in sin;
+
+ progname = *argv; /* argv[0] */
+
+ if (argc != 2) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if ((hp = gethostbyname(argv[1])) == NULL) {
+ herror(argv[1]);
+ exit(1);
+ }
+
+ for (i = 0; addr = hp->h_addr_list[i]; i++) {
+ addr = hp->h_addr_list[i];
+ bcopy(addr, &sin.sin_addr, hp->h_length);
+
+ printf("Making key for host %s (%s)\n",
+ argv[1], inet_ntoa(sin.sin_addr));
+ make_key(sin.sin_addr);
+ }
+ printf("==========\n");
+ printf("One copy of the each key should be put in %s on the\n",
+ SERVER_KEYDIR);
+ printf("Kerberos server machine (mode 600, owner root).\n");
+ printf("Another copy of each key should be put on the named\n");
+ printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n",
+ CLIENT_KEYFILE);
+ printf("where the X's refer to digits of the host's inet address.\n");
+ (void)fflush(stdout);
+ exit(0);
+}
+
+void
+make_key(addr)
+ struct in_addr addr;
+{
+ struct keyfile_data kfile;
+ char namebuf[255];
+ int fd;
+
+ (void)sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(addr));
+ fd = open(namebuf, O_WRONLY|O_CREAT, 0600);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ random_key(kfile.kf_key);
+ printf("writing to file -> %s ...", namebuf);
+ if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) {
+ fprintf(stderr, "error writing file %s\n", namebuf);
+ }
+ printf("done.\n");
+ (void)close(fd);
+ return;
+}
+
+void
+usage(name)
+ char *name;
+{
+ fprintf(stderr, "usage: %s host\n", name);
+}
diff --git a/eBones/man/Makefile b/eBones/man/Makefile
new file mode 100644
index 0000000..8de00f0
--- /dev/null
+++ b/eBones/man/Makefile
@@ -0,0 +1,19 @@
+# from: @(#)Makefile 5.4 (Berkeley) 7/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:27:15 g89r4222 Exp $
+
+MAN1= kdestroy.1 kerberos.1 kinit.1 klist.1 ksrvtgt.1 \
+ kpasswd.1 ksu.1 rcp.1 rlogin.1 rsh.1 tftp.1
+MAN3= acl_check.3 des_crypt.3 krb.3 krb_realmofhost.3 krb_sendauth.3 \
+ krb_set_tkt_string.3 kuserok.3 tf_util.3 kerberos.3
+MAN5= krb.conf.5 krb.realms.5
+MAN8= ext_srvtab.8 kdb_destroy.8 kdb_edit.8 kdb_init.8 kdb_util.8 kstash.8 \
+ kadmin.8 kadmind.8 klogind.8 kshd.8 ksrvutil.8 tcom.8 tftpd.8
+MLINKS+=krb_realmofhost.3 realm.3
+MLINKS+=des_crypt.3 des.3
+MLINKS+=krb.3 kerberos.3 krb.3 krb_mk_req.3 krb.3 krb_rd_req.3
+MLINKS+=krb.3 krb_kntoln.3 krb.3 krb_set_key.3 krb.3 krb_get_cred.3
+MLINKS+=krb.3 krb_mk_priv.3 krb.3 krb_mk_safe.3 krb.3 krb_rd_safe.3
+MLINKS+=krb.3 krb_mk_err.3 krb.3 krb_rd_err.3 krb.3 krb_ck_repl.3
+MLINKS+=krb_sendauth.3 ksend.3
+
+.include <bsd.prog.mk>
diff --git a/eBones/man/acl_check.3 b/eBones/man/acl_check.3
new file mode 100644
index 0000000..c142506
--- /dev/null
+++ b/eBones/man/acl_check.3
@@ -0,0 +1,183 @@
+.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $
+.\" $Id: acl_check.3,v 1.2 1994/07/19 19:27:17 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+acl_canonicalize_principal, acl_check, acl_exact_match, acl_add,
+acl_delete, acl_initialize \- Access control list routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+cc <files> \-lacl \-lkrb
+.PP
+.ft B
+#include <krb.h>
+.PP
+.ft B
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf;
+.PP
+.ft B
+acl_check(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_add(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+.PP
+.ft B
+acl_initialize(acl_file, mode)
+char *acl_file;
+int mode;
+.fi
+.ft R
+.SH DESCRIPTION
+.SS Introduction
+.PP
+An access control list (ACL) is a list of principals, where each
+principal is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+.PP
+.SS Principal Names
+.PP
+Principal names have the form
+.nf
+.in +5n
+<name>[.<instance>][@<realm>]
+.in -5n
+e.g.:
+.in +5n
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+.in -5n
+.fi
+It is possible for principals to be underspecified. If an instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be the local realm as determined by
+.IR krb_get_lrealm (3).
+The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+.SS Routines
+.PP
+.I acl_canonicalize_principal
+stores the canonical form of
+.I principal
+in
+.IR buf .
+.I Buf
+must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ,
+respectively, in
+.IR /usr/include/krb.h .
+.PP
+.I acl_check
+returns nonzero if
+.I principal
+appears in
+.IR acl .
+Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards. The
+only supported wildcards are entries of the form
+name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the
+its component field. For example, "jtkohl.*@*" would match principal
+jtkohl, with any instance and any realm.
+.PP
+.I acl_exact_match
+performs like
+.IR acl_check ,
+but does no canonicalization or wildcard matching.
+.PP
+.I acl_add
+atomically adds
+.I principal
+to
+.IR acl .
+Returns 0 if successful, nonzero otherwise. It is considered a failure
+if
+.I principal
+is already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_delete
+atomically deletes
+.I principal
+from
+.IR acl .
+Returns 0 if successful,
+nonzero otherwise. It is considered a failure if
+.I principal
+is not
+already in
+.IR acl .
+This routine will canonicalize
+.IR principal ,
+but will treat wildcards literally.
+.PP
+.I acl_initialize
+initializes
+.IR acl_file .
+If the file
+.I acl_file
+does not exist,
+.I acl_initialize
+creates it with mode
+.IR mode .
+If the file
+.I acl_file
+exists,
+.I acl_initialize
+removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+.SH NOTES
+In the presence of concurrency, there is a very small chance that
+.I acl_add
+or
+.I acl_delete
+could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+.PP
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
+.SH SEE ALSO
+kerberos(3), krb_get_lrealm(3)
+.SH AUTHOR
+James Aspnes (MIT Project Athena)
diff --git a/eBones/man/des.point b/eBones/man/des.point
new file mode 100644
index 0000000..853c9cb
--- /dev/null
+++ b/eBones/man/des.point
@@ -0,0 +1 @@
+.so man3/des_crypt.3
diff --git a/eBones/man/des_crypt.3 b/eBones/man/des_crypt.3
new file mode 100644
index 0000000..0be8342
--- /dev/null
+++ b/eBones/man/des_crypt.3
@@ -0,0 +1,380 @@
+.\" from: des_crypt.3,v 4.3 89/01/23 17:08:59 steiner Exp $
+.\" $Id: des_crypt.3,v 1.2 1994/07/19 19:27:19 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH DES_CRYPT 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+des_read_password, des_string_to_key, des_random_key, des_set_key,
+des_ecb_encrypt, des_cbc_encrypt, des_pcbc_encrypt, des_cbc_cksum,
+des_quad_cksum, \- (new) DES encryption
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+.PP
+.ft B
+.B int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+.PP
+.ft B
+int des_string_to_key(str,key)
+char *str;
+des_cblock key;
+.PP
+.ft B
+int des_random_key(key)
+des_cblock *key;
+.PP
+.ft B
+int des_set_key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.ft B
+int des_ecb_encrypt(input,output,schedule,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule schedule;
+int encrypt;
+.PP
+.ft B
+int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.ft B
+int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.ft B
+unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.ft B
+unsigned long quad_cksum(input,output,length,out_count,seed)
+des_cblock *input;
+des_cblock *output;
+long length;
+int out_count;
+des_cblock *seed;
+.PP
+.fi
+.SH DESCRIPTION
+This library supports various DES encryption related operations. It differs
+from the
+.I crypt, setkey, and encrypt
+library routines in that it provides
+a true DES encryption, without modifying the algorithm,
+and executes much faster.
+.PP
+For each key that may be simultaneously active, create a
+.B des_key_schedule
+struct,
+defined in "des.h". Next, create key schedules (from the 8-byte keys) as
+needed, via
+.I des_set_key,
+prior to using the encryption or checksum routines. Then
+setup the input and output areas. Make sure to note the restrictions
+on lengths being multiples of eight bytes. Finally, invoke the
+encryption/decryption routines,
+.I des_ecb_encrypt
+or
+.I des_cbc_encrypt
+or
+.I des_pcbc_encrypt,
+or, to generate a cryptographic checksum, use
+.I quad_cksum
+(fast) or
+.I des_cbc_cksum
+(slow).
+.PP
+A
+.I des_cblock
+struct is an 8 byte block used as the fundamental unit for DES data and
+keys, and is defined as:
+.PP
+.B typedef unsigned char des_cblock[8];
+.PP
+and a
+.I des_key_schedule,
+is defined as:
+.PP
+.B typedef struct des_ks_struct {des_cblock _;} des_key_schedule[16];
+.PP
+.I des_read_password
+writes the string specified by
+.I prompt
+to the standard
+output, turns off echo (if possible)
+and reads an input string from standard input until terminated with a newline.
+If
+.I verify
+is non-zero, it prompts and reads input again, for use
+in applications such as changing a password; both
+versions are compared, and the input is requested repeatedly until they
+match. Then
+.I des_read_password
+converts the input string into a valid DES key, internally
+using the
+.I des_string_to_key
+routine. The newly created key is copied to the
+area pointed to by the
+.I key
+argument.
+.I des_read_password
+returns a zero if no errors occurred, or a -1
+indicating that an error
+occurred trying to manipulate the terminal echo.
+.PP
+.PP
+.I des_string_to_key
+converts an arbitrary length null-terminated string
+to an 8 byte DES key, with odd byte parity, per FIPS specification.
+A one-way function is used to convert the string to a key, making it
+very difficult to reconstruct the string from the key.
+The
+.I str
+argument is a pointer to the string, and
+.I key
+should
+point to a
+.I des_cblock
+supplied by the caller to receive the generated key.
+No meaningful value is returned. Void is not used for compatibility with
+other compilers.
+.PP
+.PP
+.I des_random_key
+generates a random DES encryption key (eight bytes), set to odd parity per
+FIPS
+specifications.
+This routine uses the current time, process id, and a counter
+as a seed for the random number generator.
+The caller must supply space for the output key, pointed to
+by argument
+.I key,
+then after calling
+.I des_random_key
+should
+call the
+.I des_set_key
+routine when needed.
+No meaningful value is returned. Void is not used for compatibility
+with other compilers.
+.PP
+.PP
+.I des_set_key
+calculates a key schedule from all eight bytes of the input key, pointed
+to by the
+.I key
+argument, and outputs the schedule into the
+.I des_key_schedule
+indicated by the
+.I schedule
+argument. Make sure to pass a valid eight byte
+key; no padding is done. The key schedule may then be used in subsequent
+encryption/decryption/checksum operations. Many key schedules may be
+cached for later use. The user is responsible to clear keys and schedules
+as soon as no longer needed, to prevent their disclosure.
+The routine also checks the key
+parity, and returns a zero if the key parity is correct (odd), a -1
+indicating a key parity error, or a -2 indicating use of an illegal
+weak key. If an error is returned, the key schedule was not created.
+.PP
+.PP
+.I des_ecb_encrypt
+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
+block in
+.B electronic code book
+mode. It always transforms the input data, pointed to by
+.I input,
+into the output data, pointed to by the
+.I output
+argument.
+.PP
+If the
+.I encrypt
+argument is non-zero, the
+.I input
+(cleartext) is encrypted into the
+.I output
+(ciphertext) using the key_schedule specified by the
+.I schedule
+argument, previously set via
+.I des_set_key
+.PP
+If encrypt is zero, the
+.I input
+(now ciphertext) is decrypted into the
+.I output
+(now cleartext).
+.PP
+Input and output may overlap.
+.PP
+No meaningful value is returned. Void is not used for compatibility
+with other compilers.
+.PP
+.PP
+.I des_cbc_encrypt
+encrypts/decrypts using the
+.B cipher-block-chaining mode of DES.
+If the
+.I encrypt
+argument is non-zero, the routine cipher-block-chain encrypts
+the cleartext data pointed to by the
+.I input
+argument into the ciphertext pointed to by the
+.I output
+argument, using the key schedule provided by the
+.I schedule
+argument, and initialization vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral
+multiple of eight bytes, the last block is copied to a temp and zero
+filled (highest addresses). The output is ALWAYS an integral multiple
+of eight bytes.
+.PP
+If
+.I encrypt
+is zero, the routine cipher-block chain decrypts the (now) ciphertext
+data pointed to by the
+.I input
+argument into (now) cleartext pointed to by the
+.I output
+argument using the key schedule provided by the
+.I schedule
+argument, and initialization vector provided by the
+.I ivec
+argument. Decryption ALWAYS operates on integral
+multiples of 8 bytes, so it will round the
+.I length
+provided up to the
+appropriate multiple. Consequently, it will always produce the rounded-up
+number of bytes of output cleartext. The application must determine if
+the output cleartext was zero-padded due to original cleartext lengths that
+were not integral multiples of 8.
+.PP
+No errors or meaningful values are returned. Void is not used for
+compatibility with other compilers.
+.PP
+A characteristic of cbc mode is that changing a single bit of the
+cleartext, then encrypting using cbc mode,
+affects ALL the subsequent ciphertext. This makes cryptanalysis
+much more difficult. However, modifying a single bit of the ciphertext,
+then decrypting, only affects the resulting cleartext from
+the modified block and the succeeding block. Therefore,
+.I des_pcbc_encrypt
+is STRONGLY recommended for applications where
+indefinite propagation of errors is required in order to detect modifications.
+.PP
+.PP
+.I des_pcbc_encrypt
+encrypts/decrypts using a modified block chaining mode. Its calling
+sequence is identical to
+.I des_cbc_encrypt.
+It differs in its error propagation characteristics.
+.PP
+.I des_pcbc_encrypt
+is highly recommended for most encryption purposes, in that
+modification of a single bit of the ciphertext will affect ALL the
+subsequent (decrypted) cleartext. Similarly, modifying a single bit of
+the cleartext will affect ALL the subsequent (encrypted) ciphertext.
+"PCBC" mode, on encryption, "xors" both the
+cleartext of block N and the ciphertext resulting from block N with the
+cleartext for block N+1 prior to encrypting block N+1.
+.PP
+.I des_cbc_cksum
+produces an 8 byte cryptographic checksum by cipher-block-chain
+encrypting the cleartext data pointed to by the
+.I input
+argument. All of the ciphertext output is discarded, except the
+last 8-byte ciphertext block, which is written into the area pointed to by
+the
+.I output
+argument.
+It uses the key schedule,
+provided by the
+.I schedule
+argument and initialization vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral
+multiple of eight bytes, the last cleartext block is copied to a temp and zero
+filled (highest addresses). The output is ALWAYS eight bytes.
+.PP
+The routine also returns an unsigned long, which is the last (highest address)
+half of the 8 byte checksum computed.
+.PP
+.PP
+.I quad_cksum
+produces a checksum by chaining quadratic operations on the cleartext data
+pointed to by the
+.I input
+argument. The
+.I length
+argument specifies the length of the
+input -- only exactly that many bytes are included for the checksum,
+without any padding.
+.PP
+The algorithm may be iterated over the same input data, if the
+.I out_count
+argument is 2, 3 or 4, and the optional
+.I output
+argument is a non-null pointer .
+The default is one iteration, and it will not run
+more than 4 times. Multiple iterations run slower, but provide
+a longer checksum if desired. The
+.I seed
+argument provides an 8-byte seed for the first iteration. If multiple iterations are
+requested, the results of one iteration are automatically used as
+the seed for the next iteration.
+.PP
+It returns both an unsigned long checksum value, and
+if the
+.I output
+argument is not a null pointer, up to 16 bytes of
+the computed checksum are written into the output.
+.PP
+.PP
+.SH FILES
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.SH "SEE ALSO"
+.SH DIAGNOSTICS
+.SH BUGS
+This software has not yet been compiled or tested on machines other than the
+VAX and the IBM PC.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.SH RESTRICTIONS
+COPYRIGHT 1985,1986 Massachusetts Institute of Technology
+.PP
+This software may not be exported outside of the US without a special
+license from the US Dept of Commerce. It may be replaced by any secret
+key block cipher with block length and key length of 8 bytes, as long
+as the interface is the same as described here.
diff --git a/eBones/man/ext_srvtab.8 b/eBones/man/ext_srvtab.8
new file mode 100644
index 0000000..af980a9
--- /dev/null
+++ b/eBones/man/ext_srvtab.8
@@ -0,0 +1,63 @@
+.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $
+.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ext_srvtab \- extract service key files from Kerberos key distribution center database
+.SH SYNOPSIS
+ext_srvtab [
+.B \-n
+] [
+.B \-r realm
+] [
+.B hostname ...
+]
+.SH DESCRIPTION
+.I ext_srvtab
+extracts service key files from the Kerberos key distribution center
+(KDC) database.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database. If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+For each
+.I hostname
+specified on the command line,
+.I ext_srvtab
+creates the service key file
+.IR hostname -new-srvtab,
+containing all the entries in the database with an instance field of
+.I hostname.
+This new file contains all the keys registered for Kerberos-mediated
+service providing programs which use the
+.IR krb_get_phost (3)
+principal and instance conventions to run on the host
+.IR hostname .
+If the
+.B \-r
+option is specified, the realm fields in the extracted file will
+match the given realm rather than the local realm.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+.IR hostname -new-srvtab
+Service key file generated for
+.I hostname
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH SEE ALSO
+read_service_key(3), krb_get_phost(3)
diff --git a/eBones/man/kadmin.8 b/eBones/man/kadmin.8
new file mode 100644
index 0000000..6e15015
--- /dev/null
+++ b/eBones/man/kadmin.8
@@ -0,0 +1,158 @@
+.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $
+.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmin \- network utility for Kerberos database administration
+.SH SYNOPSIS
+.B kadmin [-u user] [-r default_realm] [-m]
+.SH DESCRIPTION
+This utility provides a unified administration interface to
+the
+Kerberos
+master database.
+Kerberos
+administrators
+use
+.I kadmin
+to register new users and services to the master database,
+and to change information about existing database entries.
+For instance, an administrator can use
+.I kadmin
+to change a user's
+Kerberos
+password.
+A Kerberos administrator is a user with an ``admin'' instance
+whose name appears on one of the Kerberos administration access control
+lists. If the \-u option is used,
+.I user
+will be used as the administrator instead of the local user.
+If the \-r option is used,
+.I default_realm
+will be used as the default realm for transactions. Otherwise,
+the local realm will be used by default.
+If the \-m option is used, multiple requests will be permitted
+on only one entry of the admin password. Some sites won't
+support this option.
+
+The
+.I kadmin
+program communicates over the network with the
+.I kadmind
+program, which runs on the machine housing the Kerberos master
+database.
+The
+.I kadmind
+creates new entries and makes modifications to the database.
+
+When you enter the
+.I kadmin
+command,
+the program displays a message that welcomes you and explains
+how to ask for help.
+Then
+.I kadmin
+waits for you to enter commands (which are described below).
+It then asks you for your
+.I admin
+password before accessing the database.
+
+Use the
+.I add_new_key
+(or
+.I ank
+for short)
+command to register a new principal
+with the master database.
+The command requires one argument,
+the principal's name. The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's
+new password. If no realm is specified,
+the local realm is used unless another was
+given on the commandline with the \-r flag.
+If no instance is
+specified, a null instance is used. If
+a realm other than the default realm is specified,
+you will need to supply your admin password for
+the other realm.
+
+Use the
+.I change_password (cpw)
+to change a principal's
+Kerberos
+password.
+The command requires one argument,
+the principal's
+name.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's new password.
+The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+
+Use the
+.I change_admin_password (cap)
+to change your
+.I admin
+instance password.
+This command requires no arguments.
+It prompts you for your old
+.I admin
+password, then prompts you twice to enter the new
+.I admin
+password. If this is your first command,
+the default realm is used. Otherwise, the realm
+used in the last command is used.
+
+Use the
+.I destroy_tickets (dest)
+command to destroy your admin tickets explicitly.
+
+Use the
+.I list_requests (lr)
+command to get a list of possible commands.
+
+Use the
+.I help
+command to display
+.IR kadmin's
+various help messages.
+If entered without an argument,
+.I help
+displays a general help message.
+You can get detailed information on specific
+.I kadmin
+commands
+by entering
+.I help
+.IR command_name .
+
+To quit the program, type
+.IR quit .
+
+.SH BUGS
+The user interface is primitive, and the command names could be better.
+
+.SH "SEE ALSO"
+kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8)
+.br
+``A Subsystem Utilities Package for UNIX'' by Ken Raeburn
+.SH AUTHORS
+Jeffrey I. Schiller, MIT Project Athena
+.br
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/man/kadmind.8 b/eBones/man/kadmind.8
new file mode 100644
index 0000000..59075ee
--- /dev/null
+++ b/eBones/man/kadmind.8
@@ -0,0 +1,117 @@
+.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $
+.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmind \- network daemon for Kerberos database administration
+.SH SYNOPSIS
+.B kadmind
+[
+.B \-n
+] [
+.B \-h
+] [
+.B \-r realm
+] [
+.B \-f filename
+] [
+.B \-d dbname
+] [
+.B \-a acldir
+]
+.SH DESCRIPTION
+.I kadmind
+is the network database server for the Kerberos password-changing and
+administration tools.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.
+.PP
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+If the
+.B \-r
+.I realm
+option is specified, the admin server will pretend that its
+local realm is
+.I realm
+instead of the actual local realm of the host it is running on.
+This makes it possible to run a server for a foreign kerberos
+realm.
+.PP
+If the
+.B \-f
+.I filename
+option is specified, then that file is used to hold the log information
+instead of the default.
+.PP
+If the
+.B \-d
+.I dbname
+option is specified, then that file is used as the database name instead
+of the default.
+.PP
+If the
+.B \-a
+.I acldir
+option is specified, then
+.I acldir
+is used as the directory in which to search for access control lists
+instead of the default.
+.PP
+If the
+.B \-h
+option is specified,
+.I kadmind
+prints out a short summary of the permissible control arguments, and
+then exits.
+.PP
+When performing requests on behalf of clients,
+.I kadmind
+checks access control lists (ACLs) to determine the authorization of the client
+to perform the requested action.
+Currently three distinct access types are supported:
+.TP 1i
+Addition
+(.add ACL file). If a principal is on this list, it may add new
+principals to the database.
+.TP
+Retrieval
+(.get ACL file). If a principal is on this list, it may retrieve
+database entries. NOTE: A principal's private key is never returned by
+the get functions.
+.TP
+Modification
+(.mod ACL file). If a principal is on this list, it may modify entries
+in the database.
+.PP
+A principal is always granted authorization to change its own password.
+.SH FILES
+.TP 20n
+/kerberos/admin_server.syslog
+Default log file.
+.TP
+/kerberos
+Default access control list directory.
+.TP
+admin_acl.{add,get,mod}
+Access control list files (within the directory)
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+Default DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH "SEE ALSO"
+kerberos(1), kpasswd(1), kadmin(8), acl_check(3)
+.SH AUTHORS
+Douglas A. Church, MIT Project Athena
+.br
+John T. Kohl, Project Athena/Digital Equipment Corporation
diff --git a/eBones/man/kdb_destroy.8 b/eBones/man/kdb_destroy.8
new file mode 100644
index 0000000..93db466
--- /dev/null
+++ b/eBones/man/kdb_destroy.8
@@ -0,0 +1,33 @@
+.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $
+.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_destroy \- destroy Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_destroy
+.SH DESCRIPTION
+.I kdb_destroy
+deletes a Kerberos key distribution center database.
+.PP
+The user is prompted to verify that the database should be destroyed. A
+response beginning with `y' or `Y' confirms deletion.
+Any other response aborts deletion.
+.SH DIAGNOSTICS
+.TP 20n
+"Database cannot be deleted at /kerberos/principal"
+The attempt to delete the database failed (probably due to a system or
+access permission error).
+.TP
+"Database not deleted."
+The user aborted the deletion.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.SH SEE ALSO
+kdb_init(8)
diff --git a/eBones/man/kdb_edit.8 b/eBones/man/kdb_edit.8
new file mode 100644
index 0000000..1cfd6ed
--- /dev/null
+++ b/eBones/man/kdb_edit.8
@@ -0,0 +1,55 @@
+.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $
+.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_edit \- Kerberos key distribution center database editing utility
+.SH SYNOPSIS
+kdb_edit [
+.B \-n
+]
+.SH DESCRIPTION
+.I kdb_edit
+is used to create or change principals stored in the Kerberos key
+distribution center (KDC) database.
+.PP
+When executed,
+.I kdb_edit
+prompts for the master key string and verifies that it matches the
+master key stored in the database.
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+Once the master key has been verified,
+.I kdb_edit
+begins a prompt loop. The user is prompted for the principal and
+instance to be modified. If the entry is not found the user may create
+it.
+Once an entry is found or created, the user may set the password,
+expiration date, maximum ticket lifetime, and attributes.
+Default expiration dates, maximum ticket lifetimes, and attributes are
+presented in brackets; if the user presses return the default is selected.
+There is no default password.
+The password RANDOM is interpreted specially, and if entered
+the user may have the program select a random DES key for the
+principal.
+.PP
+Upon successfully creating or changing the entry, ``Edit O.K.'' is
+printed.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/man/kdb_init.8 b/eBones/man/kdb_init.8
new file mode 100644
index 0000000..54537ad
--- /dev/null
+++ b/eBones/man/kdb_init.8
@@ -0,0 +1,41 @@
+.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $
+.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_init \- Initialize Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_init [
+.B realm
+]
+.SH DESCRIPTION
+.I kdb_init
+initializes a Kerberos key distribution center database, creating the
+necessary principals.
+.PP
+If the optional
+.I realm
+argument is not present,
+.I kdb_init
+prompts for a realm name (defaulting to the definition in /usr/include/krb.h).
+After determining the realm to be created, it prompts for
+a master key password. The master key password is used to encrypt
+every encryption key stored in the database.
+.SH DIAGNOSTICS
+.TP 20n
+"/kerberos/principal: File exists"
+An attempt was made to create a database on a machine which already had
+an existing database.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/usr/include/krb.h
+Include file defining default realm
+.SH SEE ALSO
+kdb_destroy(8)
diff --git a/eBones/man/kdb_util.8 b/eBones/man/kdb_util.8
new file mode 100644
index 0000000..30a3b9f
--- /dev/null
+++ b/eBones/man/kdb_util.8
@@ -0,0 +1,64 @@
+.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $
+.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_util \- Kerberos key distribution center database utility
+.SH SYNOPSIS
+kdb_util
+.B operation filename
+.SH DESCRIPTION
+.I kdb_util
+allows the Kerberos key distribution center (KDC) database administrator to
+perform utility functions on the database.
+.PP
+.I Operation
+must be one of the following:
+.TP 10n
+.I load
+initializes the KDC database with the records described by the
+text contained in the file
+.IR filename .
+Any existing database is overwritten.
+.TP
+.I dump
+dumps the KDC database into a text representation in the file
+.IR filename .
+.TP
+.I slave_dump
+performs a database dump like the
+.I dump
+operation, and additionally creates a semaphore file signalling the
+propagation software that an update is available for distribution to
+slave KDC databases.
+.TP
+.I new_master_key
+prompts for the old and new master key strings, and then dumps the KDC
+database into a text representation in the file
+.IR filename .
+The keys in the text representation are encrypted in the new master key.
+.TP
+.I convert_old_db
+prompts for the master key string, and then dumps the KDC database into
+a text representation in the file
+.IR filename .
+The existing database is assumed to be encrypted using the old format
+(encrypted by the key schedule of the master key); the dumped database
+is encrypted using the new format (encrypted directly with master key).
+.PP
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+.IR filename .ok
+semaphore file created by
+.IR slave_dump.
diff --git a/eBones/man/kdestroy.1 b/eBones/man/kdestroy.1
new file mode 100644
index 0000000..7099353
--- /dev/null
+++ b/eBones/man/kdestroy.1
@@ -0,0 +1,81 @@
+.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $
+.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdestroy \- destroy Kerberos tickets
+.SH SYNOPSIS
+.B kdestroy
+[
+.B \-f
+]
+[
+.B \-q
+]
+.SH DESCRIPTION
+The
+.I kdestroy
+utility destroys the user's active
+Kerberos
+authorization tickets by writing zeros to the file that contains them.
+If the ticket file does not exist,
+.I kdestroy
+displays a message to that effect.
+.PP
+After overwriting the file,
+.I kdestroy
+removes the file from the system.
+The utility
+displays a message indicating the success or failure of the
+operation.
+If
+.I kdestroy
+is unable to destroy the ticket file,
+the utility will warn you by making your terminal beep.
+.PP
+In the Athena workstation environment,
+the
+.I toehold
+service automatically destroys your tickets when you
+end a workstation session.
+If your site does not provide a similar ticket-destroying mechanism,
+you can place the
+.I kdestroy
+command in your
+.I .logout
+file so that your tickets are destroyed automatically
+when you logout.
+.PP
+The options to
+.I kdestroy
+are as follows:
+.TP 7
+.B \-f
+.I kdestroy
+runs without displaying the status message.
+.TP
+.B \-q
+.I kdestroy
+will not make your terminal beep if it fails to destroy the tickets.
+.SH FILES
+KRBTKFILE environment variable if set, otherwise
+.br
+/tmp/tkt[uid]
+.SH SEE ALSO
+kerberos(1), kinit(1), klist(1)
+.SH BUGS
+.PP
+Only the tickets in the user's current ticket file are destroyed.
+Separate ticket files are used to hold root instance and password
+changing tickets. These files should probably be destroyed too, or
+all of a user's tickets kept in a single ticket file.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+.br
+Bill Sommerfeld, MIT Project Athena
diff --git a/eBones/man/kerberos.1 b/eBones/man/kerberos.1
new file mode 100644
index 0000000..c489b88
--- /dev/null
+++ b/eBones/man/kerberos.1
@@ -0,0 +1,259 @@
+.\" from: kerberos.1,v 4.7 89/01/23 11:39:33 jtkohl Exp $
+.\" $Id: kerberos.1,v 1.2 1994/07/19 19:27:33 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KERBEROS 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kerberos \- introduction to the Kerberos system
+
+.SH DESCRIPTION
+The
+Kerberos
+system authenticates
+individual users in a network environment.
+After authenticating yourself to
+Kerberos,
+you can use network utilities such as
+.IR rlogin ,
+.IR rcp ,
+and
+.IR rsh
+without
+having to present passwords to remote hosts and without having to bother
+with
+.I \.rhosts
+files.
+Note that these utilities will work without passwords only if
+the remote machines you deal with
+support the
+Kerberos
+system.
+All Athena timesharing machines and public workstations support
+Kerberos.
+.PP
+Before you can use
+Kerberos,
+you must register as an Athena user,
+and you must make sure you have been added to
+the
+Kerberos
+database.
+You can use the
+.I kinit
+command to find out.
+This command
+tries to log you into the
+Kerberos
+system.
+.I kinit
+will prompt you for a username and password.
+Enter your username and password.
+If the utility lets you login without giving you a message,
+you have already been registered.
+.PP
+If you enter your username and
+.I kinit
+responds with this message:
+.nf
+
+Principal unknown (kerberos)
+
+.fi
+you haven't been registered as a
+Kerberos
+user.
+See your system administrator.
+.PP
+A Kerberos name contains three parts.
+The first is the
+.I principal name,
+which is usually a user's or service's name.
+The second is the
+.I instance,
+which in the case of a user is usually null.
+Some users may have privileged instances, however,
+such as ``root'' or ``admin''.
+In the case of a service, the instance is the
+name of the machine on which it runs; i.e. there
+can be an
+.I rlogin
+service running on the machine ABC, which
+is different from the rlogin service running on
+the machine XYZ.
+The third part of a Kerberos name
+is the
+.I realm.
+The realm corresponds to the Kerberos service providing
+authentication for the principal.
+For example, at MIT there is a Kerberos running at the
+Laboratory for Computer Science and one running at
+Project Athena.
+.PP
+When writing a Kerberos name, the principal name is
+separated from the instance (if not null) by a period,
+and the realm (if not the local realm) follows, preceded by
+an ``@'' sign.
+The following are examples of valid Kerberos names:
+.sp
+.nf
+.in +8
+billb
+jis.admin
+srz@lcs.mit.edu
+treese.root@athena.mit.edu
+.in -8
+.fi
+.PP
+When you authenticate yourself with
+Kerberos,
+through either the workstation
+.I toehold
+system or the
+.I kinit
+command,
+Kerberos
+gives you an initial
+Kerberos
+.IR ticket .
+(A
+Kerberos
+ticket
+is an encrypted protocol message that provides authentication.)
+Kerberos
+uses this ticket for network utilities
+such as
+.I rlogin
+and
+.IR rcp .
+The ticket transactions are done transparently,
+so you don't have to worry about their management.
+.PP
+Note, however, that tickets expire.
+Privileged tickets, such as root instance tickets,
+expire in a few minutes, while tickets that carry more ordinary
+privileges may be good for several hours or a day, depending on the
+installation's policy.
+If your login session extends beyond the time limit,
+you will have to re-authenticate yourself to
+Kerberos
+to get new tickets.
+Use the
+.IR kinit
+command to re-authenticate yourself.
+.PP
+If you use the
+.I kinit
+command to get your tickets,
+make sure you use the
+.I kdestroy
+command
+to destroy your tickets before you end your login session.
+You should probably put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+For more information about the
+.I kinit
+and
+.I kdestroy
+commands,
+see the
+.I kinit(1)
+and
+.I kdestroy(1)
+manual pages.
+.PP
+Currently,
+Kerberos
+supports the following network services:
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp .
+Other services are being worked on,
+such as the
+.IR pop
+mail system and NFS (network file system),
+but are not yet available.
+
+.SH "SEE ALSO"
+kdestroy(1), kinit(1), klist(1), kpasswd(1), des_crypt(3), kerberos(3),
+kadmin(8)
+.SH BUGS
+Kerberos
+will not do authentication forwarding.
+In other words,
+if you use
+.I rlogin
+to login to a remote host,
+you cannot use
+Kerberos
+services from that host
+until you authenticate yourself explicitly on that host.
+Although you may need to authenticate yourself on the remote
+host,
+be aware that when you do so,
+.I rlogin
+sends your password across the network in clear text.
+
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+
+The following people helped out on various aspects of the system:
+
+Jeff Schiller designed and wrote the administration server and its
+user interface, kadmin.
+He also wrote the dbm version of the database management system.
+
+Mark Colan developed the
+Kerberos
+versions of
+.IR rlogin ,
+.IR rsh ,
+and
+.IR rcp ,
+as well as contributing work on the servers.
+
+John Ostlund developed the
+Kerberos
+versions of
+.I passwd
+and
+.IR userreg .
+
+Stan Zanarotti pioneered Kerberos in a foreign realm (LCS),
+and made many contributions based on that experience.
+
+Many people contributed code and/or useful ideas, including
+Jim Aspnes,
+Bob Baldwin,
+John Barba,
+Richard Basch,
+Jim Bloom,
+Bill Bryant,
+Rob French,
+Dan Geer,
+David Jedlinsky,
+John Kohl,
+John Kubiatowicz,
+Bob McKie,
+Brian Murphy,
+Ken Raeburn,
+Chris Reed,
+Jon Rochlis,
+Mike Shanzer,
+Bill Sommerfeld,
+Jennifer Steiner,
+Ted Ts'o,
+and
+Win Treese.
+
+.SH RESTRICTIONS
+
+COPYRIGHT 1985,1986 Massachusetts Institute of Technology
diff --git a/eBones/man/kerberos.3 b/eBones/man/kerberos.3
new file mode 100644
index 0000000..30fa885
--- /dev/null
+++ b/eBones/man/kerberos.3
@@ -0,0 +1,461 @@
+.\" from: kerberos.3,v 4.9 89/01/23 16:28:19 steiner Exp $
+.\" $Id: kerberos.3,v 1.2 1994/07/19 19:27:35 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred,
+krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err,
+krb_rd_err, krb_ck_repl \- Kerberos authentication library
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+int krb_mk_req(authent,service,instance,realm,checksum)
+KTEXT authent;
+char *service;
+char *instance;
+char *realm;
+u_long checksum;
+.PP
+.ft B
+int krb_rd_req(authent,service,instance,from_addr,ad,fn)
+KTEXT authent;
+char *service;
+char *instance;
+u_long from_addr;
+AUTH_DAT *ad;
+char *fn;
+.PP
+.ft B
+int krb_kntoln(ad,lname)
+AUTH_DAT *ad;
+char *lname;
+.PP
+.ft B
+int krb_set_key(key,cvt)
+char *key;
+int cvt;
+.PP
+.ft B
+int krb_get_cred(service,instance,realm,c)
+char *service;
+char *instance;
+char *realm;
+CREDENTIALS *c;
+.PP
+.ft B
+long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+des_key_schedule schedule;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data)
+u_char *in;
+u_long in_length;
+Key_schedule schedule;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_safe(in,out,in_length,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_safe(in,length,key,sender,receiver,msg_data)
+u_char *in;
+u_long length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_err(out,code,string)
+u_char *out;
+long code;
+char *string;
+.PP
+.ft B
+long krb_rd_err(in,length,code,msg_data)
+u_char *in;
+u_long length;
+long code;
+MSG_DAT *msg_data;
+.fi
+.ft R
+.SH DESCRIPTION
+This library supports network authentication and various related
+operations. The library contains many routines beyond those described
+in this man page, but they are not intended to be used directly.
+Instead, they are called by the routines that are described, the
+authentication server and the login program.
+.PP
+.I krb_err_txt[]
+contains text string descriptions of various Kerberos error codes returned
+by some of the routines below.
+.PP
+.I krb_mk_req
+takes a pointer to a text structure in which an authenticator is to be
+built. It also takes the name, instance, and realm of the service to be
+used and an optional checksum. It is up to the application to decide
+how to generate the checksum.
+.I krb_mk_req
+then retrieves a ticket for the desired service and creates an
+authenticator. The authenticator is built in
+.I authent
+and is accessible
+to the calling procedure.
+.PP
+It is up to the application to get the authenticator to the service
+where it will be read by
+.I krb_rd_req.
+Unless an attacker posesses the session key contained in the ticket, it
+will be unable to modify the authenticator. Thus, the checksum can be
+used to verify the authenticity of the other data that will pass through
+a connection.
+.PP
+.I krb_rd_req
+takes an authenticator of type
+.B KTEXT,
+a service name, an instance, the address of the
+host originating the request, and a pointer to a structure of type
+.B AUTH_DAT
+which is filled in with information obtained from the authenticator.
+It also optionally takes the name of the file in which it will find the
+secret key(s) for the service.
+If the supplied
+.I instance
+contains "*", then the first service key with the same service name
+found in the service key file will be used, and the
+.I instance
+argument will be filled in with the chosen instance. This means that
+the caller must provide space for such an instance name.
+.PP
+It is used to find out information about the principal when a request
+has been made to a service. It is up to the application protocol to get
+the authenticator from the client to the service. The authenticator is
+then passed to
+.I krb_rd_req
+to extract the desired information.
+.PP
+.I krb_rd_req
+returns zero (RD_AP_OK) upon successful authentication. If a packet was
+forged, modified, or replayed, authentication will fail. If the
+authentication fails, a non-zero value is returned indicating the
+particular problem encountered. See
+.I krb.h
+for the list of error codes.
+.PP
+If the last argument is the null string (""), krb_rd_req will use the
+file /etc/srvtab to find its keys. If the last argument is NULL, it
+will assume that the key has been set by
+.I krb_set_key
+and will not bother looking further.
+.PP
+.I krb_kntoln
+converts a Kerberos name to a local name. It takes a structure
+of type AUTH_DAT and uses the name and instance to look in the database
+/etc/aname to find the corresponding local name. The local name is
+returned and can be used by an application to change uids, directories,
+or other parameters. It is not an integral part of Kerberos, but is
+instead provided to support the use of Kerberos in existing utilities.
+.PP
+.I krb_set_key
+takes as an argument a des key. It then creates
+a key schedule from it and saves the original key to be used as an
+initialization vector.
+It is used to set the server's key which
+must be used to decrypt tickets.
+.PP
+If called with a non-zero second argument,
+.I krb_set_key
+will first convert the input from a string of arbitrary length to a DES
+key by encrypting it with a one-way function.
+.PP
+In most cases it should not be necessary to call
+.I krb_set_key.
+The necessary keys will usually be obtained and set inside
+.I krb_rd_req. krb_set_key
+is provided for those applications that do not wish to place the
+application keys on disk.
+.PP
+.I krb_get_cred
+searches the caller's ticket file for a ticket for the given service, instance,
+and realm; and, if a ticket is found, fills in the given CREDENTIALS structure
+with the ticket information.
+.PP
+If the ticket was found,
+.I krb_get_cred
+returns GC_OK.
+If the ticket file can't be found, can't be read, doesn't belong to
+the user (other than root), isn't a regular file, or is in the wrong
+mode, the error GC_TKFIL is returned.
+.PP
+.I krb_mk_priv
+creates an encrypted, authenticated
+message from any arbitrary application data, pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key
+and the key schedule,
+.I schedule,
+are used to encrypt the data and some header information using
+.I pcbc_encrypt.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+In addition to providing privacy, this protocol message protects
+against modifications, insertions or replays. The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+.PP
+.I krb_rd_priv
+decrypts and authenticates a received
+.I krb_mk_priv
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+and the key schedule,
+.I schedule,
+are used to decrypt and verify the received message.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h.
+The routine fills in the
+.I app_data
+field with a pointer to the decrypted application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender. (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of). The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_safe
+creates an authenticated, but unencrypted message from any arbitrary
+application data,
+pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key,
+is used to seed the
+.I quad_cksum()
+checksum algorithm used as part of the authentication.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+This message does not provide privacy, but does protect (via detection)
+against modifications, insertions or replays. The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+The authentication provided by this routine is not as strong as that
+provided by
+.I krb_mk_priv
+or by computing the checksum using
+.I cbc_cksum
+instead, both of which authenticate via DES.
+.PP
+
+.I krb_rd_safe
+authenticates a received
+.I krb_mk_safe
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+is used to seed the quad_cksum() routine as part of the authentication.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields:
+the
+.I app_data
+field with a pointer to the application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender.
+(The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of). The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_err
+constructs an application level error message that may be used along
+with
+.I krb_mk_priv
+or
+.I krb_mk_safe.
+.I out
+is a pointer to the output buffer,
+.I code
+is an application specific error code, and
+.I string
+is an application specific error string.
+
+.PP
+.I krb_rd_err
+unpacks a received
+.I krb_mk_err
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+.I code
+is a pointer to a value to be filled in with the error
+value provided by the application.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields: the
+.I app_data
+field with a pointer to the application error text,
+.I app_length
+with the length of the
+.I app_data
+field, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender. (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of).
+
+The routine returns zero if the error message has been successfully received,
+or a Kerberos error code.
+.PP
+The
+.I KTEXT
+structure is used to pass around text of varying lengths. It consists
+of a buffer for the data, and a length. krb_rd_req takes an argument of this
+type containing the authenticator, and krb_mk_req returns the
+authenticator in a structure of this type. KTEXT itself is really a
+pointer to the structure. The actual structure is of type KTEXT_ST.
+.PP
+The
+.I AUTH_DAT
+structure is filled in by krb_rd_req. It must be allocated before
+calling krb_rd_req, and a pointer to it is passed. The structure is
+filled in with data obtained from Kerberos.
+.I MSG_DAT
+structure is filled in by either krb_rd_priv, krb_rd_safe, or
+krb_rd_err. It must be allocated before the call and a pointer to it
+is passed. The structure is
+filled in with data obtained from Kerberos.
+.PP
+.SH FILES
+/usr/include/krb.h
+.br
+/usr/lib/libkrb.a
+.br
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.br
+/etc/aname
+.br
+/etc/srvtab
+.br
+/tmp/tkt[uid]
+.SH "SEE ALSO"
+kerberos(1), des_crypt(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The caller of
+.I krb_rd_req, krb_rd_priv, and krb_rd_safe
+must check time order and for replay attempts.
+.I krb_ck_repl
+is not implemented yet.
+.SH AUTHORS
+Clifford Neuman, MIT Project Athena
+.br
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.SH RESTRICTIONS
+COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology
diff --git a/eBones/man/kerberos.point b/eBones/man/kerberos.point
new file mode 100644
index 0000000..a75ae2c
--- /dev/null
+++ b/eBones/man/kerberos.point
@@ -0,0 +1 @@
+.so man3/kerberos.3
diff --git a/eBones/man/kinit.1 b/eBones/man/kinit.1
new file mode 100644
index 0000000..f9a97a7
--- /dev/null
+++ b/eBones/man/kinit.1
@@ -0,0 +1,133 @@
+.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $
+.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kinit \- Kerberos login utility
+.SH SYNOPSIS
+.B kinit
+[
+.B \-irvl
+]
+.SH DESCRIPTION
+The
+.I kinit
+command is used to login to the
+Kerberos
+authentication and authorization system.
+Note that only registered
+Kerberos
+users can use the
+Kerberos
+system.
+For information about registering as a
+Kerberos
+user,
+see the
+.I kerberos(1)
+manual page.
+.PP
+If you are logged in to a workstation that is running the
+.I toehold
+service,
+you do not have to use
+.I kinit.
+The
+.I toehold
+login procedure will log you into
+Kerberos
+automatically.
+You will need to use
+.I kinit
+only in those situations in which
+your original tickets have expired.
+(Tickets expire in about a day.)
+Note as well that
+.I toehold
+will automatically destroy your tickets when you logout from the workstation.
+.PP
+When you use
+.I kinit
+without options,
+the utility
+prompts for your username and Kerberos password,
+and tries to authenticate your login with the local
+Kerberos
+server.
+.PP
+If
+Kerberos
+authenticates the login attempt,
+.I kinit
+retrieves your initial ticket and puts it in the ticket file specified by
+your KRBTKFILE environment variable.
+If this variable is undefined,
+your ticket will be stored in the
+.IR /tmp
+directory,
+in the file
+.I tktuid ,
+where
+.I uid
+specifies your user identification number.
+.PP
+If you have logged in to
+Kerberos
+without the benefit of the workstation
+.I toehold
+system,
+make sure you use the
+.I kdestroy
+command to destroy any active tickets before you end your login session.
+You may want to put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+.PP
+The options to
+.I kinit
+are as follows:
+.TP 7
+.B \-i
+.I kinit
+prompts you for a
+Kerberos
+instance.
+.TP
+.B \-r
+.I kinit
+prompts you for a
+Kerberos
+realm.
+This option lets you authenticate yourself with a remote
+Kerberos
+server.
+.TP
+.B \-v
+Verbose mode.
+.I kinit
+prints the name of the ticket file used, and
+a status message indicating the success or failure of
+your login attempt.
+.TP
+.B \-l
+.I kinit
+prompts you for a ticket lifetime in minutes. Due to protocol
+restrictions in Kerberos Version 4, this value must be between 5 and
+1275 minutes.
+.SH SEE ALSO
+.PP
+kerberos(1), kdestroy(1), klist(1), toehold(1)
+.SH BUGS
+The
+.B \-r
+option has not been fully implemented.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
diff --git a/eBones/man/klist.1 b/eBones/man/klist.1
new file mode 100644
index 0000000..a66e668
--- /dev/null
+++ b/eBones/man/klist.1
@@ -0,0 +1,84 @@
+.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $
+.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+klist \- list currently held Kerberos tickets
+.SH SYNOPSIS
+.B klist
+[
+\fB\-s \fR|\fB \-t\fR
+] [
+.B \-file
+name ] [
+.B \-srvtab
+]
+.br
+.SH DESCRIPTION
+.I klist
+prints the name of the tickets file and the
+identity of the principal the tickets are for (as listed in the
+tickets file), and
+lists the principal names of all Kerberos tickets currently held by
+the user, along with the issue and expire time for each authenticator.
+Principal names are listed in the form
+.I name.instance@realm,
+with the '.' omitted if the instance is null,
+and the '@' omitted if the realm is null.
+
+If given the
+.B \-s
+option,
+.I klist
+does not print the issue and expire times, the name of the tickets file,
+or the identity of the principal.
+
+If given the
+.B \-t
+option,
+.B klist
+checks for the existence of a non-expired ticket-granting-ticket in the
+ticket file. If one is present, it exits with status 0, else it exits
+with status 1. No output is generated when this option is specified.
+
+If given the
+.B \-file
+option, the following argument is used as the ticket file.
+Otherwise, if the
+.B KRBTKFILE
+environment variable is set, it is used.
+If this environment variable
+is not set, the file
+.B /tmp/tkt[uid]
+is used, where
+.B uid
+is the current user-id of the user.
+
+If given the
+.B \-srvtab
+option, the file is treated as a service key file, and the names of the
+keys contained therein are printed. If no file is
+specified with a
+.B \-file
+option, the default is
+.IR /etc/srvtab .
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm
+.TP
+/tmp/tkt[uid]
+as the default ticket file ([uid] is the decimal UID of the user).
+.TP
+/etc/srvtab
+as the default service key file
+.SH SEE ALSO
+.PP
+kerberos(1), kinit(1), kdestroy(1)
+.SH BUGS
+When reading a file as a service key file, very little sanity or error
+checking is performed.
diff --git a/eBones/man/klogind.8 b/eBones/man/klogind.8
new file mode 100644
index 0000000..459cd26
--- /dev/null
+++ b/eBones/man/klogind.8
@@ -0,0 +1,122 @@
+.\" from: klogind.8,v 4.1 89/01/23 11:39:30 jtkohl Exp $
+.\" $Id: klogind.8,v 1.2 1994/07/19 19:27:39 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)rlogind.8 6.4 (Berkeley) 9/19/88
+.\"
+.TH KLOGIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.UC 5
+.SH NAME
+klogind \- remote login server
+.SH SYNOPSIS
+.B /usr/etc/klogind
+.br
+.B /usr/etc/Klogind
+.br
+.B /usr/etc/eklogind
+.SH DESCRIPTION
+.I Klogind
+is the server for the Kerberos version of the
+.IR rlogin (1)
+program. The server provides a remote login facility
+with authentication provided by Kerberos.
+.PP
+.I Klogind
+listens for service requests at the port indicated in
+the ``klogin'' or ``eklogin'' service specification; see
+.IR services (5).
+.PP
+Invocation as Klogind is intended for secure
+hosts to which no password access will be granted; invocation as klogind
+is intended for normal hosts to which password access may be granted if
+Kerberos authorization fails; invocation as eklogind provides an
+encrypted communications channel. A host can run either Klogind or
+klogind but not both (they use the same port, ``klogin''). Eklogind may
+be run independently.
+.PP
+When a service request is received, the server checks the client's
+source address and requests the corresponding host name (see
+.IR gethostbyaddr (3N),
+.IR hosts (5)
+and
+.IR named (8)).
+If the hostname cannot be determined,
+the dot-notation representation of the host address is used.
+.PP
+Once the source address has been checked,
+.I klogind
+allocates a pseudo terminal (see
+.IR pty (4)),
+and manipulates file descriptors so that the slave
+half of the pseudo terminal becomes the
+.B stdin ,
+.B stdout ,
+and
+.B stderr
+for a login process.
+The login process is an instance of the
+.IR login (1)
+program, invoked with the
+.B \-k,
+.B \-K,
+or
+.B \-e
+option, depending on whether the klogind was started as klogind, Klogind
+or eklogind, respectively.
+The login process then proceeds with the
+authentication process as described in
+.IR kshd (8),
+but if automatic authentication fails, it reprompts the user
+to login as one finds on a standard terminal line.
+.PP
+The parent of the login process manipulates the master side of
+the pseudo terminal, operating as an intermediary
+between the login process and the client instance of the
+.I rlogin
+program. If klogind is invoked as eklogind, all data passed over
+the network are encrypted.
+In normal operation, the packet protocol described
+in
+.IR pty (4)
+is invoked to provide ^S/^Q type facilities and propagate
+interrupt signals to the remote programs. The login process
+propagates the client terminal's baud rate and terminal type,
+as found in the environment variable, ``TERM''; see
+.IR environ (7).
+The screen or window size of the terminal is requested from the client,
+and window size changes from the client are propagated to the pseudo terminal.
+.SH DIAGNOSTICS
+All diagnostic messages are returned on the connection
+associated with the
+.BR stderr ,
+after which any network connections are closed.
+An error is indicated by a leading byte with a value of 1.
+.PP
+.B ``Try again.''
+.br
+A
+.I fork
+by the server failed.
+.PP
+.B ``/bin/sh: ...''
+.br
+The user's login shell could not be started.
+.SH SEE ALSO
+kerberos(3)
+.SH BUGS
+.PP
+A more extensible protocol should be used.
diff --git a/eBones/man/kpasswd.1 b/eBones/man/kpasswd.1
new file mode 100644
index 0000000..2283f1f
--- /dev/null
+++ b/eBones/man/kpasswd.1
@@ -0,0 +1,86 @@
+.\" from: kpasswd.1,v 4.2 89/07/25 17:23:08 jtkohl Exp $
+.\" $Id: kpasswd.1,v 1.2 1994/07/19 19:27:40 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KPASSWD 1 "Kerberos Version 4.0" "MIT Project Athena"
+.FM mit
+.SH NAME
+kpasswd \- change a user's Kerberos password
+.SH SYNOPSIS
+.B kpasswd
+[
+.B \-h
+] [
+.B \-n
+.I name
+] [
+.B \-i
+.I instance
+] [
+.B \-r
+.I realm
+] [
+\-u
+.IR username[.instance][@realm] ]
+.SH DESCRIPTION
+The
+.I kpasswd
+command is used to change a Kerberos principal's password.
+.PP
+If the
+.I \-h
+option is specified, a brief summary of the options is printed, and
+.I kpasswd
+then exits.
+.PP
+If the
+.I \-n
+option is specified,
+.I name
+is used as the principal name rather than the username of the user
+running
+.IR kpasswd .
+(This is determined from the ticket file if it exists;
+otherwise, it is determined from the unix user id.)
+.PP
+If the
+.I \-i
+option is specified,
+.I instance
+is used as the instance rather than a null instance.
+.PP
+If the
+.I \-r
+option is specified,
+.I realm
+is used as the realm rather than the local realm.
+.PP
+If the
+.I \-u
+option is specified, a fully qualified kerberos
+principal can be given.
+.PP
+
+The utility prompts for the current Kerberos password (printing
+the name of the principal for which it intends to change the password),
+which is verified by the Kerberos server. If the old password is
+correct, the user is prompted twice for the new password. A message is
+printed indicating the success or failure of the password changing
+operation.
+
+.SH BUGS
+
+.I kpasswd
+does not handle names, instances, or realms with special
+characters in them when the -n, -i, or -r options are used. Any
+valid fullname is accepted, however, if the -u option is used.
+
+If the principal whose password you are trying to change does
+not exist, you will not be told until after you have entered the
+old password.
+
+.SH SEE ALSO
+kerberos(1), kinit(1), passwd(1), kadmin(8)
diff --git a/eBones/man/krb.conf.5 b/eBones/man/krb.conf.5
new file mode 100644
index 0000000..ac977bb
--- /dev/null
+++ b/eBones/man/krb.conf.5
@@ -0,0 +1,32 @@
+.\" from: krb.conf.5,v 4.1 89/01/23 11:10:34 jtkohl Exp $
+.\" $Id: krb.conf.5,v 1.2 1994/07/19 19:27:43 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB.CONF 5 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+/etc/krb.conf \- Kerberos configuration file
+.SH DESCRIPTION
+.I krb.conf
+contains configuration information describing the Kerberos realm and the
+Kerberos key distribution center (KDC) servers for known realms.
+.PP
+.I krb.conf
+contains the name of the local realm in the first
+line, followed by lines indicating realm/host
+entries. The first token is a realm name, and the second is the hostname
+of a host running a KDC for that realm.
+The words "admin server" following the hostname indicate that
+the host also provides an administrative database server.
+For example:
+.nf
+.in +1i
+ATHENA.MIT.EDU
+ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ATHENA.MIT.EDU kerberos-2.mit.edu
+LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+.in -1i
+.SH SEE ALSO
+krb.realms(5), krb_get_krbhst(3), krb_get_lrealm(3)
diff --git a/eBones/man/krb.realms.5 b/eBones/man/krb.realms.5
new file mode 100644
index 0000000..90226a9
--- /dev/null
+++ b/eBones/man/krb.realms.5
@@ -0,0 +1,39 @@
+.\" from: krb.realms.5,v 4.1 89/01/23 11:10:41 jtkohl Exp $
+.\" $Id: krb.realms.5,v 1.2 1994/07/19 19:27:45 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB.REALMS 5 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+/etc/krb.realms \- host to Kerberos realm translation file
+.SH DESCRIPTION
+.I krb.realms
+provides a translation from a hostname to the Kerberos realm name for
+the services provided by that host.
+.PP
+Each line of the translation file is in one of the following forms
+(domain_name should be of the form .XXX.YYY, e.g. .LCS.MIT.EDU):
+.nf
+.in +5n
+host_name kerberos_realm
+domain_name kerberos_realm
+.in -5n
+.fi
+If a hostname exactly matches the
+.I host_name
+field in a line of the first
+form, the corresponding realm is the realm of the host.
+If a hostname does not match any
+.I host_name
+in the file, but its
+domain exactly matches the
+.I domain_name
+field in a line of the second
+form, the corresponding realm is the realm of the host.
+.PP
+If no translation entry applies, the host's realm is considered to be
+the hostname's domain portion converted to upper case.
+.SH SEE ALSO
+krb_realmofhost(3)
diff --git a/eBones/man/krb_realmofhost.3 b/eBones/man/krb_realmofhost.3
new file mode 100644
index 0000000..f284069
--- /dev/null
+++ b/eBones/man/krb_realmofhost.3
@@ -0,0 +1,161 @@
+.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
+.\" $Id: krb_realmofhost.3,v 1.2 1994/07/19 19:27:46 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question. In order to prevent certain security attacks, this routine
+must either have
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+The configuration file is described by
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned. If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports
+.I n
+= 1. It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/eBones/man/krb_sendauth.3 b/eBones/man/krb_sendauth.3
new file mode 100644
index 0000000..f5e95b7
--- /dev/null
+++ b/eBones/man/krb_sendauth.3
@@ -0,0 +1,348 @@
+.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
+.\" $Id: krb_sendauth.3,v 1.2 1994/07/19 19:27:47 g89r4222 Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated. They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters. It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <mit-copyright.h>.
diff --git a/eBones/man/krb_set_tkt_string.3 b/eBones/man/krb_set_tkt_string.3
new file mode 100644
index 0000000..c9f3dcf
--- /dev/null
+++ b/eBones/man/krb_set_tkt_string.3
@@ -0,0 +1,43 @@
+.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $
+.\" $Id: krb_set_tkt_string.3,v 1.2 1994/07/19 19:27:49 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_set_tkt_string \- set Kerberos ticket cache file name
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+void krb_set_tkt_string(filename)
+char *filename;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_set_tkt_string
+sets the name of the file that holds the user's
+cache of Kerberos server tickets and associated session keys.
+.PP
+The string
+.I filename
+passed in is copied into local storage.
+Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
+copied in for use as the cache file name.
+.PP
+This routine should be called during initialization, before other
+Kerberos routines are called; otherwise the routines which fetch the
+ticket cache file name may be called and return an undesired ticket file
+name until this routine is called.
+.SH FILES
+.TP 20n
+/tmp/tkt[uid]
+default ticket file name, unless the environment variable KRBTKFILE is set.
+[uid] denotes the user's uid, in decimal.
+.SH SEE ALSO
+kerberos(3), setenv(3)
diff --git a/eBones/man/ksend.point b/eBones/man/ksend.point
new file mode 100644
index 0000000..2dbe5de
--- /dev/null
+++ b/eBones/man/ksend.point
@@ -0,0 +1 @@
+.so man3/krb_sendauth.3
diff --git a/eBones/man/kshd.8 b/eBones/man/kshd.8
new file mode 100644
index 0000000..e1ecc22
--- /dev/null
+++ b/eBones/man/kshd.8
@@ -0,0 +1,152 @@
+.\" from: kshd.8,v 4.1 89/01/23 11:39:41 jtkohl Exp $
+.\" $Id: kshd.8,v 1.2 1994/07/19 19:27:50 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)rshd.8 6.5 (Berkeley) 9/19/88
+.\"
+.TH KSHD 8 "Kerberos Version 4.0" "MIT Project Athena"
+.UC 5
+.SH NAME
+kshd \- remote shell server
+.SH SYNOPSIS
+.B /usr/etc/kshd
+.SH DESCRIPTION
+.I Kshd
+is the server for the
+.IR kcmd (3)
+routine and, consequently, for the
+.IR rsh (1)
+program. The server provides remote execution facilities
+with authentication based on Kerberos.
+.PP
+.I Kshd
+listens for service requests at the port indicated in
+the ``kshell'' service specification; see
+.IR services (5).
+When a service request is received the following protocol
+is initiated:
+.IP 1)
+The server reads characters from the socket up
+to a null (`\e0') byte. The resultant string is
+interpreted as an ASCII number, base 10.
+.IP 2)
+If the number received in step 1 is non-zero,
+it is interpreted as the port number of a secondary
+stream to be used for the
+.BR stderr .
+A second connection is then created to the specified
+port on the client's machine.
+.IP 3)
+The server checks the client's source address
+and requests the corresponding host name (see
+.IR gethostbyaddr (3N),
+.IR hosts (5)
+and
+.IR named (8)).
+If the hostname cannot be determined,
+the dot-notation representation of the host address is used.
+.IP 4)
+A Kerberos ticket/authenticator pair are retrieved on the initial socket.
+.IP 5)
+A null terminated user name of at most 16 characters
+is retrieved on the initial socket. This user name
+is interpreted as a user identity to use on the
+.BR server 's
+machine.
+.IP 6)
+A null terminated command to be passed to a
+shell is retrieved on the initial socket. The length of
+the command is limited by the upper bound on the size of
+the system's argument list.
+.IP 7)
+.I Kshd
+then validates the user according to the following steps.
+The local (server-end) user name is looked up in the password file
+and a
+.I chdir
+is performed to the user's home directory. If either
+the lookup or
+.I chdir
+fail, the connection is terminated. The \&.klogin file in the home
+directory is used to mediate access to the account (via \fIkuserok\fP(3))
+by the Kerberos principal named in the ticket/authenticator. If this
+authorization check fails, the connection is terminated.
+.IP 8)
+A null byte is returned on the initial socket
+and the command line is passed to the normal login
+shell of the user. The
+shell inherits the network connections established
+by
+.IR kshd .
+.SH DIAGNOSTICS
+Except for the last one listed below,
+all diagnostic messages
+are returned on the initial socket,
+after which any network connections are closed.
+An error is indicated by a leading byte with a value of
+1 (0 is returned in step 8 above upon successful completion
+of all the steps prior to the execution of the login shell).
+.PP
+.B ``remuser too long''
+.br
+The name of the user on the remote machine is
+longer than 16 characters.
+.PP
+.B ``command too long ''
+.br
+The command line passed exceeds the size of the argument
+list (as configured into the system).
+.PP
+.B ``Login incorrect.''
+.br
+No password file entry for the user name existed.
+.PP
+.B ``No remote directory.''
+.br
+The
+.I chdir
+command to the home directory failed.
+.PP
+.B ``Permission denied.''
+.br
+The authorization procedure described above failed.
+.PP
+.B ``Can't make pipe.''
+.br
+The pipe needed for the
+.BR stderr ,
+wasn't created.
+.PP
+.B ``Try again.''
+.br
+A
+.I fork
+by the server failed.
+.PP
+.B ``<shellname>: ...''
+.br
+The user's login shell could not be started. This message is returned
+on the connection associated with the
+.BR stderr ,
+and is not preceded by a flag byte.
+.SH SEE ALSO
+rsh(1), kerberos(3), kuserok(3)
+.SH BUGS
+A facility to allow all data exchanges to be encrypted should be
+present.
+.PP
+A more extensible protocol should be used.
diff --git a/eBones/man/ksrvtgt.1 b/eBones/man/ksrvtgt.1
new file mode 100644
index 0000000..25fd939
--- /dev/null
+++ b/eBones/man/ksrvtgt.1
@@ -0,0 +1,51 @@
+.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $
+.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a
+service key
+.SH SYNOPSIS
+.B ksrvtgt
+name instance [[realm] srvtab]
+.SH DESCRIPTION
+.I ksrvtgt
+retrieves a ticket-granting ticket with a lifetime of five (5) minutes
+for the principal
+.I name.instance@realm
+(or
+.I name.instance@localrealm
+if
+.I realm
+is not supplied on the command line), decrypts the response using
+the service key found in
+.I srvtab
+(or in
+.B /etc/srvtab
+if
+.I srvtab
+is not specified on the command line), and stores the ticket in the
+standard ticket cache.
+.PP
+This command is intended primarily for use in shell scripts and other
+batch-type facilities.
+.SH DIAGNOSTICS
+"Generic kerberos failure (kfailure)" can indicate a whole range of
+problems, the most common of which is the inability to read the service
+key file.
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm.
+.TP
+/tmp/tkt[uid]
+The default ticket file.
+.TP
+/etc/srvtab
+The default service key file.
+.SH SEE ALSO
+kerberos(1), kinit(1), kdestroy(1)
diff --git a/eBones/man/ksrvutil.8 b/eBones/man/ksrvutil.8
new file mode 100644
index 0000000..a7fed82
--- /dev/null
+++ b/eBones/man/ksrvutil.8
@@ -0,0 +1,93 @@
+.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $
+.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvutil \- host kerberos keyfile (srvtab) manipulation utility
+.SH SYNOPSIS
+ksrvutil
+.B operation
+[
+.B \-k
+] [
+.B \-i
+] [
+.B \-f filename
+]
+.SH DESCRIPTION
+.I ksrvutil
+allows a system manager to list or change keys currently in his
+keyfile or to add new keys to the keyfile.
+.PP
+
+Operation must be one of the following:
+.TP 10n
+.I list
+lists the keys in a keyfile showing version number and principal
+name. If the \-k option is given, keys will also be shown.
+.TP 10n
+.I change
+changes all the keys in the keyfile by using the regular admin
+protocol. If the \-i flag is given,
+.I ksrvutil
+will prompt for yes or no before changing each key. If the \-k
+option is used, the old and new keys will be displayed.
+.TP 10n
+.I add
+allows the user to add a key.
+.I add
+prompts for name, instance, realm, and key version number, asks
+for confirmation, and then asks for a password.
+.I ksrvutil
+then converts the password to a key and appends the keyfile with
+the new information. If the \-k option is used, the key is
+displayed.
+
+.PP
+In all cases, the default file used is KEY_FILE as defined in
+krb.h unless this is overridden by the \-f option.
+
+.PP
+A good use for
+.I ksrvutil
+would be for adding keys to a keyfile. A system manager could
+ask a kerberos administrator to create a new service key with
+.IR kadmin (8)
+and could supply an initial password. Then, he could use
+.I ksrvutil
+to add the key to the keyfile and then to change the key so that
+it will be random and unknown to either the system manager or
+the kerberos administrator.
+
+.I ksrvutil
+always makes a backup copy of the keyfile before making any
+changes.
+
+.SH DIAGNOSTICS
+If
+.I ksrvutil
+should exit on an error condition at any time during a change or
+add, a copy of the
+original keyfile can be found in
+.IR filename .old
+where
+.I filename
+is the name of the keyfile, and a copy of the file with all new
+keys changed or added so far can be found in
+.IR filename .work.
+The original keyfile is left unmodified until the program exits
+at which point it is removed and replaced it with the workfile.
+Appending the workfile to the backup copy and replacing the
+keyfile with the result should always give a usable keyfile,
+although the resulting keyfile will have some out of date keys
+in it.
+
+.SH SEE ALSO
+kadmin(8), ksrvtgt(1)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/man/kstash.8 b/eBones/man/kstash.8
new file mode 100644
index 0000000..d83379a
--- /dev/null
+++ b/eBones/man/kstash.8
@@ -0,0 +1,41 @@
+.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $
+.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kstash \- stash Kerberos key distribution center database master key
+.SH SYNOPSIS
+kstash
+.SH DESCRIPTION
+.I kstash
+saves the Kerberos key distribution center (KDC) database master key in
+the master key cache file.
+.PP
+The user is prompted to enter the key, to verify the authenticity of the
+key and the authorization to store the key in the file.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.TP
+"kstash: Unable to open master key file"
+The attempt to open the cache file for writing failed (probably due to a
+system or access permission error).
+.TP
+"kstash: Write I/O error on master key file"
+The
+.BR write (2)
+system call returned an error while
+.I kstash
+was attempting to write the key to the file.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/man/ksu.1 b/eBones/man/ksu.1
new file mode 100644
index 0000000..fe434d3
--- /dev/null
+++ b/eBones/man/ksu.1
@@ -0,0 +1,83 @@
+.\" from: ksu.1,v 4.1 89/01/23 11:38:16 jtkohl Exp $
+.\" $Id: ksu.1,v 1.2 1994/07/19 19:27:57 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1988 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)su.1 6.7 (Berkeley) 12/7/88
+.\"
+.TH KSU 1 "Kerberos Version 4.0" "MIT Project Athena"
+.UC
+.SH NAME
+ksu \- substitute user id, using Kerberos
+.SH SYNOPSIS
+.B ksu
+[-flm] [login]
+.SH DESCRIPTION
+\fIKsu\fP requests the password for \fIlogin\fP (or for ``root'', if no
+login is provided), and switches to that user and group ID. A shell is
+then invoked.
+.PP
+By default, your environment is unmodified with the exception of
+\fIUSER\fP, \fIHOME\fP, and \fISHELL\fP. \fIHOME\fP and \fISHELL\fP
+are set to the target login's \fI/etc/passwd\fP values. \fIUSER\fP
+is set to the target login, unless the target login has a UID of 0,
+in which case it is unmodified. The invoked shell is the target
+login's. This is the traditional behavior of \fIksu\fP.
+.PP
+The \fI-l\fP option simulates a full login. The environment is discarded
+except for \fIHOME\fP, \fISHELL\fP, \fIPATH\fP, \fITERM\fP, and \fIUSER\fP.
+\fIHOME\fP and \fISHELL\fP are modified as above. \fIUSER\fP is set to
+the target login. \fIPATH\fP is set to ``/usr/ucb:/bin:/usr/bin''.
+\fITERM\fP is imported from your current environment. The invoked shell
+is the target login's, and \fIksu\fP will change directory to the target
+login's home directory.
+.PP
+The \fI-m\fP option causes the environment to remain unmodified, and
+the invoked shell to be your login shell. No directory changes are
+made. As a security precaution, if the
+.I -m
+option is specified, the target user's shell is a non-standard shell
+(as defined by \fIgetusershell\fP(3)) and the caller's real uid is
+non-zero,
+.I su
+will fail.
+.PP
+If the invoked shell is \fIcsh\fP, the \fI-f\fP option prevents it from
+reading the \fI.cshrc\fP file. Otherwise, this option is ignored.
+.PP
+Only users with root instances listed in /\&.klogin may \fIksu\fP to
+``root'' (The format of this file is described by \fIrlogin\fP(1).). When
+attempting root access, \fIksu\fP attempts to fetch a
+ticket-granting-ticket for ``username.root@localrealm'', where
+\fIusername\fP is the username of the process. If possible, the tickets
+are used to obtain, use, and verify tickets for the service
+``rcmd.host@localrealm'' where \fIhost\fP is the canonical host name (as
+determined by
+.IR krb_get_phost (3))
+of the machine. If this verification
+fails, the \fIksu\fP is disallowed (If the service
+``rcmd.host@localrealm'' is not registered, the \fIksu\fP is allowed.).
+.PP
+By default (unless the prompt is reset by a startup file) the super-user
+prompt is set to ``#'' to remind one of its awesome power.
+.PP
+When not attempting to switch to the ``root'' user,
+.I ksu
+behaves exactly like
+.IR su (1).
+.SH "SEE ALSO"
+su(1), csh(1), login(1), rlogin(1), sh(1), krb_get_phost(3), passwd(5),
+group(5), environ(7)
diff --git a/eBones/man/kuserok.3 b/eBones/man/kuserok.3
new file mode 100644
index 0000000..36968ba
--- /dev/null
+++ b/eBones/man/kuserok.3
@@ -0,0 +1,63 @@
+.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $
+.\" $Id: kuserok.3,v 1.2 1994/07/19 19:27:58 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kuserok \- Kerberos version of ruserok
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+kuserok(kdata, localuser)
+AUTH_DAT *auth_data;
+char *localuser;
+.fi
+.ft R
+.SH DESCRIPTION
+.I kuserok
+determines whether a Kerberos principal described by the structure
+.I auth_data
+is authorized to login as user
+.I localuser
+according to the authorization file
+("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized,
+1 (one) if not authorized.
+.PP
+If there is no account for
+.I localuser
+on the local machine, authorization is not granted.
+If there is no authorization file, and the Kerberos principal described
+by
+.I auth_data
+translates to
+.I localuser
+(using
+.IR krb_kntoln (3)),
+authorization is granted.
+If the authorization file
+can't be accessed, or the file is not owned by
+.IR localuser,
+authorization is denied. Otherwise, the file is searched for
+a matching principal name, instance, and realm. If a match is found,
+authorization is granted, else authorization is denied.
+.PP
+The file entries are in the format:
+.nf
+.in +5n
+ name.instance@realm
+.in -5n
+.fi
+with one entry per line.
+.SH SEE ALSO
+kerberos(3), ruserok(3), krb_kntoln(3)
+.SH FILES
+.TP 20n
+~\fIlocaluser\fR/.klogin
+authorization list
diff --git a/eBones/man/rcp.1 b/eBones/man/rcp.1
new file mode 100644
index 0000000..1f298f6
--- /dev/null
+++ b/eBones/man/rcp.1
@@ -0,0 +1,129 @@
+.\" from: rcp.1,v 4.1 89/01/23 11:39:00 jtkohl Exp $
+.\" $Id: rcp.1,v 1.2 1994/07/19 19:28:00 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)rcp.1 6.6 (Berkeley) 9/20/88
+.\"
+.TH RCP 1 "Kerberos Version 4.0" "MIT Project Athena"
+.UC 5
+.SH NAME
+rcp \- remote file copy
+.SH SYNOPSIS
+.B rcp
+[
+.B \-p
+] [
+.B \-x
+] [
+.B \-k
+realm ] file1 file2
+.br
+.B rcp
+[
+.B \-p
+] [
+.B \-x
+] [
+.B \-k
+realm ] [
+.B \-r
+] file ... directory
+.SH DESCRIPTION
+.I Rcp
+copies files between machines. Each
+.I file
+or
+.I directory
+argument is either a remote file name of the
+form ``rhost:path'', or a local file name (containing no `:' characters,
+or a `/' before any `:'s).
+.PP
+If the
+.B \-r
+option
+is specified and any of the source files are directories,
+.I rcp
+copies each subtree rooted at that name; in this case
+the destination must be a directory.
+.PP
+By default, the mode and owner of
+.I file2
+are preserved if it already existed; otherwise the mode of the source file
+modified by the
+.IR umask (2)
+on the destination host is used.
+The
+.B \-p
+option causes
+.I rcp
+to attempt to preserve (duplicate) in its copies the modification
+times and modes of the source files, ignoring the
+.IR umask .
+.PP
+If
+.I path
+is not a full path name, it is interpreted relative to
+your login directory on
+.IR rhost .
+A
+.I path
+on a remote host may be quoted (using \e, ", or \(aa)
+so that the metacharacters are interpreted remotely.
+.PP
+.I Rcp
+does not prompt for passwords; it uses Kerberos authentication when
+connecting to
+.IR rhost .
+Authorization is as described in
+.IR rlogin (1).
+.PP
+The
+.B \-x
+option selects encryption of all information transferring between hosts.
+The
+.B \-k
+.I realm
+option causes
+.I rcp
+to obtain tickets for the remote host in
+.I realm
+instead of the remote host's realm as determined by
+.IR krb_realmofhost (3).
+.PP
+.I Rcp
+handles third party copies, where neither source nor target files
+are on the current machine.
+Hostnames may also take the form ``rname@rhost'' to use
+.I rname
+rather than the current user name on the remote host.
+.SH SEE ALSO
+cp(1), ftp(1), rsh(1), rlogin(1), kerberos(3), krb_getrealm(3),
+rcp(1) [UCB version]
+.SH BUGS
+Doesn't detect all cases where the target of a copy might
+be a file in cases where only a directory should be legal.
+.PP
+Is confused by any output generated by commands in a
+\&.login, \&.profile, or \&.cshrc file on the remote host.
+.PP
+The destination user and hostname may have to be specified as
+``rhost.rname'' when the destination machine is running the 4.2BSD
+version of \fIrcp\fP.
+.PP
+Kerberos is only used for the first connection of a third-party copy;
+the second connection uses the standard Berkeley rcp protocol.
+
diff --git a/eBones/man/realm.point b/eBones/man/realm.point
new file mode 100644
index 0000000..9c6940f
--- /dev/null
+++ b/eBones/man/realm.point
@@ -0,0 +1 @@
+.so man3/krb_realmofhost.3
diff --git a/eBones/man/rlogin.1 b/eBones/man/rlogin.1
new file mode 100644
index 0000000..3e0dc62
--- /dev/null
+++ b/eBones/man/rlogin.1
@@ -0,0 +1,199 @@
+.\" from: rlogin.1,v 4.2 89/11/02 11:20:39 jtkohl Exp $
+.\" $Id: rlogin.1,v 1.2 1994/07/19 19:28:01 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)rlogin.1 6.9 (Berkeley) 9/19/88
+.\"
+.TH RLOGIN 1 "Kerberos Version 4.0" "MIT Project Athena"
+.UC 5
+.SH NAME
+rlogin \- remote login
+.SH SYNOPSIS
+.B rlogin
+rhost [
+\fB\-e\fR\fI\|c\fR
+] [
+.B \-8
+] [
+.B \-c
+] [
+.B \-a
+] [
+.B \-t
+termtype ] [
+.B \-n
+] [
+.B \-7
+] [
+.B \-d
+] [
+.B \-k
+realm ] [
+.B \-x
+] [
+.B \-noflow
+] [
+.B \-L
+] [
+.B \-l
+username ]
+.br
+rhost [
+\fB\-e\fR\fIc\fR
+] [
+.B \-8
+] [
+.B \-c
+] [
+.B \-a
+] [
+.B \-t
+termtype ] [
+.B \-n
+] [
+.B \-7
+] [
+.B \-d
+] [
+.B \-k
+realm ] [
+.B \-x
+] [
+.B \-noflow
+] [
+.B \-L
+] [
+.B \-l
+username ]
+.SH DESCRIPTION
+.I Rlogin
+connects your terminal on the current local host system
+.I lhost
+to the remote host system
+.I rhost.
+.PP
+The version built to use Kerberos authentication is very similar to the
+standard Berkeley rlogin(1), except that instead of the \fIrhosts\fP
+mechanism, it uses Kerberos authentication to determine the
+authorization to use a remote account.
+.PP
+Each user may have a private authorization list in a file \&.klogin
+in his login directory. Each line in this file should contain a
+Kerberos principal name of the form
+.IR principal.instance@realm .
+If the originating user is authenticated to one of the principals named
+in \&.klogin, access is granted to the account. The principal
+\fIaccountname\fP.@\fIlocalrealm\fP is granted access if there is no
+\&.klogin file.
+Otherwise
+a login and password will be prompted for on the remote machine as in
+.IR login (1).
+To avoid some security problems, the \&.klogin file must be owned by
+the remote user.
+.PP
+If there is some problem in marshaling the Kerberos authentication
+information, an error message is printed and the standard UCB rlogin is
+executed in place of the Kerberos rlogin.
+.PP
+A line of the form ``~.'' disconnects from the remote host, where
+``~'' is the escape character.
+Similarly, the line ``~^Z'' (where ^Z, control-Z, is the suspend character)
+will suspend the rlogin session.
+Substitution of the delayed-suspend character (normally ^Y)
+for the suspend character suspends the send portion of the rlogin,
+but allows output from the remote system.
+.PP
+The remote terminal type is the same as your local
+terminal type (as given in your environment TERM variable), unless the
+.B \-t
+option is specified (see below).
+The terminal or window size is also copied to the remote system
+if the server supports the option,
+and changes in size are reflected as well.
+.PP
+All echoing takes place at the remote site, so that (except for
+delays) the rlogin is transparent. Flow control via ^S and ^Q and
+flushing of input and output on interrupts are handled properly.
+.PP
+The
+.B \-8
+option allows an eight-bit input data path at all times;
+otherwise parity bits are stripped except when the remote side's
+stop and start characters are other than ^S/^Q. Eight-bit mode is the default.
+.PP
+The
+.B \-L
+option allows the rlogin session to be run in litout mode.
+.PP
+The
+.B \-e
+option allows specification of a different escape character.
+There is no space separating this option flag and the new escape
+character.
+.PP
+The
+.B \-c
+option requires confirmation before disconnecting via ``~.''
+.PP
+The
+.B \-a
+option forces the remote machine to ask for a password by sending a null local
+username. This option has no effect unless the standard UCB rlogin is
+executed in place of the Kerberos rlogin (see above).
+.PP
+The
+.B \-t
+option replaces the terminal type passed to the remote host with
+\fItermtype\fP.
+.PP
+The
+.B \-n
+option prevents suspension of rlogin via ``~^Z'' or ``~^Y''.
+.PP
+The
+.B \-7
+option forces seven-bit transmissions.
+.PP
+The
+.B \-d
+option turns on socket debugging (via \fIsetsockopt(2)\fR) on the TCP
+sockets used for communication with the remote host.
+.PP
+The
+.B \-noflow
+option forces transmission of flow control characters (^S/^Q) to the
+remote system.
+.PP
+The
+.B \-k
+option requests rlogin to obtain tickets for the remote host in realm
+.I realm
+instead of the remote host's realm as determined by
+.IR krb_realmofhost (3).
+.PP
+The
+.B \-x
+option turns on DES encryption for all data passed via the
+rlogin session. This significantly reduces response time and
+significantly increases CPU utilization.
+.SH SEE ALSO
+rsh(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3),
+rlogin(1) [UCB version]
+.SH FILES
+/usr/hosts/* for \fIrhost\fP version of the command
+.SH BUGS
+More of the environment should be propagated.
diff --git a/eBones/man/rsh.1 b/eBones/man/rsh.1
new file mode 100644
index 0000000..8d0974c
--- /dev/null
+++ b/eBones/man/rsh.1
@@ -0,0 +1,152 @@
+.\" from: rsh.1,v 4.1 89/01/23 11:39:11 jtkohl Exp $
+.\" $Id: rsh.1,v 1.2 1994/07/19 19:28:03 g89r4222 Exp $
+.\"
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)rsh.1 6.2 (Berkeley) 9/20/88
+.\"
+.TH RSH 1 "Kerberos Version 4.0" "MIT Project Athena"
+.UC 5
+.SH NAME
+rsh \- remote shell
+.SH SYNOPSIS
+.B rsh
+host
+[
+.B \-l
+username
+] [
+.B \-n
+] [
+.B \-d
+] [
+.B \-k
+realm ] command
+.br
+host
+[
+.B \-l
+username
+] [
+.B \-n
+] [
+.B \-d
+] [
+.B \-k
+realm ] command
+.SH DESCRIPTION
+.I Rsh
+connects to the specified
+.I host,
+and executes the specified \fIcommand\fR.
+.I Rsh
+copies its standard input to the remote command, the standard
+output of the remote command to its standard output, and the
+standard error of the remote command to its standard error.
+Interrupt, quit and terminate signals are propagated to the remote
+command; \fIrsh\fP normally terminates when the remote command does.
+.PP
+The remote username used is the same as your local username,
+unless you specify a different remote name with the
+.B \-l
+option.
+Kerberos authentication is used, and authorization is determined as in
+rlogin(1).
+.PP
+The
+.B \-k
+\fIrealm\fP option causes
+.I rsh
+to obtain tickets for the remote host in
+.I realm
+instead of the remote host's realm as determined by
+.IR krb_realmofhost (3).
+.PP
+The
+.B \-d
+option turns on socket debugging (via \fIsetsockopt(2)\fR) on the TCP
+sockets used for communication with the remote host.
+.PP
+The
+.B \-n
+option redirects input from the special device
+.I /dev/null
+(see the BUGS section below).
+.PP
+If you omit
+.I command,
+then instead of executing a single command, you will be logged in
+on the remote host using
+.IR rlogin (1).
+.PP
+Shell metacharacters which are not quoted are interpreted
+on local machine, while quoted metacharacters are interpreted on
+the remote machine.
+Thus the command
+.PP
+\ \ \ rsh otherhost cat remotefile >> localfile
+.PP
+appends the remote file
+.I remotefile
+to the local file
+.I localfile,
+while
+.PP
+\ \ \ rsh otherhost cat remotefile ">>" otherremotefile
+.PP
+appends
+.I remotefile
+to
+.I otherremotefile.
+.PP
+The host names for local machines are also commands in the directory
+/usr/hosts; if you put this directory in your search path
+then the
+.B rsh
+on the command line can be omitted.
+.SH FILES
+.ta 2i
+/etc/hosts
+.br
+/usr/hosts/*
+.DT
+.SH SEE ALSO
+rlogin(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3)
+.SH BUGS
+If you are using
+.IR csh (1)
+and put a
+.IR rsh (1)
+in the background without redirecting its input
+away from the terminal, it will block even if no reads
+are posted by the remote command. If no input is desired
+you should redirect the input of
+.I rsh
+to /dev/null using the
+.B \-n
+option.
+.PP
+You cannot run an interactive command
+(like
+.IR rogue (6)
+or
+.IR vi (1));
+use
+.IR rlogin (1).
+.PP
+Stop signals stop the local \fIrsh\fP process only; this is arguably
+wrong, but currently hard to fix for reasons too complicated to
+explain here.
diff --git a/eBones/man/tcom.8 b/eBones/man/tcom.8
new file mode 100644
index 0000000..23317cc
--- /dev/null
+++ b/eBones/man/tcom.8
@@ -0,0 +1,54 @@
+.\" from: tcom.8,v 4.2 89/05/03 14:34:53 jtkohl Exp $
+.\" $Id: tcom.8,v 1.2 1994/07/19 19:28:04 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TCOM 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tcom \- control operation of server tftp daemon
+.SH SYNOPSIS
+tcom
+.SH DESCRIPTION
+.I Tcom
+is a program to control the execution of the server trivial file transfer
+daemon. It sends user commands to the daemon by writing them into a
+shared file and signalling the daemon; it watches the daemon's log to
+obtain the results of the commands. The following commands are supported:
+.TP 20
+help
+display a list of commands
+.TP
+input trace on|off
+turn tracing of input packets on or off
+.TP
+output trace on|off
+turn tracing of output packets on or off
+.TP
+trace on|off
+turn all packet tracing on or off
+.TP
+times
+display server parent and children process times
+.TP
+uptime
+display daemon up time
+.TP
+exit
+force daemon to shut down and exit
+.SH FILES
+.TP 20
+/tftpd/lock
+lock file containing daemon's PID
+.TP
+/tftpd/command
+command file to daemon
+.TP
+/tftpd/slog
+daemon's log file
+.SH "SEE ALSO"
+tftpd (8)
+.SH BUGS
+Two tcom's running at the same time will result in chaos. Also,
+watching the daemon's log file uses a lot of CPU time.
diff --git a/eBones/man/tf_util.3 b/eBones/man/tf_util.3
new file mode 100644
index 0000000..3a9bc94
--- /dev/null
+++ b/eBones/man/tf_util.3
@@ -0,0 +1,151 @@
+.\" from: tf_util.3,v 4.2 89/04/25 17:17:11 jtkohl Exp $
+.\" $Id: tf_util.3,v 1.2 1994/07/19 19:28:05 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TF_UTIL 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tf_init, tf_get_pname, tf_get_pinst, tf_get_cred, tf_close \
+\- Routines for manipulating a Kerberos ticket file
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+tf_init(tf_name, rw)
+char *tf_name;
+int rw;
+.PP
+.ft B
+tf_get_pname(pname)
+char *pname;
+.PP
+.ft B
+tf_get_pinst(pinst)
+char *pinst;
+.PP
+.ft B
+tf_get_cred(c)
+CREDENTIALS *c;
+.PP
+.ft B
+tf_close()
+.PP
+.fi
+.SH DESCRIPTION
+This group of routines are provided to manipulate the Kerberos tickets
+file. A ticket file has the following format:
+.nf
+.in +4
+.sp
+principal's name (null-terminated string)
+principal's instance (null-terminated string)
+CREDENTIAL_1
+CREDENTIAL_2
+ ...
+CREDENTIAL_n
+EOF
+.sp
+.in -4
+.LP
+Where "CREDENTIAL_x" consists of the following fixed-length
+fields from the CREDENTIALS structure (defined in <krb.h>):
+.nf
+.sp
+.in +4
+ char service[ANAME_SZ]
+ char instance[INST_SZ]
+ char realm[REALM_SZ]
+ des_cblock session
+ int lifetime
+ int kvno
+ KTEXT_ST ticket_st
+ long issue_date
+.in -4
+.sp
+.fi
+.PP
+.I tf_init
+must be called before the other ticket file
+routines.
+It takes the name of the ticket file to use,
+and a read/write flag as arguments.
+It tries to open the ticket file, checks the mode and if
+everything is okay, locks the file. If it's opened for
+reading, the lock is shared. If it's opened for writing,
+the lock is exclusive.
+KSUCCESS is returned if all went well, otherwise one of the
+following:
+.nf
+.sp
+NO_TKT_FIL - file wasn't there
+TKT_FIL_ACC - file was in wrong mode, etc.
+TKT_FIL_LCK - couldn't lock the file, even after a retry
+.sp
+.fi
+.PP
+The
+.I tf_get_pname
+reads the principal's name from a ticket file.
+It should only be called after tf_init has been called. The
+principal's name is filled into the
+.I pname
+parameter. If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If the principal's name was null, or EOF was encountered, or the
+name was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+.PP
+The
+.I tf_get_pinst
+reads the principal's instance from a ticket file.
+It should only be called after tf_init and tf_get_pname
+have been called.
+The principal's instance is filled into the
+.I pinst
+parameter.
+If all goes
+well, KSUCCESS is returned.
+If tf_init wasn't called, TKT_FIL_INI
+is returned.
+If EOF was encountered, or the
+name was longer than INST_SZ, TKT_FIL_FMT is returned.
+Note that, unlike the principal name, the instance name may be null.
+.PP
+The
+.I tf_get_cred
+routine reads a CREDENTIALS record from a ticket file and
+fills in the given structure.
+It should only be called after
+tf_init, tf_get_pname, and tf_get_pinst have been called.
+If all goes well, KSUCCESS is returned. Possible error codes
+are:
+.nf
+.sp
+TKT_FIL_INI - tf_init wasn't called first
+TKT_FIL_FMT - bad format
+EOF - end of file encountered
+.sp
+.fi
+.PP
+.I tf_close
+closes the ticket file and releases the lock on it.
+.SH "SEE ALSO"
+krb(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The ticket file routines have to be called in a certain order.
+.SH AUTHORS
+Jennifer Steiner, MIT Project Athena
+.br
+Bill Bryant, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1987 Massachusetts Institute of Technology
diff --git a/eBones/man/tftp.1 b/eBones/man/tftp.1
new file mode 100644
index 0000000..4abd7ac
--- /dev/null
+++ b/eBones/man/tftp.1
@@ -0,0 +1,66 @@
+.\" from: tftp.1,v 4.1 89/01/23 11:36:23 jtkohl Exp $
+.\" $Id: tftp.1,v 1.2 1994/07/19 19:28:07 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TFTP 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tftp \- trivial file transfer protocol
+.SH SYNOPSIS
+.B tftp
+-action localname host foreignname [mode]
+.SH DESCRIPTION
+If
+.I action
+is
+.B w,
+.B p,
+or
+.B ap,
+.I tftp
+writes the local file, called localname, onto the foreign host's
+file system as foreignname. If
+.I action
+is
+.B ap,
+Kerberos authentication is used.
+Note that foreignname must be quoted if it
+contains shell special characters. If
+.I action
+is
+.B r,
+.B g,
+or
+.B ag,
+.I tftp
+reads foreign host's file foreignname into the local file,
+localname. If
+.I action
+is
+.B ag,
+Kerberos authentication is used.
+.I Tftp
+will not supersede or overwrite existing local files, however; to do so,
+use
+.I action
+.B o.
+.sp 2
+.I Mode
+may be
+.B netascii,
+or
+.B image.
+Netascii, the default mode, transfers
+the file as standard ascii characters. Image mode transfers
+the file in binary, with no character conversion.
+.sp 1
+If Kerberos authentication is not used with
+.B tftp,
+access will be denied unless the remote and local host are on the same
+local-area network.
+.SH "SEE ALSO"
+.nf
+\fIInternet Protocol Handbook\fR
+kerberosintro(1)
diff --git a/eBones/man/tftpd.8 b/eBones/man/tftpd.8
new file mode 100644
index 0000000..22a7fe8
--- /dev/null
+++ b/eBones/man/tftpd.8
@@ -0,0 +1,39 @@
+.\" from: tftpd.8,v 4.1 89/01/23 11:36:12 jtkohl Exp $
+.\" $Id: tftpd.8,v 1.2 1994/07/19 19:28:08 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH TFTPD 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+tftpd \- server tftp daemon
+.SH SYNOPSIS
+.B /etc/tftpd
+.SH DESCRIPTION
+.I Tftpd
+is a daemon which runs the trivial file transfer protocol server for the
+MIT Internet software. It listens for incoming connections, and forks a
+child to perform each requested transfer. It uses the directory
+.IR /tftpd ;
+the file
+.I lock
+in that directory is used to prevent two daemons from becoming
+active simultaneously; it also contains the daemon's process ID,
+which is used by the tftp command program
+.IR tcom (8)
+to control the daemon's operation.
+.SH FILES
+.br
+.TP 20n
+/tftpd/lock
+interlock, PID storage
+.TP
+/dev/net
+the network device
+.i0
+.dt
+.SH "SEE ALSO"
+tftp (1), tcom (8)
+.br
+\fIInternet Protocol Handbook\fR
diff --git a/eBones/patchlevel.h b/eBones/patchlevel.h
new file mode 100644
index 0000000..836f08e
--- /dev/null
+++ b/eBones/patchlevel.h
@@ -0,0 +1,6 @@
+/*-
+ * $Id: patchlevel.h,v 1.2 1994/07/19 19:21:10 g89r4222 Exp $
+ */
+
+#define PATCHLEVEL 9
+#define FreeBSD_PL 0.1
diff --git a/eBones/register/Makefile b/eBones/register/Makefile
new file mode 100644
index 0000000..3ab09c3
--- /dev/null
+++ b/eBones/register/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+# $Id: Makefile,v 1.4 1994/07/20 09:21:07 g89r4222 Exp $
+
+PROG= register
+SRCS= register.c
+CFLAGS+=-DCRYPT -DDEBUG -DKERBEROS -I${.CURDIR}/../include
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes -lcrypt
+BINDIR= /usr/bin
+BINOWN= root
+BINMODE=4555
+
+.include <bsd.prog.mk>
diff --git a/eBones/register/pathnames.h b/eBones/register/pathnames.h
new file mode 100644
index 0000000..611c54f
--- /dev/null
+++ b/eBones/register/pathnames.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/1/93
+ */
+
+#define SERVER_KEYDIR "/etc/kerberosIV/register_keys"
+#define CLIENT_KEYFILE "/etc/kerberosIV/.update.key"
+#define KEYFILE_BASE ".update.key"
+#define _PATH_KPASSWD "/usr/bin/passwd"
diff --git a/eBones/register/register.1 b/eBones/register/register.1
new file mode 100644
index 0000000..d8bf104
--- /dev/null
+++ b/eBones/register/register.1
@@ -0,0 +1,63 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)register.1 8.1 (Berkeley) 6/1/93
+.\"
+.TH REGISTER 1 "June 1, 1993"
+.UC 7
+.SH NAME
+register \- register with Kerberos
+.SH SYNOPSIS
+.B register
+.SH DESCRIPTION
+The
+.I register
+command
+is used to register a new user with Kerberos.
+The Kerberos server keeps record of certain trusted hosts
+from which it will accept new registrations.
+If the host on which
+.I register
+is run is trusted by Kerberos, the user
+is asked for his current password, and then
+a new password to be used with Kerberos.
+A user may only register with Kerberos one time.
+.SH FILES
+.br
+/.update.keyxx.xx.xx.xx shared DES key with server
+.SH "SEE ALSO"
+registerd(8), kerberos(1)
+.SH DIAGNOSTICS
+\*(lqPrincipal not unique\*(rq
+if the user already exists in the Kerberos database.
+.br
+\*(lqPermission Denied,\*(rq
+if the host on which register is being run is untrusted.
diff --git a/eBones/register/register.c b/eBones/register/register.c
new file mode 100644
index 0000000..d20f848
--- /dev/null
+++ b/eBones/register/register.c
@@ -0,0 +1,311 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+#define SERVICE "krbupdate" /* service to add to KDC's database */
+#define PROTO "tcp"
+
+char realm[REALM_SZ];
+char krbhst[MAX_HSTNM];
+
+static char pname[ANAME_SZ];
+static char iname[INST_SZ];
+static char password[_PASSWORD_LEN];
+
+/* extern char *sys_errlist; */
+void die();
+void setup_key(), type_info(), cleanup();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct servent *se;
+ struct hostent *host;
+ struct sockaddr_in sin, local;
+ int rval;
+ int sock, llen;
+ u_char code;
+ static struct rlimit rl = { 0, 0 };
+
+ signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ perror("rlimit");
+ exit(1);
+ }
+
+ if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
+ fprintf(stderr, "couldn't find entry for service %s\n",
+ SERVICE);
+ exit(1);
+ }
+ if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get Kerberos host: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((host = gethostbyname(krbhst)) == NULL) {
+ fprintf(stderr, "couldn't get host entry for host %s\n",
+ krbhst);
+ exit(1);
+ }
+
+ sin.sin_family = host->h_addrtype;
+ (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
+ sin.sin_port = se->s_port;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+ perror("connect");
+ (void)close(sock);
+ exit(1);
+ }
+
+ llen = sizeof(local);
+ if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
+ perror("getsockname");
+ (void)close(sock);
+ exit(1);
+ }
+
+ setup_key(local);
+
+ type_info();
+
+ if (!get_user_info()) {
+ code = ABORT;
+ (void)des_write(sock, &code, 1);
+ cleanup();
+ exit(1);
+ }
+
+ code = APPEND_DB;
+ if (des_write(sock, &code, 1) != 1) {
+ perror("write 1");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
+ perror("write principal name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, iname, INST_SZ) != INST_SZ) {
+ perror("write instance name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, password, 255) != 255) {
+ perror("write password");
+ cleanup();
+ exit(1);
+ }
+
+ /* get return message */
+
+ {
+ int cc;
+ char msgbuf[BUFSIZ];
+
+ cc = read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during key verification\n");
+ cleanup();
+ exit(1);
+ }
+ if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
+ fprintf(stderr, "%s: %s", krbhst, msgbuf);
+ cleanup();
+ exit(1);
+ }
+
+ cc = des_read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during read\n");
+ cleanup();
+ exit(1);
+ } else {
+ printf("%s: %s", krbhst, msgbuf);
+ }
+ }
+
+ cleanup();
+ (void)close(sock);
+}
+
+void
+cleanup()
+{
+ bzero(password, 255);
+}
+
+extern char *crypt();
+extern char *getpass();
+
+int
+get_user_info()
+{
+ int uid = getuid();
+ int valid = 0, i;
+ struct passwd *pw;
+ char *pas, *namep;
+
+ /* NB: we must run setuid-root to get at the real pw file */
+
+ if ((pw = getpwuid(uid)) == NULL) {
+ fprintf(stderr, "Who are you?\n");
+ return(0);
+ }
+ (void)seteuid(uid);
+ (void)strcpy(pname, pw->pw_name); /* principal name */
+
+ for (i = 1; i < 3; i++) {
+ pas = getpass("login password:");
+ namep = crypt(pas, pw->pw_passwd);
+ if (strcmp(namep, pw->pw_passwd)) {
+ fprintf(stderr, "Password incorrect\n");
+ continue;
+ } else {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid)
+ return(0);
+ pas = getpass("Kerberos password (may be the same):");
+ while (*pas == NULL) {
+ printf("<NULL> password not allowed\n");
+ pas = getpass("Kerberos password (may be the same):");
+ }
+ (void)strcpy(password, pas); /* password */
+ pas = getpass("Retype Kerberos password:");
+ if (strcmp(password, pas)) {
+ fprintf(stderr, "Password mismatch -- aborted\n");
+ return(0);
+ }
+
+ iname[0] = NULL; /* null instance name */
+ return(1);
+}
+
+void
+setup_key(local)
+ struct sockaddr_in local;
+{
+ static struct keyfile_data kdata;
+ static Key_schedule schedule;
+ int fd;
+ char namebuf[MAXPATHLEN];
+ extern int errno;
+
+ (void) sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(local.sin_addr));
+
+ fd = open(namebuf, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "couldn't open key file %s for local host: ",
+ namebuf);
+ perror("");
+ exit(1);
+ }
+
+ if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
+ fprintf(stderr,"size error reading key file for local host %s\n",
+ inet_ntoa(local.sin_addr));
+ exit(1);
+ }
+ key_sched(kdata.kf_key, schedule);
+ des_set_key(kdata.kf_key, schedule);
+ return;
+}
+
+void
+type_info()
+{
+ printf("Kerberos user registration (realm %s)\n\n", realm);
+ printf("Please enter your login password followed by your new Kerberos password.\n");
+ printf("The Kerberos password you enter now will be used in the future\n");
+ printf("as your Kerberos password for all machines in the %s realm.\n", realm);
+ printf("You will only be allowed to perform this operation once, although you may run\n");
+ printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
+}
+
+void
+die()
+{
+ fprintf(stderr, "\nServer no longer listening\n");
+ fflush(stderr);
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/register/register_proto.h b/eBones/register/register_proto.h
new file mode 100644
index 0000000..5478949
--- /dev/null
+++ b/eBones/register/register_proto.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)register_proto.h 8.1 (Berkeley) 6/1/93
+ */
+
+#define APPEND_DB 0x01
+#define ABORT 0x02
+
+#define GOTKEY_MSG "GOTKEY"
+
+struct keyfile_data {
+ C_Block kf_key;
+};
diff --git a/eBones/registerd/Makefile b/eBones/registerd/Makefile
new file mode 100644
index 0000000..bc91577
--- /dev/null
+++ b/eBones/registerd/Makefile
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 1990 The Regents of the University of California.
+# All rights reserved.
+#
+# %sccs.include.redist.sh
+#
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+#
+# $Id: Makefile,v 1.3 1994/07/20 09:20:51 g89r4222 Exp $
+
+PROG= registerd
+SRCS= registerd.c
+CFLAGS+=-DCRYPT -DKERBEROS -I${.CURDIR}/../register
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= registerd.8
+BINDIR= /usr/libexec
+
+.include <bsd.prog.mk>
diff --git a/eBones/registerd/registerd.8 b/eBones/registerd/registerd.8
new file mode 100644
index 0000000..7ceff75
--- /dev/null
+++ b/eBones/registerd/registerd.8
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)registerd.8 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt REGISTERD 8
+.Os
+.Sh NAME
+.Nm registerd
+.Nd Kerberos registration daemon
+.Sh SYNOPSIS
+.Nm registerd
+.Sh DESCRIPTION
+Act as a registration agent for a Kerberos domain.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keys -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/principal*
+Kerberos database
+.It Pa /etc/kerberosIV/register_keys
+directory containing keys for trusted hosts
+.El
+.Sh SEE ALSO
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh DIAGNOSTICS
+.Dq Already exists ,
+if the user already exists in the Kerberos database.
+.Pp
+.Dq Permission Denied ,
+if the host on which register is being run is untrusted.
+.Sh HISTORY
+The
+.Nm registerd
+utility
+first appeared in 4.4BSD.
+
diff --git a/eBones/registerd/registerd.c b/eBones/registerd/registerd.c
new file mode 100644
index 0000000..b62e379
--- /dev/null
+++ b/eBones/registerd/registerd.c
@@ -0,0 +1,341 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/krb_db.h>
+#include <stdio.h>
+#include "register_proto.h"
+#include "pathnames.h"
+
+#define KBUFSIZ (sizeof(struct keyfile_data))
+#define RCRYPT 0x00
+#define CLEAR 0x01
+
+char *progname, msgbuf[BUFSIZ];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ static Key_schedule schedule;
+ static struct rlimit rl = { 0, 0 };
+ struct keyfile_data *kfile;
+ u_char code;
+ int kf, retval, sval;
+ struct sockaddr_in sin;
+ char keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
+ void die();
+
+ progname = argv[0]; /* for the library routines */
+
+ openlog("registerd", LOG_PID, LOG_AUTH);
+
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGTSTP, SIG_IGN);
+ (void)signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ syslog(LOG_ERR, "setrlimit: %m");
+ exit(1);
+ }
+
+
+ /* figure out who we are talking to */
+
+ sval = sizeof(sin);
+ if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ exit(1);
+ }
+
+ /* get encryption key */
+
+ (void) sprintf(keyfile, "%s/%s%s",
+ SERVER_KEYDIR,
+ KEYFILE_BASE,
+ inet_ntoa(sin.sin_addr));
+
+ if ((kf = open(keyfile, O_RDONLY)) < 0) {
+ syslog(LOG_ERR,
+ "error opening Kerberos update keyfile (%s): %m", keyfile);
+ (void) sprintf(msgbuf,
+ "couldn't open session keyfile for your host");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+
+ if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
+ syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
+ (void) sprintf(msgbuf,
+ "couldn't read session key from your host's keyfile");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+ (void) sprintf(msgbuf, GOTKEY_MSG);
+ send_packet(msgbuf, CLEAR);
+ kfile = (struct keyfile_data *) keybuf;
+ key_sched(kfile->kf_key, schedule);
+ des_set_key(kfile->kf_key, schedule);
+
+ /* read the command code byte */
+
+ if (des_read(0, &code, 1) == 1) {
+
+ switch(code) {
+ case APPEND_DB:
+ retval = do_append(&sin);
+ break;
+ case ABORT:
+ cleanup();
+ close(0);
+ exit(0);
+ default:
+ retval = KFAILURE;
+ syslog(LOG_NOTICE,
+ "invalid command code on db update (0x%x)",
+ code);
+ }
+
+ } else {
+ retval = KFAILURE;
+ syslog(LOG_ERR,
+ "couldn't read command code on Kerberos update");
+ }
+
+ code = (u_char) retval;
+ if (code != KSUCCESS) {
+ (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
+ send_packet(msgbuf, RCRYPT);
+ } else {
+ (void) sprintf(msgbuf, "Update complete.");
+ send_packet(msgbuf, RCRYPT);
+ }
+ cleanup();
+ close(0);
+ exit(0);
+}
+
+#define MAX_PRINCIPAL 10
+static Principal principal_data[MAX_PRINCIPAL];
+static C_Block key, master_key;
+static Key_schedule master_key_schedule;
+int
+do_append(sinp)
+ struct sockaddr_in *sinp;
+{
+ Principal default_princ;
+ char input_name[ANAME_SZ];
+ char input_instance[INST_SZ];
+ int j,n, more;
+ long mkeyversion;
+
+
+
+ /* get master key from MKEYFILE */
+ if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
+ syslog(LOG_ERR, "couldn't get master key");
+ return(KFAILURE);
+ }
+
+ mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
+ if (mkeyversion < 0) {
+ syslog(LOG_ERR, "couldn't validate master key");
+ return(KFAILURE);
+ }
+
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+
+ if (n != 1) {
+ syslog(LOG_ERR, "couldn't get default principal");
+ return(KFAILURE);
+ }
+
+ /*
+ * get principal name, instance, and password from network.
+ * convert password to key and store it
+ */
+
+ if (net_get_principal(input_name, input_instance, key) != 0) {
+ return(KFAILURE);
+ }
+
+
+ j = kerb_get_principal(
+ input_name,
+ input_instance,
+ principal_data,
+ MAX_PRINCIPAL,
+ &more
+ );
+
+ if (j != 0) {
+ /* already in database, no update */
+ syslog(LOG_NOTICE,
+ "attempt to add duplicate entry for principal %s.%s",
+ input_name, input_instance);
+ return(KDC_PR_N_UNIQUE);
+ }
+
+ /*
+ * set up principal's name, instance
+ */
+
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+
+
+ /* and the expiration date and version #s */
+
+ principal_data[0].exp_date = default_princ.exp_date;
+ strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
+
+
+ /* and the key */
+
+ kdb_encrypt_key(key, key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(key, &principal_data[0].key_low, 4);
+ bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
+ bzero(key, sizeof(key));
+
+ principal_data[0].key_version = 1; /* 1st entry */
+
+ /* and write it to the database */
+
+ if (kerb_put_principal(&principal_data[0], 1)) {
+ syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
+ return(KFAILURE);
+ }
+
+ syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
+ principal_data[0].name,
+ principal_data[0].instance,
+ inet_ntoa(sinp->sin_addr)
+ );
+
+ return(KSUCCESS);
+
+}
+
+send_packet(msg,flag)
+ char *msg;
+ int flag;
+{
+ int len = strlen(msg);
+ msg[len++] = '\n';
+ msg[len] = '\0';
+ if (len > sizeof(msgbuf)) {
+ syslog(LOG_ERR, "send_packet: invalid msg size");
+ return;
+ }
+ if (flag == RCRYPT) {
+ if (des_write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else if (flag == CLEAR) {
+ if (write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else
+ syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
+
+}
+
+net_get_principal(pname, iname, keyp)
+ char *pname, *iname;
+ C_Block *keyp;
+{
+ int cc;
+ static char password[255];
+
+ cc = des_read(0, pname, ANAME_SZ);
+ if (cc != ANAME_SZ) {
+ syslog(LOG_ERR, "couldn't get principal name");
+ return(-1);
+ }
+
+ cc = des_read(0, iname, INST_SZ);
+ if (cc != INST_SZ) {
+ syslog(LOG_ERR, "couldn't get instance name");
+ return(-1);
+ }
+
+ cc = des_read(0, password, 255);
+ if (cc != 255) {
+ syslog(LOG_ERR, "couldn't get password");
+ bzero(password, 255);
+ return(-1);
+ }
+
+ string_to_key(password, *keyp);
+ bzero(password, 255);
+ return(0);
+}
+
+cleanup()
+{
+ bzero(master_key, sizeof(master_key));
+ bzero(key, sizeof(key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+}
+
+void
+die()
+{
+ syslog(LOG_ERR, "remote end died (SIGPIPE)");
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/usr.bin/kadmin/kadmin.8 b/eBones/usr.bin/kadmin/kadmin.8
new file mode 100644
index 0000000..6e15015
--- /dev/null
+++ b/eBones/usr.bin/kadmin/kadmin.8
@@ -0,0 +1,158 @@
+.\" from: kadmin.8,v 4.2 89/07/25 17:20:02 jtkohl Exp $
+.\" $Id: kadmin.8,v 1.2 1994/07/19 19:27:22 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIN 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmin \- network utility for Kerberos database administration
+.SH SYNOPSIS
+.B kadmin [-u user] [-r default_realm] [-m]
+.SH DESCRIPTION
+This utility provides a unified administration interface to
+the
+Kerberos
+master database.
+Kerberos
+administrators
+use
+.I kadmin
+to register new users and services to the master database,
+and to change information about existing database entries.
+For instance, an administrator can use
+.I kadmin
+to change a user's
+Kerberos
+password.
+A Kerberos administrator is a user with an ``admin'' instance
+whose name appears on one of the Kerberos administration access control
+lists. If the \-u option is used,
+.I user
+will be used as the administrator instead of the local user.
+If the \-r option is used,
+.I default_realm
+will be used as the default realm for transactions. Otherwise,
+the local realm will be used by default.
+If the \-m option is used, multiple requests will be permitted
+on only one entry of the admin password. Some sites won't
+support this option.
+
+The
+.I kadmin
+program communicates over the network with the
+.I kadmind
+program, which runs on the machine housing the Kerberos master
+database.
+The
+.I kadmind
+creates new entries and makes modifications to the database.
+
+When you enter the
+.I kadmin
+command,
+the program displays a message that welcomes you and explains
+how to ask for help.
+Then
+.I kadmin
+waits for you to enter commands (which are described below).
+It then asks you for your
+.I admin
+password before accessing the database.
+
+Use the
+.I add_new_key
+(or
+.I ank
+for short)
+command to register a new principal
+with the master database.
+The command requires one argument,
+the principal's name. The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's
+new password. If no realm is specified,
+the local realm is used unless another was
+given on the commandline with the \-r flag.
+If no instance is
+specified, a null instance is used. If
+a realm other than the default realm is specified,
+you will need to supply your admin password for
+the other realm.
+
+Use the
+.I change_password (cpw)
+to change a principal's
+Kerberos
+password.
+The command requires one argument,
+the principal's
+name.
+You are asked to enter your
+.I admin
+password,
+then prompted twice to enter the principal's new password.
+The name
+given can be fully qualified using
+the standard
+.I name.instance@realm
+convention.
+
+Use the
+.I change_admin_password (cap)
+to change your
+.I admin
+instance password.
+This command requires no arguments.
+It prompts you for your old
+.I admin
+password, then prompts you twice to enter the new
+.I admin
+password. If this is your first command,
+the default realm is used. Otherwise, the realm
+used in the last command is used.
+
+Use the
+.I destroy_tickets (dest)
+command to destroy your admin tickets explicitly.
+
+Use the
+.I list_requests (lr)
+command to get a list of possible commands.
+
+Use the
+.I help
+command to display
+.IR kadmin's
+various help messages.
+If entered without an argument,
+.I help
+displays a general help message.
+You can get detailed information on specific
+.I kadmin
+commands
+by entering
+.I help
+.IR command_name .
+
+To quit the program, type
+.IR quit .
+
+.SH BUGS
+The user interface is primitive, and the command names could be better.
+
+.SH "SEE ALSO"
+kerberos(1), kadmind(8), kpasswd(1), ksrvutil(8)
+.br
+``A Subsystem Utilities Package for UNIX'' by Ken Raeburn
+.SH AUTHORS
+Jeffrey I. Schiller, MIT Project Athena
+.br
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/usr.bin/kdestroy/Makefile b/eBones/usr.bin/kdestroy/Makefile
new file mode 100644
index 0000000..5947028
--- /dev/null
+++ b/eBones/usr.bin/kdestroy/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:15 g89r4222 Exp $
+
+PROG= kdestroy
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/kdestroy/kdestroy.1 b/eBones/usr.bin/kdestroy/kdestroy.1
new file mode 100644
index 0000000..7099353
--- /dev/null
+++ b/eBones/usr.bin/kdestroy/kdestroy.1
@@ -0,0 +1,81 @@
+.\" from: kdestroy.1,v 4.9 89/01/23 11:39:50 jtkohl Exp $
+.\" $Id: kdestroy.1,v 1.2 1994/07/19 19:27:32 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDESTROY 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdestroy \- destroy Kerberos tickets
+.SH SYNOPSIS
+.B kdestroy
+[
+.B \-f
+]
+[
+.B \-q
+]
+.SH DESCRIPTION
+The
+.I kdestroy
+utility destroys the user's active
+Kerberos
+authorization tickets by writing zeros to the file that contains them.
+If the ticket file does not exist,
+.I kdestroy
+displays a message to that effect.
+.PP
+After overwriting the file,
+.I kdestroy
+removes the file from the system.
+The utility
+displays a message indicating the success or failure of the
+operation.
+If
+.I kdestroy
+is unable to destroy the ticket file,
+the utility will warn you by making your terminal beep.
+.PP
+In the Athena workstation environment,
+the
+.I toehold
+service automatically destroys your tickets when you
+end a workstation session.
+If your site does not provide a similar ticket-destroying mechanism,
+you can place the
+.I kdestroy
+command in your
+.I .logout
+file so that your tickets are destroyed automatically
+when you logout.
+.PP
+The options to
+.I kdestroy
+are as follows:
+.TP 7
+.B \-f
+.I kdestroy
+runs without displaying the status message.
+.TP
+.B \-q
+.I kdestroy
+will not make your terminal beep if it fails to destroy the tickets.
+.SH FILES
+KRBTKFILE environment variable if set, otherwise
+.br
+/tmp/tkt[uid]
+.SH SEE ALSO
+kerberos(1), kinit(1), klist(1)
+.SH BUGS
+.PP
+Only the tickets in the user's current ticket file are destroyed.
+Separate ticket files are used to hold root instance and password
+changing tickets. These files should probably be destroyed too, or
+all of a user's tickets kept in a single ticket file.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
+.br
+Bill Sommerfeld, MIT Project Athena
diff --git a/eBones/usr.bin/kdestroy/kdestroy.c b/eBones/usr.bin/kdestroy/kdestroy.c
new file mode 100644
index 0000000..f010fcd
--- /dev/null
+++ b/eBones/usr.bin/kdestroy/kdestroy.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This program causes Kerberos tickets to be destroyed.
+ * Options are:
+ *
+ * -q[uiet] - no bell even if tickets not destroyed
+ * -f[orce] - no message printed at all
+ *
+ * from: kdestroy.c,v 4.5 88/03/18 15:16:02 steiner Exp $
+ * $Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdestroy.c,v 1.2 1994/07/19 19:24:16 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <krb.h>
+#ifdef BSD42
+#include <strings.h>
+#endif BSD42
+
+
+static char *pname;
+
+static usage()
+{
+ fprintf(stderr, "Usage: %s [-f] [-q]\n", pname);
+ exit(1);
+}
+
+main(argc, argv)
+ char *argv[];
+{
+ int fflag=0, qflag=0, k_errno;
+ register char *cp;
+
+ cp = rindex (argv[0], '/');
+ if (cp == NULL)
+ pname = argv[0];
+ else
+ pname = cp+1;
+
+ if (argc > 2)
+ usage();
+ else if (argc == 2) {
+ if (!strcmp(argv[1], "-f"))
+ ++fflag;
+ else if (!strcmp(argv[1], "-q"))
+ ++qflag;
+ else usage();
+ }
+
+ k_errno = dest_tkt();
+
+ if (fflag) {
+ if (k_errno != 0 && k_errno != RET_TKFIL)
+ exit(1);
+ else
+ exit(0);
+ } else {
+ if (k_errno == 0)
+ printf("Tickets destroyed.\n");
+ else if (k_errno == RET_TKFIL)
+ fprintf(stderr, "No tickets to destroy.\n");
+ else {
+ fprintf(stderr, "Tickets NOT destroyed.\n");
+ if (!qflag)
+ fprintf(stderr, "\007");
+ exit(1);
+ }
+ }
+ exit(0);
+}
diff --git a/eBones/usr.bin/kinit/Makefile b/eBones/usr.bin/kinit/Makefile
new file mode 100644
index 0000000..e616f42
--- /dev/null
+++ b/eBones/usr.bin/kinit/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:31 g89r4222 Exp $
+
+PROG= kinit
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/kinit/kinit.1 b/eBones/usr.bin/kinit/kinit.1
new file mode 100644
index 0000000..f9a97a7
--- /dev/null
+++ b/eBones/usr.bin/kinit/kinit.1
@@ -0,0 +1,133 @@
+.\" from: kinit.1,v 4.6 89/01/23 11:39:11 jtkohl Exp $
+.\" $Id: kinit.1,v 1.2 1994/07/19 19:27:36 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KINIT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kinit \- Kerberos login utility
+.SH SYNOPSIS
+.B kinit
+[
+.B \-irvl
+]
+.SH DESCRIPTION
+The
+.I kinit
+command is used to login to the
+Kerberos
+authentication and authorization system.
+Note that only registered
+Kerberos
+users can use the
+Kerberos
+system.
+For information about registering as a
+Kerberos
+user,
+see the
+.I kerberos(1)
+manual page.
+.PP
+If you are logged in to a workstation that is running the
+.I toehold
+service,
+you do not have to use
+.I kinit.
+The
+.I toehold
+login procedure will log you into
+Kerberos
+automatically.
+You will need to use
+.I kinit
+only in those situations in which
+your original tickets have expired.
+(Tickets expire in about a day.)
+Note as well that
+.I toehold
+will automatically destroy your tickets when you logout from the workstation.
+.PP
+When you use
+.I kinit
+without options,
+the utility
+prompts for your username and Kerberos password,
+and tries to authenticate your login with the local
+Kerberos
+server.
+.PP
+If
+Kerberos
+authenticates the login attempt,
+.I kinit
+retrieves your initial ticket and puts it in the ticket file specified by
+your KRBTKFILE environment variable.
+If this variable is undefined,
+your ticket will be stored in the
+.IR /tmp
+directory,
+in the file
+.I tktuid ,
+where
+.I uid
+specifies your user identification number.
+.PP
+If you have logged in to
+Kerberos
+without the benefit of the workstation
+.I toehold
+system,
+make sure you use the
+.I kdestroy
+command to destroy any active tickets before you end your login session.
+You may want to put the
+.I kdestroy
+command in your
+.I \.logout
+file so that your tickets will be destroyed automatically when you logout.
+.PP
+The options to
+.I kinit
+are as follows:
+.TP 7
+.B \-i
+.I kinit
+prompts you for a
+Kerberos
+instance.
+.TP
+.B \-r
+.I kinit
+prompts you for a
+Kerberos
+realm.
+This option lets you authenticate yourself with a remote
+Kerberos
+server.
+.TP
+.B \-v
+Verbose mode.
+.I kinit
+prints the name of the ticket file used, and
+a status message indicating the success or failure of
+your login attempt.
+.TP
+.B \-l
+.I kinit
+prompts you for a ticket lifetime in minutes. Due to protocol
+restrictions in Kerberos Version 4, this value must be between 5 and
+1275 minutes.
+.SH SEE ALSO
+.PP
+kerberos(1), kdestroy(1), klist(1), toehold(1)
+.SH BUGS
+The
+.B \-r
+option has not been fully implemented.
+.SH AUTHORS
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.br
+Clifford Neuman, MIT Project Athena
diff --git a/eBones/usr.bin/kinit/kinit.c b/eBones/usr.bin/kinit/kinit.c
new file mode 100644
index 0000000..94ce0fe
--- /dev/null
+++ b/eBones/usr.bin/kinit/kinit.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Routine to initialize user to Kerberos. Prompts optionally for
+ * user, instance and realm. Authenticates user and gets a ticket
+ * for the Kerberos ticket-granting service for future use.
+ *
+ * Options are:
+ *
+ * -i[instance]
+ * -r[realm]
+ * -v[erbose]
+ * -l[ifetime]
+ *
+ * from: kinit.c,v 4.12 90/03/20 16:11:15 jon Exp $
+ * $Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kinit.c,v 1.2 1994/07/19 19:24:33 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <pwd.h>
+#include <krb.h>
+
+#ifndef ORGANIZATION
+#define ORGANIZATION "MIT Project Athena"
+#endif /*ORGANIZATION*/
+
+#ifdef PC
+#define LEN 64 /* just guessing */
+#endif PC
+
+#if defined(BSD42) || defined(__FreeBSD__)
+#include <strings.h>
+#include <sys/param.h>
+#if defined(ultrix) || defined(sun)
+#define LEN 64
+#else
+#define LEN MAXHOSTNAMELEN
+#endif /* defined(ultrix) || defined(sun) */
+#endif /* BSD42 */
+
+#define LIFE 96 /* lifetime of ticket in 5-minute units */
+
+char *progname;
+
+void
+get_input(s, size, stream)
+char *s;
+int size;
+FILE *stream;
+{
+ char *p;
+
+ if (fgets(s, size, stream) == NULL)
+ exit(1);
+ if ((p = index(s, '\n')) != NULL)
+ *p = '\0';
+}
+
+main(argc, argv)
+ char *argv[];
+{
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char buf[LEN];
+ char *username = NULL;
+ int iflag, rflag, vflag, lflag, lifetime, k_errno;
+ register char *cp;
+ register i;
+
+ *inst = *realm = '\0';
+ iflag = rflag = vflag = lflag = 0;
+ lifetime = LIFE;
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (--argc) {
+ if ((*++argv)[0] != '-') {
+ if (username)
+ usage();
+ username = *argv;
+ continue;
+ }
+ for (i = 1; (*argv)[i] != '\0'; i++)
+ switch ((*argv)[i]) {
+ case 'i': /* Instance */
+ ++iflag;
+ continue;
+ case 'r': /* Realm */
+ ++rflag;
+ continue;
+ case 'v': /* Verbose */
+ ++vflag;
+ continue;
+ case 'l':
+ ++lflag;
+ continue;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ if (username &&
+ (k_errno = kname_parse(aname, inst, realm, username))
+ != KSUCCESS) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ iflag = rflag = 1;
+ username = NULL;
+ }
+ if (k_gethostname(buf, LEN)) {
+ fprintf(stderr, "%s: k_gethostname failed\n", progname);
+ exit(1);
+ }
+ printf("%s (%s)\n", ORGANIZATION, buf);
+ if (username) {
+ printf("Kerberos Initialization for \"%s", aname);
+ if (*inst)
+ printf(".%s", inst);
+ if (*realm)
+ printf("@%s", realm);
+ printf("\"\n");
+ } else {
+ if (iflag) {
+ printf("Kerberos Initialization\n");
+ printf("Kerberos name: ");
+ get_input(aname, sizeof(aname), stdin);
+ } else {
+ int uid = getuid();
+ char *getenv();
+ struct passwd *pwd;
+
+ /* default to current user name unless running as root */
+ if (uid == 0 && (username = getenv("USER")) &&
+ strcmp(username, "root") != 0) {
+ strncpy(aname, username, sizeof(aname));
+ strncpy(inst, "root", sizeof(inst));
+ } else {
+ pwd = getpwuid(uid);
+
+ if (pwd == (struct passwd *) NULL) {
+ fprintf(stderr, "Unknown name for your uid\n");
+ printf("Kerberos name: ");
+ gets(aname);
+ } else
+ strncpy(aname, pwd->pw_name, sizeof(aname));
+ }
+ }
+
+ if (!*aname)
+ exit(0);
+ if (!k_isname(aname)) {
+ fprintf(stderr, "%s: bad Kerberos name format\n",
+ progname);
+ exit(1);
+ }
+ }
+ /* optional instance */
+ if (iflag) {
+ printf("Kerberos instance: ");
+ get_input(inst, sizeof(inst), stdin);
+ if (!k_isinst(inst)) {
+ fprintf(stderr, "%s: bad Kerberos instance format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (rflag) {
+ printf("Kerberos realm: ");
+ get_input(realm, sizeof(realm), stdin);
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: bad Kerberos realm format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (lflag) {
+ printf("Kerberos ticket lifetime (minutes): ");
+ get_input(buf, sizeof(buf), stdin);
+ lifetime = atoi(buf);
+ if (lifetime < 5)
+ lifetime = 1;
+ else
+ lifetime /= 5;
+ /* This should be changed if the maximum ticket lifetime */
+ /* changes */
+ if (lifetime > 255)
+ lifetime = 255;
+ }
+ if (!*realm && krb_get_lrealm(realm, 1)) {
+ fprintf(stderr, "%s: krb_get_lrealm failed\n", progname);
+ exit(1);
+ }
+ k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm,
+ lifetime, 0);
+ if (vflag) {
+ printf("Kerberos realm %s:\n", realm);
+ printf("%s\n", krb_err_txt[k_errno]);
+ } else if (k_errno) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ exit(1);
+ }
+}
+
+usage()
+{
+ fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.bin/klist/Makefile b/eBones/usr.bin/klist/Makefile
new file mode 100644
index 0000000..aa0d720
--- /dev/null
+++ b/eBones/usr.bin/klist/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:37 g89r4222 Exp $
+
+PROG= klist
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/klist/klist.1 b/eBones/usr.bin/klist/klist.1
new file mode 100644
index 0000000..a66e668
--- /dev/null
+++ b/eBones/usr.bin/klist/klist.1
@@ -0,0 +1,84 @@
+.\" from: klist.1,v 4.8 89/01/24 14:35:09 jtkohl Exp $
+.\" $Id: klist.1,v 1.2 1994/07/19 19:27:38 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KLIST 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+klist \- list currently held Kerberos tickets
+.SH SYNOPSIS
+.B klist
+[
+\fB\-s \fR|\fB \-t\fR
+] [
+.B \-file
+name ] [
+.B \-srvtab
+]
+.br
+.SH DESCRIPTION
+.I klist
+prints the name of the tickets file and the
+identity of the principal the tickets are for (as listed in the
+tickets file), and
+lists the principal names of all Kerberos tickets currently held by
+the user, along with the issue and expire time for each authenticator.
+Principal names are listed in the form
+.I name.instance@realm,
+with the '.' omitted if the instance is null,
+and the '@' omitted if the realm is null.
+
+If given the
+.B \-s
+option,
+.I klist
+does not print the issue and expire times, the name of the tickets file,
+or the identity of the principal.
+
+If given the
+.B \-t
+option,
+.B klist
+checks for the existence of a non-expired ticket-granting-ticket in the
+ticket file. If one is present, it exits with status 0, else it exits
+with status 1. No output is generated when this option is specified.
+
+If given the
+.B \-file
+option, the following argument is used as the ticket file.
+Otherwise, if the
+.B KRBTKFILE
+environment variable is set, it is used.
+If this environment variable
+is not set, the file
+.B /tmp/tkt[uid]
+is used, where
+.B uid
+is the current user-id of the user.
+
+If given the
+.B \-srvtab
+option, the file is treated as a service key file, and the names of the
+keys contained therein are printed. If no file is
+specified with a
+.B \-file
+option, the default is
+.IR /etc/srvtab .
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm
+.TP
+/tmp/tkt[uid]
+as the default ticket file ([uid] is the decimal UID of the user).
+.TP
+/etc/srvtab
+as the default service key file
+.SH SEE ALSO
+.PP
+kerberos(1), kinit(1), kdestroy(1)
+.SH BUGS
+When reading a file as a service key file, very little sanity or error
+checking is performed.
diff --git a/eBones/usr.bin/klist/klist.c b/eBones/usr.bin/klist/klist.c
new file mode 100644
index 0000000..4a95bc0
--- /dev/null
+++ b/eBones/usr.bin/klist/klist.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Lists your current Kerberos tickets.
+ * Written by Bill Sommerfeld, MIT Project Athena.
+ *
+ * from: klist.c,v 4.15 89/08/30 11:19:16 jtkohl Exp $
+ * $Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: klist.c,v 1.2 1994/07/19 19:24:38 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <krb.h>
+#include <prot.h>
+
+char *tkt_string();
+char *short_date();
+char *whoami; /* What was I invoked as?? */
+char *getenv();
+
+extern char *krb_err_txt[];
+
+/* ARGSUSED */
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int long_form = 1;
+ int tgt_test = 0;
+ int do_srvtab = 0;
+ char *tkt_file = NULL;
+ char *cp;
+
+ whoami = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (*(++argv)) {
+ if (!strcmp(*argv, "-s")) {
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-t")) {
+ tgt_test = 1;
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-l")) { /* now default */
+ continue;
+ }
+ if (!strcmp(*argv, "-file")) {
+ if (*(++argv)) {
+ tkt_file = *argv;
+ continue;
+ } else
+ usage();
+ }
+ if (!strcmp(*argv, "-srvtab")) {
+ if (tkt_file == NULL) /* if no other file spec'ed,
+ set file to default srvtab */
+ tkt_file = KEYFILE;
+ do_srvtab = 1;
+ continue;
+ }
+ usage();
+ }
+
+ if (do_srvtab)
+ display_srvtab(tkt_file);
+ else
+ display_tktfile(tkt_file, tgt_test, long_form);
+ exit(0);
+}
+
+
+display_tktfile(file, tgt_test, long_form)
+char *file;
+int tgt_test, long_form;
+{
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ char buf1[20], buf2[20];
+ int k_errno;
+ CREDENTIALS c;
+ int header = 1;
+
+ if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL))
+ file = TKT_FILE;
+
+ if (long_form)
+ printf("Ticket file: %s\n", file);
+
+ /*
+ * Since krb_get_tf_realm will return a ticket_file error,
+ * we will call tf_init and tf_close first to filter out
+ * things like no ticket file. Otherwise, the error that
+ * the user would see would be
+ * klist: can't find realm of ticket file: No ticket file (tf_util)
+ * instead of
+ * klist: No ticket file (tf_util)
+ */
+
+ /* Open ticket file */
+ if (k_errno = tf_init(file, R_TKT_FIL)) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Close ticket file */
+ (void) tf_close();
+
+ /*
+ * We must find the realm of the ticket file here before calling
+ * tf_init because since the realm of the ticket file is not
+ * really stored in the principal section of the file, the
+ * routine we use must itself call tf_init and tf_close.
+ */
+ if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: can't find realm of ticket file: %s\n",
+ whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /* Open ticket file */
+ if (k_errno = tf_init(file, R_TKT_FIL)) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Get principal name and instance */
+ if ((k_errno = tf_get_pname(pname)) ||
+ (k_errno = tf_get_pinst(pinst))) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /*
+ * You may think that this is the obvious place to get the
+ * realm of the ticket file, but it can't be done here as the
+ * routine to do this must open the ticket file. This is why
+ * it was done before tf_init.
+ */
+
+ if (!tgt_test && long_form)
+ printf("Principal:\t%s%s%s%s%s\n\n", pname,
+ (pinst[0] ? "." : ""), pinst,
+ (prealm[0] ? "@" : ""), prealm);
+ while ((k_errno = tf_get_cred(&c)) == KSUCCESS) {
+ if (!tgt_test && long_form && header) {
+ printf("%-15s %-15s %s\n",
+ " Issued", " Expires", " Principal");
+ header = 0;
+ }
+ if (tgt_test) {
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ if (!strcmp(c.service, TICKET_GRANTING_TICKET) &&
+ !strcmp(c.instance, prealm)) {
+ if (time(0) < c.issue_date)
+ exit(0); /* tgt hasn't expired */
+ else
+ exit(1); /* has expired */
+ }
+ continue; /* not a tgt */
+ }
+ if (long_form) {
+ (void) strcpy(buf1, short_date(&c.issue_date));
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ (void) strcpy(buf2, short_date(&c.issue_date));
+ printf("%s %s ", buf1, buf2);
+ }
+ printf("%s%s%s%s%s\n",
+ c.service, (c.instance[0] ? "." : ""), c.instance,
+ (c.realm[0] ? "@" : ""), c.realm);
+ }
+ if (tgt_test)
+ exit(1); /* no tgt found */
+ if (header && long_form && k_errno == EOF) {
+ printf("No tickets in file.\n");
+ }
+}
+
+char *
+short_date(dp)
+ long *dp;
+{
+ register char *cp;
+ extern char *ctime();
+ cp = ctime(dp) + 4;
+ cp[15] = '\0';
+ return (cp);
+}
+
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami);
+ exit(1);
+}
+
+display_srvtab(file)
+char *file;
+{
+ int stab;
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char key[8];
+ unsigned char vno;
+ int count;
+
+ printf("Server key file: %s\n", file);
+
+ if ((stab = open(file, O_RDONLY, 0400)) < 0) {
+ perror(file);
+ exit(1);
+ }
+ printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm",
+ "Key Version");
+ printf("------------------------------------------------------\n");
+
+ /* argh. getst doesn't return error codes, it silently fails */
+ while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
+ && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
+ && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
+ if (((count = read(stab,(char *) &vno,1)) != 1) ||
+ ((count = read(stab,(char *) key,8)) != 8)) {
+ if (count < 0)
+ perror("reading from key file");
+ else
+ fprintf(stderr, "key file truncated\n");
+ exit(1);
+ }
+ printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno);
+ }
+ if (count < 0)
+ perror(file);
+ (void) close(stab);
+}
+
+/* adapted from getst() in librkb */
+/*
+ * ok_getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. ok_getst() returns the number of characters read, including
+ * the null terminator.
+ *
+ * If there is a read error, it returns -1 (like the read(2) system call)
+ */
+
+ok_getst(fd, s, n)
+ int fd;
+ register char *s;
+{
+ register count = n;
+ int err;
+ while ((err = read(fd, s, 1)) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ if (err < 0)
+ return(-1);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/usr.bin/ksrvtgt/Makefile b/eBones/usr.bin/ksrvtgt/Makefile
new file mode 100644
index 0000000..5e8944d
--- /dev/null
+++ b/eBones/usr.bin/ksrvtgt/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:26:54 g89r4222 Exp $
+
+PROG= ksrvtgt
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/bin
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/ksrvtgt/ksrvtgt.1 b/eBones/usr.bin/ksrvtgt/ksrvtgt.1
new file mode 100644
index 0000000..25fd939
--- /dev/null
+++ b/eBones/usr.bin/ksrvtgt/ksrvtgt.1
@@ -0,0 +1,51 @@
+.\" from: ksrvtgt.1,v 4.1 89/01/24 14:36:28 jtkohl Exp $
+.\" $Id: ksrvtgt.1,v 1.2 1994/07/19 19:27:52 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVTGT 1 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvtgt \- fetch and store Kerberos ticket-granting-ticket using a
+service key
+.SH SYNOPSIS
+.B ksrvtgt
+name instance [[realm] srvtab]
+.SH DESCRIPTION
+.I ksrvtgt
+retrieves a ticket-granting ticket with a lifetime of five (5) minutes
+for the principal
+.I name.instance@realm
+(or
+.I name.instance@localrealm
+if
+.I realm
+is not supplied on the command line), decrypts the response using
+the service key found in
+.I srvtab
+(or in
+.B /etc/srvtab
+if
+.I srvtab
+is not specified on the command line), and stores the ticket in the
+standard ticket cache.
+.PP
+This command is intended primarily for use in shell scripts and other
+batch-type facilities.
+.SH DIAGNOSTICS
+"Generic kerberos failure (kfailure)" can indicate a whole range of
+problems, the most common of which is the inability to read the service
+key file.
+.SH FILES
+.TP 2i
+/etc/krb.conf
+to get the name of the local realm.
+.TP
+/tmp/tkt[uid]
+The default ticket file.
+.TP
+/etc/srvtab
+The default service key file.
+.SH SEE ALSO
+kerberos(1), kinit(1), kdestroy(1)
diff --git a/eBones/usr.bin/ksrvtgt/ksrvtgt.c b/eBones/usr.bin/ksrvtgt/ksrvtgt.c
new file mode 100644
index 0000000..46bbd56
--- /dev/null
+++ b/eBones/usr.bin/ksrvtgt/ksrvtgt.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Get a ticket-granting-ticket given a service key file (srvtab)
+ * The lifetime is the shortest allowed [1 five-minute interval]
+ *
+ * from: ksrvtgt.c,v 4.3 89/07/28 10:17:28 jtkohl Exp $
+ * $Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+const char rcsid[] =
+"$Id: ksrvtgt.c,v 1.2 1994/07/19 19:26:56 g89r4222 Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <krb.h>
+#include <conf.h>
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char realm[REALM_SZ + 1];
+ register int code;
+ char srvtab[MAXPATHLEN + 1];
+
+ bzero(realm, sizeof(realm));
+ bzero(srvtab, sizeof(srvtab));
+
+ if (argc < 3 || argc > 5) {
+ fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ if (argc == 4)
+ (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1);
+
+ if (argc == 5) {
+ (void) strncpy(realm, argv[3], sizeof(realm) - 1);
+ (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1);
+ }
+
+ if (srvtab[0] == 0)
+ (void) strcpy(srvtab, KEYFILE);
+
+ if (realm[0] == 0)
+ if (krb_get_lrealm(realm) != KSUCCESS)
+ (void) strcpy(realm, KRB_REALM);
+
+ code = krb_get_svc_in_tkt(argv[1], argv[2], realm,
+ "krbtgt", realm, 1, srvtab);
+ if (code)
+ fprintf(stderr, "%s\n", krb_err_txt[code]);
+ exit(code);
+}
diff --git a/eBones/usr.bin/register/Makefile b/eBones/usr.bin/register/Makefile
new file mode 100644
index 0000000..3ab09c3
--- /dev/null
+++ b/eBones/usr.bin/register/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+# $Id: Makefile,v 1.4 1994/07/20 09:21:07 g89r4222 Exp $
+
+PROG= register
+SRCS= register.c
+CFLAGS+=-DCRYPT -DDEBUG -DKERBEROS -I${.CURDIR}/../include
+.PATH: ${.CURDIR}/../../usr.bin/rlogin
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes -lcrypt
+BINDIR= /usr/bin
+BINOWN= root
+BINMODE=4555
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/register/pathnames.h b/eBones/usr.bin/register/pathnames.h
new file mode 100644
index 0000000..611c54f
--- /dev/null
+++ b/eBones/usr.bin/register/pathnames.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/1/93
+ */
+
+#define SERVER_KEYDIR "/etc/kerberosIV/register_keys"
+#define CLIENT_KEYFILE "/etc/kerberosIV/.update.key"
+#define KEYFILE_BASE ".update.key"
+#define _PATH_KPASSWD "/usr/bin/passwd"
diff --git a/eBones/usr.bin/register/register.1 b/eBones/usr.bin/register/register.1
new file mode 100644
index 0000000..d8bf104
--- /dev/null
+++ b/eBones/usr.bin/register/register.1
@@ -0,0 +1,63 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)register.1 8.1 (Berkeley) 6/1/93
+.\"
+.TH REGISTER 1 "June 1, 1993"
+.UC 7
+.SH NAME
+register \- register with Kerberos
+.SH SYNOPSIS
+.B register
+.SH DESCRIPTION
+The
+.I register
+command
+is used to register a new user with Kerberos.
+The Kerberos server keeps record of certain trusted hosts
+from which it will accept new registrations.
+If the host on which
+.I register
+is run is trusted by Kerberos, the user
+is asked for his current password, and then
+a new password to be used with Kerberos.
+A user may only register with Kerberos one time.
+.SH FILES
+.br
+/.update.keyxx.xx.xx.xx shared DES key with server
+.SH "SEE ALSO"
+registerd(8), kerberos(1)
+.SH DIAGNOSTICS
+\*(lqPrincipal not unique\*(rq
+if the user already exists in the Kerberos database.
+.br
+\*(lqPermission Denied,\*(rq
+if the host on which register is being run is untrusted.
diff --git a/eBones/usr.bin/register/register.c b/eBones/usr.bin/register/register.c
new file mode 100644
index 0000000..d20f848
--- /dev/null
+++ b/eBones/usr.bin/register/register.c
@@ -0,0 +1,311 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+#define SERVICE "krbupdate" /* service to add to KDC's database */
+#define PROTO "tcp"
+
+char realm[REALM_SZ];
+char krbhst[MAX_HSTNM];
+
+static char pname[ANAME_SZ];
+static char iname[INST_SZ];
+static char password[_PASSWORD_LEN];
+
+/* extern char *sys_errlist; */
+void die();
+void setup_key(), type_info(), cleanup();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct servent *se;
+ struct hostent *host;
+ struct sockaddr_in sin, local;
+ int rval;
+ int sock, llen;
+ u_char code;
+ static struct rlimit rl = { 0, 0 };
+
+ signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ perror("rlimit");
+ exit(1);
+ }
+
+ if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
+ fprintf(stderr, "couldn't find entry for service %s\n",
+ SERVICE);
+ exit(1);
+ }
+ if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get Kerberos host: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((host = gethostbyname(krbhst)) == NULL) {
+ fprintf(stderr, "couldn't get host entry for host %s\n",
+ krbhst);
+ exit(1);
+ }
+
+ sin.sin_family = host->h_addrtype;
+ (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
+ sin.sin_port = se->s_port;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+ perror("connect");
+ (void)close(sock);
+ exit(1);
+ }
+
+ llen = sizeof(local);
+ if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
+ perror("getsockname");
+ (void)close(sock);
+ exit(1);
+ }
+
+ setup_key(local);
+
+ type_info();
+
+ if (!get_user_info()) {
+ code = ABORT;
+ (void)des_write(sock, &code, 1);
+ cleanup();
+ exit(1);
+ }
+
+ code = APPEND_DB;
+ if (des_write(sock, &code, 1) != 1) {
+ perror("write 1");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
+ perror("write principal name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, iname, INST_SZ) != INST_SZ) {
+ perror("write instance name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, password, 255) != 255) {
+ perror("write password");
+ cleanup();
+ exit(1);
+ }
+
+ /* get return message */
+
+ {
+ int cc;
+ char msgbuf[BUFSIZ];
+
+ cc = read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during key verification\n");
+ cleanup();
+ exit(1);
+ }
+ if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
+ fprintf(stderr, "%s: %s", krbhst, msgbuf);
+ cleanup();
+ exit(1);
+ }
+
+ cc = des_read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during read\n");
+ cleanup();
+ exit(1);
+ } else {
+ printf("%s: %s", krbhst, msgbuf);
+ }
+ }
+
+ cleanup();
+ (void)close(sock);
+}
+
+void
+cleanup()
+{
+ bzero(password, 255);
+}
+
+extern char *crypt();
+extern char *getpass();
+
+int
+get_user_info()
+{
+ int uid = getuid();
+ int valid = 0, i;
+ struct passwd *pw;
+ char *pas, *namep;
+
+ /* NB: we must run setuid-root to get at the real pw file */
+
+ if ((pw = getpwuid(uid)) == NULL) {
+ fprintf(stderr, "Who are you?\n");
+ return(0);
+ }
+ (void)seteuid(uid);
+ (void)strcpy(pname, pw->pw_name); /* principal name */
+
+ for (i = 1; i < 3; i++) {
+ pas = getpass("login password:");
+ namep = crypt(pas, pw->pw_passwd);
+ if (strcmp(namep, pw->pw_passwd)) {
+ fprintf(stderr, "Password incorrect\n");
+ continue;
+ } else {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid)
+ return(0);
+ pas = getpass("Kerberos password (may be the same):");
+ while (*pas == NULL) {
+ printf("<NULL> password not allowed\n");
+ pas = getpass("Kerberos password (may be the same):");
+ }
+ (void)strcpy(password, pas); /* password */
+ pas = getpass("Retype Kerberos password:");
+ if (strcmp(password, pas)) {
+ fprintf(stderr, "Password mismatch -- aborted\n");
+ return(0);
+ }
+
+ iname[0] = NULL; /* null instance name */
+ return(1);
+}
+
+void
+setup_key(local)
+ struct sockaddr_in local;
+{
+ static struct keyfile_data kdata;
+ static Key_schedule schedule;
+ int fd;
+ char namebuf[MAXPATHLEN];
+ extern int errno;
+
+ (void) sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(local.sin_addr));
+
+ fd = open(namebuf, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "couldn't open key file %s for local host: ",
+ namebuf);
+ perror("");
+ exit(1);
+ }
+
+ if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
+ fprintf(stderr,"size error reading key file for local host %s\n",
+ inet_ntoa(local.sin_addr));
+ exit(1);
+ }
+ key_sched(kdata.kf_key, schedule);
+ des_set_key(kdata.kf_key, schedule);
+ return;
+}
+
+void
+type_info()
+{
+ printf("Kerberos user registration (realm %s)\n\n", realm);
+ printf("Please enter your login password followed by your new Kerberos password.\n");
+ printf("The Kerberos password you enter now will be used in the future\n");
+ printf("as your Kerberos password for all machines in the %s realm.\n", realm);
+ printf("You will only be allowed to perform this operation once, although you may run\n");
+ printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
+}
+
+void
+die()
+{
+ fprintf(stderr, "\nServer no longer listening\n");
+ fflush(stderr);
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/usr.bin/register/register_proto.h b/eBones/usr.bin/register/register_proto.h
new file mode 100644
index 0000000..5478949
--- /dev/null
+++ b/eBones/usr.bin/register/register_proto.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)register_proto.h 8.1 (Berkeley) 6/1/93
+ */
+
+#define APPEND_DB 0x01
+#define ABORT 0x02
+
+#define GOTKEY_MSG "GOTKEY"
+
+struct keyfile_data {
+ C_Block kf_key;
+};
diff --git a/eBones/usr.sbin/ext_srvtab/Makefile b/eBones/usr.sbin/ext_srvtab/Makefile
new file mode 100644
index 0000000..f30bbbb
--- /dev/null
+++ b/eBones/usr.sbin/ext_srvtab/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:22:34 g89r4222 Exp $
+
+PROG= ext_srvtab
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD+= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.8 b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8
new file mode 100644
index 0000000..af980a9
--- /dev/null
+++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.8
@@ -0,0 +1,63 @@
+.\" from: ext_srvtab.8,v 4.2 89/07/18 16:53:18 jtkohl Exp $
+.\" $Id: ext_srvtab.8,v 1.2 1994/07/19 19:27:20 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH EXT_SRVTAB 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ext_srvtab \- extract service key files from Kerberos key distribution center database
+.SH SYNOPSIS
+ext_srvtab [
+.B \-n
+] [
+.B \-r realm
+] [
+.B hostname ...
+]
+.SH DESCRIPTION
+.I ext_srvtab
+extracts service key files from the Kerberos key distribution center
+(KDC) database.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database. If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+For each
+.I hostname
+specified on the command line,
+.I ext_srvtab
+creates the service key file
+.IR hostname -new-srvtab,
+containing all the entries in the database with an instance field of
+.I hostname.
+This new file contains all the keys registered for Kerberos-mediated
+service providing programs which use the
+.IR krb_get_phost (3)
+principal and instance conventions to run on the host
+.IR hostname .
+If the
+.B \-r
+option is specified, the realm fields in the extracted file will
+match the given realm rather than the local realm.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+.IR hostname -new-srvtab
+Service key file generated for
+.I hostname
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH SEE ALSO
+read_service_key(3), krb_get_phost(3)
diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.c b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c
new file mode 100644
index 0000000..3a5dcec
--- /dev/null
+++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $
+ * $Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: ext_srvtab.c,v 1.2 1994/07/19 19:22:36 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#define TRUE 1
+#define FALSE 0
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+char progname[] = "ext_srvtab";
+char realm[REALM_SZ];
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ FILE *fout;
+ char fname[1024];
+ int fopen_errs = 0;
+ int arg;
+ Principal princs[40];
+ int more;
+ int prompt = TRUE;
+ register int n, i;
+
+ bzero(realm, sizeof(realm));
+
+ /* Parse commandline arguments */
+ if (argc < 2)
+ usage();
+ else {
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-n") == 0)
+ prompt = FALSE;
+ else if (strcmp(argv[i], "-r") == 0) {
+ if (++i >= argc)
+ usage();
+ else {
+ strcpy(realm, argv[i]);
+ /*
+ * This is to humor the broken way commandline
+ * argument parsing is done. Later, this
+ * program ignores everything that starts with -.
+ */
+ argv[i][0] = '-';
+ }
+ }
+ else if (argv[i][0] == '-')
+ usage();
+ else
+ if (!k_isinst(argv[i])) {
+ fprintf(stderr, "%s: bad instance name: %s\n",
+ progname, argv[i]);
+ usage();
+ }
+ }
+ }
+
+ if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ fflush (stderr);
+ exit(1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ exit(1);
+ }
+
+ /* For each arg, search for instances of arg, and produce */
+ /* srvtab file */
+ if (!realm[0])
+ if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ fprintf(stderr, "%s: couldn't get local realm\n", progname);
+ exit(1);
+ }
+ (void) umask(077);
+
+ for (arg = 1; arg < argc; arg++) {
+ if (argv[arg][0] == '-')
+ continue;
+ sprintf(fname, "%s-new-srvtab", argv[arg]);
+ if ((fout = fopen(fname, "w")) == NULL) {
+ fprintf(stderr, "Couldn't create file '%s'.\n", fname);
+ fopen_errs++;
+ continue;
+ }
+ printf("Generating '%s'....\n", fname);
+ n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more);
+ if (more)
+ fprintf(stderr, "More than 40 found...\n");
+ for (i = 0; i < n; i++) {
+ FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout);
+ FWrite(princs[i].instance, strlen(princs[i].instance) + 1,
+ 1, fout);
+ FWrite(realm, strlen(realm) + 1, 1, fout);
+ FWrite(&princs[i].key_version,
+ sizeof(princs[i].key_version), 1, fout);
+ bcopy(&princs[i].key_low, session_key, sizeof(long));
+ bcopy(&princs[i].key_high, session_key + sizeof(long),
+ sizeof(long));
+ kdb_encrypt_key (session_key, session_key,
+ master_key, master_key_schedule, DES_DECRYPT);
+ FWrite(session_key, sizeof session_key, 1, fout);
+ }
+ fclose(fout);
+ }
+
+ StampOutSecrets();
+
+ exit(fopen_errs); /* 0 errors if successful */
+
+}
+
+Die()
+{
+ StampOutSecrets();
+ exit(1);
+}
+
+FWrite(p, size, n, f)
+ char *p;
+ int size;
+ int n;
+ FILE *f;
+{
+ if (fwrite(p, size, n, f) != n) {
+ printf("Error writing output file. Terminating.\n");
+ Die();
+ }
+}
+
+StampOutSecrets()
+{
+ bzero(master_key, sizeof master_key);
+ bzero(session_key, sizeof session_key);
+ bzero(master_key_schedule, sizeof master_key_schedule);
+}
+
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kadmin/kadmind.8 b/eBones/usr.sbin/kadmin/kadmind.8
new file mode 100644
index 0000000..59075ee
--- /dev/null
+++ b/eBones/usr.sbin/kadmin/kadmind.8
@@ -0,0 +1,117 @@
+.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $
+.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmind \- network daemon for Kerberos database administration
+.SH SYNOPSIS
+.B kadmind
+[
+.B \-n
+] [
+.B \-h
+] [
+.B \-r realm
+] [
+.B \-f filename
+] [
+.B \-d dbname
+] [
+.B \-a acldir
+]
+.SH DESCRIPTION
+.I kadmind
+is the network database server for the Kerberos password-changing and
+administration tools.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.
+.PP
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+If the
+.B \-r
+.I realm
+option is specified, the admin server will pretend that its
+local realm is
+.I realm
+instead of the actual local realm of the host it is running on.
+This makes it possible to run a server for a foreign kerberos
+realm.
+.PP
+If the
+.B \-f
+.I filename
+option is specified, then that file is used to hold the log information
+instead of the default.
+.PP
+If the
+.B \-d
+.I dbname
+option is specified, then that file is used as the database name instead
+of the default.
+.PP
+If the
+.B \-a
+.I acldir
+option is specified, then
+.I acldir
+is used as the directory in which to search for access control lists
+instead of the default.
+.PP
+If the
+.B \-h
+option is specified,
+.I kadmind
+prints out a short summary of the permissible control arguments, and
+then exits.
+.PP
+When performing requests on behalf of clients,
+.I kadmind
+checks access control lists (ACLs) to determine the authorization of the client
+to perform the requested action.
+Currently three distinct access types are supported:
+.TP 1i
+Addition
+(.add ACL file). If a principal is on this list, it may add new
+principals to the database.
+.TP
+Retrieval
+(.get ACL file). If a principal is on this list, it may retrieve
+database entries. NOTE: A principal's private key is never returned by
+the get functions.
+.TP
+Modification
+(.mod ACL file). If a principal is on this list, it may modify entries
+in the database.
+.PP
+A principal is always granted authorization to change its own password.
+.SH FILES
+.TP 20n
+/kerberos/admin_server.syslog
+Default log file.
+.TP
+/kerberos
+Default access control list directory.
+.TP
+admin_acl.{add,get,mod}
+Access control list files (within the directory)
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+Default DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH "SEE ALSO"
+kerberos(1), kpasswd(1), kadmin(8), acl_check(3)
+.SH AUTHORS
+Douglas A. Church, MIT Project Athena
+.br
+John T. Kohl, Project Athena/Digital Equipment Corporation
diff --git a/eBones/usr.sbin/kadmind/kadmind.8 b/eBones/usr.sbin/kadmind/kadmind.8
new file mode 100644
index 0000000..59075ee
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/kadmind.8
@@ -0,0 +1,117 @@
+.\" from: kadmind.8,v 4.1 89/07/25 17:28:33 jtkohl Exp $
+.\" $Id: kadmind.8,v 1.2 1994/07/19 19:27:25 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KADMIND 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kadmind \- network daemon for Kerberos database administration
+.SH SYNOPSIS
+.B kadmind
+[
+.B \-n
+] [
+.B \-h
+] [
+.B \-r realm
+] [
+.B \-f filename
+] [
+.B \-d dbname
+] [
+.B \-a acldir
+]
+.SH DESCRIPTION
+.I kadmind
+is the network database server for the Kerberos password-changing and
+administration tools.
+.PP
+Upon execution, it prompts the user to enter the master key string for
+the database.
+.PP
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+If the
+.B \-r
+.I realm
+option is specified, the admin server will pretend that its
+local realm is
+.I realm
+instead of the actual local realm of the host it is running on.
+This makes it possible to run a server for a foreign kerberos
+realm.
+.PP
+If the
+.B \-f
+.I filename
+option is specified, then that file is used to hold the log information
+instead of the default.
+.PP
+If the
+.B \-d
+.I dbname
+option is specified, then that file is used as the database name instead
+of the default.
+.PP
+If the
+.B \-a
+.I acldir
+option is specified, then
+.I acldir
+is used as the directory in which to search for access control lists
+instead of the default.
+.PP
+If the
+.B \-h
+option is specified,
+.I kadmind
+prints out a short summary of the permissible control arguments, and
+then exits.
+.PP
+When performing requests on behalf of clients,
+.I kadmind
+checks access control lists (ACLs) to determine the authorization of the client
+to perform the requested action.
+Currently three distinct access types are supported:
+.TP 1i
+Addition
+(.add ACL file). If a principal is on this list, it may add new
+principals to the database.
+.TP
+Retrieval
+(.get ACL file). If a principal is on this list, it may retrieve
+database entries. NOTE: A principal's private key is never returned by
+the get functions.
+.TP
+Modification
+(.mod ACL file). If a principal is on this list, it may modify entries
+in the database.
+.PP
+A principal is always granted authorization to change its own password.
+.SH FILES
+.TP 20n
+/kerberos/admin_server.syslog
+Default log file.
+.TP
+/kerberos
+Default access control list directory.
+.TP
+admin_acl.{add,get,mod}
+Access control list files (within the directory)
+.TP
+/kerberos/principal.pag, /kerberos/principal.dir
+Default DBM files containing database
+.TP
+/.k
+Master key cache file.
+.SH "SEE ALSO"
+kerberos(1), kpasswd(1), kadmin(8), acl_check(3)
+.SH AUTHORS
+Douglas A. Church, MIT Project Athena
+.br
+John T. Kohl, Project Athena/Digital Equipment Corporation
diff --git a/eBones/usr.sbin/kdb_destroy/Makefile b/eBones/usr.sbin/kdb_destroy/Makefile
new file mode 100644
index 0000000..a48805b
--- /dev/null
+++ b/eBones/usr.sbin/kdb_destroy/Makefile
@@ -0,0 +1,8 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:23:46 g89r4222 Exp $
+
+PROG= kdb_destroy
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.8 b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8
new file mode 100644
index 0000000..93db466
--- /dev/null
+++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.8
@@ -0,0 +1,33 @@
+.\" from: kdb_destroy.8,v 4.1 89/01/23 11:08:02 jtkohl Exp $
+.\" $Id: kdb_destroy.8,v 1.2 1994/07/19 19:27:26 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_DESTROY 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_destroy \- destroy Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_destroy
+.SH DESCRIPTION
+.I kdb_destroy
+deletes a Kerberos key distribution center database.
+.PP
+The user is prompted to verify that the database should be destroyed. A
+response beginning with `y' or `Y' confirms deletion.
+Any other response aborts deletion.
+.SH DIAGNOSTICS
+.TP 20n
+"Database cannot be deleted at /kerberos/principal"
+The attempt to delete the database failed (probably due to a system or
+access permission error).
+.TP
+"Database not deleted."
+The user aborted the deletion.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.SH SEE ALSO
+kdb_init(8)
diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.c b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c
new file mode 100644
index 0000000..0c45896
--- /dev/null
+++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $
+ * $Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_destroy.c,v 1.2 1994/07/19 19:23:49 g89r4222 Exp $";
+#endif lint
+
+#include <strings.h>
+#include <stdio.h>
+#include "krb.h"
+#include "krb_db.h"
+
+main()
+{
+ char answer[10]; /* user input */
+ char dbm[256]; /* database path and name */
+ char dbm1[256]; /* database path and name */
+ char *file1, *file2; /* database file names */
+
+ strcpy(dbm, DBM_FILE);
+ strcpy(dbm1, DBM_FILE);
+ file1 = strcat(dbm, ".dir");
+ file2 = strcat(dbm1, ".pag");
+
+ printf("You are about to destroy the Kerberos database ");
+ printf("on this machine.\n");
+ printf("Are you sure you want to do this (y/n)? ");
+ fgets(answer, sizeof(answer), stdin);
+
+ if (answer[0] == 'y' || answer[0] == 'Y') {
+ if (unlink(file1) == 0 && unlink(file2) == 0)
+ fprintf(stderr, "Database deleted at %s\n", DBM_FILE);
+ else
+ fprintf(stderr, "Database cannot be deleted at %s\n",
+ DBM_FILE);
+ } else
+ fprintf(stderr, "Database not deleted.\n");
+}
diff --git a/eBones/usr.sbin/kdb_edit/Makefile b/eBones/usr.sbin/kdb_edit/Makefile
new file mode 100644
index 0000000..65a5e5a
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/Makefile
@@ -0,0 +1,12 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $
+
+PROG= kdb_edit
+CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include
+SRCS= kdb_edit.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.8 b/eBones/usr.sbin/kdb_edit/kdb_edit.8
new file mode 100644
index 0000000..1cfd6ed
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.8
@@ -0,0 +1,55 @@
+.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $
+.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_edit \- Kerberos key distribution center database editing utility
+.SH SYNOPSIS
+kdb_edit [
+.B \-n
+]
+.SH DESCRIPTION
+.I kdb_edit
+is used to create or change principals stored in the Kerberos key
+distribution center (KDC) database.
+.PP
+When executed,
+.I kdb_edit
+prompts for the master key string and verifies that it matches the
+master key stored in the database.
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+Once the master key has been verified,
+.I kdb_edit
+begins a prompt loop. The user is prompted for the principal and
+instance to be modified. If the entry is not found the user may create
+it.
+Once an entry is found or created, the user may set the password,
+expiration date, maximum ticket lifetime, and attributes.
+Default expiration dates, maximum ticket lifetimes, and attributes are
+presented in brackets; if the user presses return the default is selected.
+There is no default password.
+The password RANDOM is interpreted specially, and if entered
+the user may have the program select a random DES key for the
+principal.
+.PP
+Upon successfully creating or changing the entry, ``Edit O.K.'' is
+printed.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c
new file mode 100644
index 0000000..4c02db6
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services.
+ *
+ * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
+ * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $
+ */
+
+/*
+ * exit returns 0 ==> success -1 ==> error
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include "time.h"
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+/* MKEYFILE is now defined in kdc.h */
+#include <kdc.h>
+
+extern char *errmsg();
+extern int errno;
+extern char *strcpy();
+
+void sig_exit();
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+char prog[32];
+char *progname = prog;
+int nflag = 0;
+int cflag;
+int lflag;
+int uflag;
+int debug;
+extern kerb_debug;
+
+Key_schedule KS;
+C_Block new_key;
+unsigned char *input;
+
+unsigned char *ivec;
+int i, j;
+int more;
+
+char *in_ptr;
+char input_name[ANAME_SZ];
+char input_instance[INST_SZ];
+char input_string[ANAME_SZ];
+
+#define MAX_PRINCIPAL 10
+Principal principal_data[MAX_PRINCIPAL];
+
+static Principal old_principal;
+static Principal default_princ;
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+static char pw_str[255];
+static long master_key_version;
+
+/*
+ * gets replacement
+ */
+static char * s_gets(char * str, int len)
+{
+ int i;
+ char *s;
+
+ if((s = fgets(str, len, stdin)) == NULL)
+ return(s);
+ if(str[i = (strlen(str)-1)] == '\n')
+ str[i] = '\0';
+ return(s);
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ /* Local Declarations */
+
+ long n;
+
+ prog[sizeof prog - 1] = '\0'; /* make sure terminated */
+ strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
+ * program */
+
+ /* Assume a long is four bytes */
+ if (sizeof(long) != 4) {
+ fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
+ exit(-1);
+ }
+ /* Assume <=32 signals */
+ if (NSIG > 32) {
+ fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
+ exit(-1);
+ }
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i = 1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ debug = 1;
+ continue;
+
+ /* debug flag */
+ case 'l':
+ kerb_debug |= 1;
+ continue;
+
+ case 'n': /* read MKEYFILE for master key */
+ nflag = 1;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: illegal flag \"%c\"\n",
+ progname, argv[0][i]);
+ Usage(); /* Give message and die */
+ }
+ };
+
+ fprintf(stdout, "Opening database...\n");
+ fflush(stdout);
+ kerb_init();
+ if (argc > 0) {
+ if (kerb_db_set_name(*argv) != 0) {
+ fprintf(stderr, "Could not open altername database name\n");
+ exit(1);
+ }
+ }
+
+#ifdef notdef
+ no_core_dumps(); /* diddle signals to avoid core dumps! */
+
+ /* ignore whatever is reasonable */
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+
+#endif
+
+ if (kdb_get_master_key ((nflag == 0),
+ master_key, master_key_schedule) != 0) {
+ fprintf (stdout, "Couldn't read master key.\n");
+ fflush (stdout);
+ exit (-1);
+ }
+
+ if ((master_key_version = kdb_verify_master_key(master_key,
+ master_key_schedule,
+ stdout)) < 0)
+ exit (-1);
+
+ /* lookup the default values */
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (n != 1) {
+ fprintf(stderr,
+ "%s: Kerberos error on default value lookup, %d found.\n",
+ progname, n);
+ exit(-1);
+ }
+ fprintf(stdout, "Previous or default values are in [brackets] ,\n");
+ fprintf(stdout, "enter return to leave the same, or new value.\n");
+
+ while (change_principal()) {
+ }
+
+ cleanup();
+}
+
+change_principal()
+{
+ static char temp[255];
+ int creating = 0;
+ int editpw = 0;
+ int changed = 0;
+ long temp_long;
+ int n;
+ struct tm *tp, edate, *localtime();
+ long maketime();
+
+ fprintf(stdout, "\nPrincipal name: ");
+ fflush(stdout);
+ if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0')
+ return 0;
+ fprintf(stdout, "Instance: ");
+ fflush(stdout);
+ /* instance can be null */
+ s_gets(input_instance, INST_SZ-1);
+ j = kerb_get_principal(input_name, input_instance, principal_data,
+ MAX_PRINCIPAL, &more);
+ if (!j) {
+ fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
+ s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */
+ if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
+ return -1;
+ /* make a new principal, fill in defaults */
+ j = 1;
+ creating = 1;
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+ principal_data[0].exp_date = default_princ.exp_date;
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
+ principal_data[0].key_version = 0; /* bumped up later */
+ }
+ tp = localtime(&principal_data[0].exp_date);
+ (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+ for (i = 0; i < j; i++) {
+ for (;;) {
+ fprintf(stdout,
+ "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
+ principal_data[i].name, principal_data[i].instance,
+ principal_data[i].kdc_key_ver);
+ editpw = 1;
+ changed = 0;
+ if (!creating) {
+ /*
+ * copy the existing data so we can use the old values
+ * for the qualifier clause of the replace
+ */
+ principal_data[i].old = (char *) &old_principal;
+ bcopy(&principal_data[i], &old_principal,
+ sizeof(old_principal));
+ printf("\nChange password [n] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (strcmp("y", temp) && strcmp("Y", temp))
+ editpw = 0;
+ }
+ /* password */
+ if (editpw) {
+#ifdef NOENCRYPTION
+ placebo_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#else
+ des_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#endif
+ if (!strcmp(pw_str, "RANDOM")) {
+ printf("\nRandom password [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "RANDOM" */
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+ } else if (!strcmp(pw_str, "NULL")) {
+ printf("\nNull Key [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "NULL" */
+ } else {
+
+ principal_data[i].key_low = 0;
+ principal_data[i].key_high = 0;
+ goto null_key;
+ }
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str,new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+
+ /* seal it under the kerberos master key */
+ kdb_encrypt_key (new_key, new_key,
+ master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal_data[i].key_low, 4);
+ bcopy(((long *) new_key) + 1,
+ &principal_data[i].key_high, 4);
+ bzero(new_key, sizeof(new_key));
+ null_key:
+ /* set master key version */
+ principal_data[i].kdc_key_ver =
+ (unsigned char) master_key_version;
+ /* bump key version # */
+ principal_data[i].key_version++;
+ fprintf(stdout,
+ "\nPrincipal's new key version = %d\n",
+ principal_data[i].key_version);
+ fflush(stdout);
+ changed = 1;
+ }
+ /* expiration date */
+ fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) >
+ sizeof(principal_data[0].exp_date_txt))) {
+ bad_date:
+ fprintf(stdout, "\07\07Date Invalid\n");
+ fprintf(stdout,
+ "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ }
+
+ if (*temp) {
+ if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
+ &edate.tm_mon, &edate.tm_mday) != 3)
+ goto bad_date;
+ (void) strcpy(principal_data[i].exp_date_txt, temp);
+ edate.tm_mon--; /* January is 0, not 1 */
+ edate.tm_hour = 23; /* nearly midnight at the end of the */
+ edate.tm_min = 59; /* specified day */
+ if (!(principal_data[i].exp_date = maketime(&edate, 1)))
+ goto bad_date;
+ changed = 1;
+ }
+
+ /* maximum lifetime */
+ fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_life;
+ if (temp_long > 255 || (temp_long < 0)) {
+ bad_life:
+ fprintf(stdout, "\07\07Invalid, choose 0-255\n");
+ fprintf(stdout,
+ "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].max_life = (unsigned short) temp_long;
+ break;
+ }
+
+ /* attributes */
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_att;
+ if (temp_long > 65535 || (temp_long < 0)) {
+ bad_att:
+ fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].attributes =
+ (unsigned short) temp_long;
+ break;
+ }
+
+ /*
+ * remaining fields -- key versions and mod info, should
+ * not be directly manipulated
+ */
+ if (changed) {
+ if (kerb_put_principal(&principal_data[i], 1)) {
+ fprintf(stdout,
+ "\nError updating Kerberos database");
+ } else {
+ fprintf(stdout, "Edit O.K.");
+ }
+ } else {
+ fprintf(stdout, "Unchanged");
+ }
+
+
+ bzero(&principal_data[i].key_low, 4);
+ bzero(&principal_data[i].key_high, 4);
+ fflush(stdout);
+ break;
+ }
+ }
+ if (more) {
+ fprintf(stdout, "\nThere were more tuples found ");
+ fprintf(stdout, "than there were space for");
+ }
+ return 1;
+}
+
+
+no_core_dumps()
+{
+
+ signal(SIGQUIT, sig_exit);
+ signal(SIGILL, sig_exit);
+ signal(SIGTRAP, sig_exit);
+ signal(SIGIOT, sig_exit);
+ signal(SIGEMT, sig_exit);
+ signal(SIGFPE, sig_exit);
+ signal(SIGBUS, sig_exit);
+ signal(SIGSEGV, sig_exit);
+ signal(SIGSYS, sig_exit);
+}
+
+void
+sig_exit(sig, code, scp)
+ int sig, code;
+ struct sigcontext *scp;
+{
+ cleanup();
+ fprintf(stderr,
+ "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
+ sig, code, scp->sc_pc);
+ exit(-1);
+}
+
+
+cleanup()
+{
+
+ bzero(master_key, sizeof(master_key));
+ bzero(session_key, sizeof(session_key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(principal_data, sizeof(principal_data));
+ bzero(new_key, sizeof(new_key));
+ bzero(pw_str, sizeof(pw_str));
+}
+Usage()
+{
+ fprintf(stderr, "Usage: %s [-n]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kdb_edit/maketime.c b/eBones/usr.sbin/kdb_edit/maketime.c
new file mode 100644
index 0000000..057ecc3
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/maketime.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Convert a struct tm * to a UNIX time.
+ *
+ * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $
+ * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp ";
+#endif lint
+
+#include <sys/time.h>
+
+#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define SECSPERDAY 24*60*60
+#define SECSPERHOUR 60*60
+#define SECSPERMIN 60
+
+static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+ 365};
+
+static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+long
+maketime(tp, local)
+register struct tm *tp;
+int local;
+{
+ register long retval;
+ int foo;
+ int *marray;
+
+ if (tp->tm_mon < 0 || tp->tm_mon > 11 ||
+ tp->tm_hour < 0 || tp->tm_hour > 23 ||
+ tp->tm_min < 0 || tp->tm_min > 59 ||
+ tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */
+ return 0;
+
+ retval = 0;
+ if (tp->tm_year < 1900)
+ foo = tp->tm_year + 1900;
+ else
+ foo = tp->tm_year;
+
+ if (foo < 1901 || foo > 2038) /* year is too small/large */
+ return 0;
+
+ if (daysinyear(foo) == 366) {
+ if (tp->tm_mon > 1)
+ retval+= SECSPERDAY; /* add leap day */
+ marray = leapyear;
+ } else
+ marray = nonleapyear;
+
+ if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon])
+ return 0; /* out of range */
+
+ while (--foo >= 1970)
+ retval += daysinyear(foo) * SECSPERDAY;
+
+ retval += cumdays[tp->tm_mon] * SECSPERDAY;
+ retval += (tp->tm_mday-1) * SECSPERDAY;
+ retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec;
+
+ if (local) {
+ /* need to use local time, so we retrieve timezone info */
+ struct timezone tz;
+ struct timeval tv;
+ if (gettimeofday(&tv, &tz) < 0) {
+ /* some error--give up? */
+ return(retval);
+ }
+ retval += tz.tz_minuteswest * SECSPERMIN;
+ }
+ return(retval);
+}
diff --git a/eBones/usr.sbin/kdb_edit/time.h b/eBones/usr.sbin/kdb_edit/time.h
new file mode 100644
index 0000000..ed128d8
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/time.h
@@ -0,0 +1,45 @@
+/* Structure for use by time manipulating subroutines.
+ * The following library routines use it:
+ * libc: ctime, localtime, gmtime, asctime
+ * libcx: partime, maketime (may not be installed yet)
+ */
+
+/*
+ * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $
+ * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $
+ */
+
+struct tm { /* See defines below for allowable ranges */
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ int tm_zon; /* NEW: mins westward of Greenwich */
+ int tm_ampm; /* NEW: 1 if AM, 2 if PM */
+};
+
+#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/
+#define TMNULL (-1) /* Items not specified are given this value
+ * in order to distinguish null specs from zero
+ * specs. This is only used by partime and
+ * maketime. */
+
+ /* Indices into TM structure */
+#define TM_SEC 0 /* 0-59 */
+#define TM_MIN 1 /* 0-59 */
+#define TM_HOUR 2 /* 0-23 */
+#define TM_MDAY 3 /* 1-31 day of month */
+#define TM_DAY TM_MDAY /* " synonym */
+#define TM_MON 4 /* 0-11 */
+#define TM_YEAR 5 /* (year-1900) (year) */
+#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */
+#define TM_YDAY 7 /* 0-365 day of year */
+#define TM_ISDST 8 /* 0 Std, 1 DST */
+ /* New stuff */
+#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */
+#define TM_AMPM 10 /* 1 AM, 2 PM */
diff --git a/eBones/usr.sbin/kdb_init/Makefile b/eBones/usr.sbin/kdb_init/Makefile
new file mode 100644
index 0000000..ce51a9f
--- /dev/null
+++ b/eBones/usr.sbin/kdb_init/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:03 g89r4222 Exp $
+
+PROG= kdb_init
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_init/kdb_init.8 b/eBones/usr.sbin/kdb_init/kdb_init.8
new file mode 100644
index 0000000..54537ad
--- /dev/null
+++ b/eBones/usr.sbin/kdb_init/kdb_init.8
@@ -0,0 +1,41 @@
+.\" from: kdb_init.8,v 4.1 89/01/23 11:09:02 jtkohl Exp $
+.\" $Id: kdb_init.8,v 1.2 1994/07/19 19:27:29 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_INIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_init \- Initialize Kerberos key distribution center database
+.SH SYNOPSIS
+kdb_init [
+.B realm
+]
+.SH DESCRIPTION
+.I kdb_init
+initializes a Kerberos key distribution center database, creating the
+necessary principals.
+.PP
+If the optional
+.I realm
+argument is not present,
+.I kdb_init
+prompts for a realm name (defaulting to the definition in /usr/include/krb.h).
+After determining the realm to be created, it prompts for
+a master key password. The master key password is used to encrypt
+every encryption key stored in the database.
+.SH DIAGNOSTICS
+.TP 20n
+"/kerberos/principal: File exists"
+An attempt was made to create a database on a machine which already had
+an existing database.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/usr/include/krb.h
+Include file defining default realm
+.SH SEE ALSO
+kdb_destroy(8)
diff --git a/eBones/usr.sbin/kdb_init/kdb_init.c b/eBones/usr.sbin/kdb_init/kdb_init.c
new file mode 100644
index 0000000..dc7055e
--- /dev/null
+++ b/eBones/usr.sbin/kdb_init/kdb_init.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * program to initialize the database, reports error if database file
+ * already exists.
+ *
+ * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $
+ * $Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_init.c,v 1.3 1994/09/24 14:04:17 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <string.h>
+
+#define TRUE 1
+
+enum ap_op {
+ NULL_KEY, /* setup null keys */
+ MASTER_KEY, /* use master key as new key */
+ RANDOM_KEY, /* choose a random key */
+};
+
+int debug = 0;
+char *progname, *rindex();
+C_Block master_key;
+Key_schedule master_key_schedule;
+
+main(argc, argv)
+ char *argv[];
+{
+ char realm[REALM_SZ];
+ char *cp;
+ int code;
+ char *database;
+
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ if (argc > 3) {
+ fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
+ exit(1);
+ }
+ if (argc == 3) {
+ database = argv[2];
+ --argc;
+ } else
+ database = DBM_FILE;
+
+ /* Do this first, it'll fail if the database exists */
+ if ((code = kerb_db_create(database)) != 0) {
+ fprintf(stderr, "Couldn't create database: %s\n",
+ sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(database);
+
+ if (argc == 2)
+ strncpy(realm, argv[1], REALM_SZ);
+ else {
+ fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM);
+ if (fgets(realm, sizeof(realm), stdin) == NULL) {
+ fprintf(stderr, "\nEOF reading realm\n");
+ exit(1);
+ }
+ if (cp = index(realm, '\n'))
+ *cp = '\0';
+ if (!*realm) /* no realm given */
+ strcpy(realm, KRB_REALM);
+ }
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n",
+ progname, realm);
+ exit(1);
+ }
+ printf("You will be prompted for the database Master Password.\n");
+ printf("It is important that you NOT FORGET this password.\n");
+ fflush(stdout);
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ exit (-1);
+ }
+
+ if (
+ add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) ||
+ add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) ||
+ add_principal("krbtgt", realm, RANDOM_KEY) ||
+ add_principal("changepw", KRB_MASTER, RANDOM_KEY)
+ ) {
+ fprintf(stderr, "\n%s: couldn't initialize database.\n",
+ progname);
+ exit(1);
+ }
+
+ /* play it safe */
+ bzero (master_key, sizeof (C_Block));
+ bzero (master_key_schedule, sizeof (Key_schedule));
+ exit(0);
+}
+
+/* use a return code to indicate success or failure. check the return */
+/* values of the routines called by this routine. */
+
+add_principal(name, instance, aap_op)
+ char *name, *instance;
+ enum ap_op aap_op;
+{
+ Principal principal;
+ char datestring[50];
+ char pw_str[255];
+ void read_pw_string();
+ void string_to_key();
+ void random_key();
+ struct tm *tm, *localtime();
+ C_Block new_key;
+
+ bzero(&principal, sizeof(principal));
+ strncpy(principal.name, name, ANAME_SZ);
+ strncpy(principal.instance, instance, INST_SZ);
+ switch (aap_op) {
+ case NULL_KEY:
+ principal.key_low = 0;
+ principal.key_high = 0;
+ break;
+ case RANDOM_KEY:
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ case MASTER_KEY:
+ bcopy (master_key, new_key, sizeof (C_Block));
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ }
+ principal.exp_date = 946702799; /* Happy new century */
+ strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ);
+ principal.mod_date = time(0);
+
+ tm = localtime(&principal.mod_date);
+ principal.attributes = 0;
+ principal.max_life = 255;
+
+ principal.kdc_key_ver = 1;
+ principal.key_version = 1;
+
+ strncpy(principal.mod_name, "db_creation", ANAME_SZ);
+ strncpy(principal.mod_instance, "", INST_SZ);
+ principal.old = 0;
+
+ kerb_db_put_principal(&principal, 1);
+
+ /* let's play it safe */
+ bzero (new_key, sizeof (C_Block));
+ bzero (&principal.key_low, 4);
+ bzero (&principal.key_high, 4);
+ return 0;
+}
diff --git a/eBones/usr.sbin/kdb_util/Makefile b/eBones/usr.sbin/kdb_util/Makefile
new file mode 100644
index 0000000..b3513d6
--- /dev/null
+++ b/eBones/usr.sbin/kdb_util/Makefile
@@ -0,0 +1,13 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.2 1994/07/19 19:24:09 g89r4222 Exp $
+
+PROG= kdb_util
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../kdb_edit \
+ -I${.CURDIR}/../include
+SRCS= kdb_util.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_util/kdb_util.8 b/eBones/usr.sbin/kdb_util/kdb_util.8
new file mode 100644
index 0000000..30a3b9f
--- /dev/null
+++ b/eBones/usr.sbin/kdb_util/kdb_util.8
@@ -0,0 +1,64 @@
+.\" from: kdb_util.8,v 4.1 89/01/23 11:09:11 jtkohl Exp $
+.\" $Id: kdb_util.8,v 1.2 1994/07/19 19:27:30 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_UTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_util \- Kerberos key distribution center database utility
+.SH SYNOPSIS
+kdb_util
+.B operation filename
+.SH DESCRIPTION
+.I kdb_util
+allows the Kerberos key distribution center (KDC) database administrator to
+perform utility functions on the database.
+.PP
+.I Operation
+must be one of the following:
+.TP 10n
+.I load
+initializes the KDC database with the records described by the
+text contained in the file
+.IR filename .
+Any existing database is overwritten.
+.TP
+.I dump
+dumps the KDC database into a text representation in the file
+.IR filename .
+.TP
+.I slave_dump
+performs a database dump like the
+.I dump
+operation, and additionally creates a semaphore file signalling the
+propagation software that an update is available for distribution to
+slave KDC databases.
+.TP
+.I new_master_key
+prompts for the old and new master key strings, and then dumps the KDC
+database into a text representation in the file
+.IR filename .
+The keys in the text representation are encrypted in the new master key.
+.TP
+.I convert_old_db
+prompts for the master key string, and then dumps the KDC database into
+a text representation in the file
+.IR filename .
+The existing database is assumed to be encrypted using the old format
+(encrypted by the key schedule of the master key); the dumped database
+is encrypted using the new format (encrypted directly with master key).
+.PP
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+.IR filename .ok
+semaphore file created by
+.IR slave_dump.
diff --git a/eBones/usr.sbin/kdb_util/kdb_util.c b/eBones/usr.sbin/kdb_util/kdb_util.c
new file mode 100644
index 0000000..8465b5b
--- /dev/null
+++ b/eBones/usr.sbin/kdb_util/kdb_util.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Kerberos database manipulation utility. This program allows you to
+ * dump a kerberos database to an ascii readable file and load this
+ * file into the database. Read locking of the database is done during a
+ * dump operation. NO LOCKING is done during a load operation. Loads
+ * should happen with other processes shutdown.
+ *
+ * Written July 9, 1987 by Jeffrey I. Schiller
+ *
+ * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $
+ * $Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_util.c,v 1.3 1994/09/24 14:04:21 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "time.h"
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <krb_db.h>
+
+#define TRUE 1
+
+Principal aprinc;
+
+static des_cblock master_key, new_master_key;
+static des_key_schedule master_key_schedule, new_master_key_schedule;
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+extern long kdb_get_master_key(), kdb_verify_master_key();
+extern char *malloc();
+extern int errno;
+
+char * progname;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *file;
+ enum {
+ OP_LOAD,
+ OP_DUMP,
+ OP_SLAVE_DUMP,
+ OP_NEW_MASTER,
+ OP_CONVERT_OLD_DB,
+ } op;
+ char *file_name;
+ char *prog = argv[0];
+ char *db_name;
+
+ progname = prog;
+
+ if (argc != 3 && argc != 4) {
+ fprintf(stderr, "Usage: %s operation file-name [database name].\n",
+ argv[0]);
+ exit(1);
+ }
+ if (argc == 3)
+ db_name = DBM_FILE;
+ else
+ db_name = argv[3];
+
+ if (kerb_db_set_name (db_name) != 0) {
+ perror("Can't open database");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "load"))
+ op = OP_LOAD;
+ else if (!strcmp(argv[1], "dump"))
+ op = OP_DUMP;
+ else if (!strcmp(argv[1], "slave_dump"))
+ op = OP_SLAVE_DUMP;
+ else if (!strcmp(argv[1], "new_master_key"))
+ op = OP_NEW_MASTER;
+ else if (!strcmp(argv[1], "convert_old_db"))
+ op = OP_CONVERT_OLD_DB;
+ else {
+ fprintf(stderr,
+ "%s: %s is an invalid operation.\n", prog, argv[1]);
+ fprintf(stderr,
+ "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);
+ fprintf(stderr,
+ "\"load\", \"new_master_key\", and \"convert_old_db\".\n");
+ exit(1);
+ }
+
+ file_name = argv[2];
+ file = fopen(file_name, op == OP_LOAD ? "r" : "w");
+ if (file == NULL) {
+ fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);
+ (void) fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+
+ switch (op) {
+ case OP_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ break;
+ case OP_SLAVE_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ update_ok_file (file_name);
+ break;
+ case OP_LOAD:
+ load_db (db_name, file);
+ break;
+ case OP_NEW_MASTER:
+ convert_new_master_key (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ case OP_CONVERT_OLD_DB:
+ convert_old_format_db (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ }
+ exit(0);
+ }
+
+clear_secrets ()
+{
+ bzero((char *)master_key, sizeof (des_cblock));
+ bzero((char *)master_key_schedule, sizeof (Key_schedule));
+ bzero((char *)new_master_key, sizeof (des_cblock));
+ bzero((char *)new_master_key_schedule, sizeof (Key_schedule));
+}
+
+/* cv_key is a procedure which takes a principle and changes its key,
+ either for a new method of encrypting the keys, or a new master key.
+ if cv_key is null no transformation of key is done (other than net byte
+ order). */
+
+struct callback_args {
+ void (*cv_key)();
+ FILE *output_file;
+};
+
+static int dump_db_1(arg, principal)
+ char *arg;
+ Principal *principal;
+{ /* replace null strings with "*" */
+ struct callback_args *a = (struct callback_args *)arg;
+
+ if (principal->instance[0] == '\0') {
+ principal->instance[0] = '*';
+ principal->instance[1] = '\0';
+ }
+ if (principal->mod_name[0] == '\0') {
+ principal->mod_name[0] = '*';
+ principal->mod_name[1] = '\0';
+ }
+ if (principal->mod_instance[0] == '\0') {
+ principal->mod_instance[0] = '*';
+ principal->mod_instance[1] = '\0';
+ }
+ if (a->cv_key != NULL) {
+ (*a->cv_key) (principal);
+ }
+ fprintf(a->output_file, "%s %s %d %d %d %d %x %x",
+ principal->name,
+ principal->instance,
+ principal->max_life,
+ principal->kdc_key_ver,
+ principal->key_version,
+ principal->attributes,
+ htonl (principal->key_low),
+ htonl (principal->key_high));
+ print_time(a->output_file, principal->exp_date);
+ print_time(a->output_file, principal->mod_date);
+ fprintf(a->output_file, " %s %s\n",
+ principal->mod_name,
+ principal->mod_instance);
+ return 0;
+}
+
+dump_db (db_file, output_file, cv_key)
+ char *db_file;
+ FILE *output_file;
+ void (*cv_key)();
+{
+ struct callback_args a;
+
+ a.cv_key = cv_key;
+ a.output_file = output_file;
+
+ kerb_db_iterate (dump_db_1, (char *)&a);
+ return fflush(output_file);
+}
+
+load_db (db_file, input_file)
+ char *db_file;
+ FILE *input_file;
+{
+ char exp_date_str[50];
+ char mod_date_str[50];
+ int temp1, temp2, temp3;
+ long time_explode();
+ int code;
+ char *temp_db_file;
+ temp1 = strlen(db_file+2);
+ temp_db_file = malloc (temp1);
+ strcpy(temp_db_file, db_file);
+ strcat(temp_db_file, "~");
+
+ /* Create the database */
+ if ((code = kerb_db_create(temp_db_file)) != 0) {
+ fprintf(stderr, "Couldn't create temp database %s: %s\n",
+ temp_db_file, sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(temp_db_file);
+ for (;;) { /* explicit break on eof from fscanf */
+ bzero((char *)&aprinc, sizeof(aprinc));
+ if (fscanf(input_file,
+ "%s %s %d %d %d %hd %x %x %s %s %s %s\n",
+ aprinc.name,
+ aprinc.instance,
+ &temp1,
+ &temp2,
+ &temp3,
+ &aprinc.attributes,
+ &aprinc.key_low,
+ &aprinc.key_high,
+ exp_date_str,
+ mod_date_str,
+ aprinc.mod_name,
+ aprinc.mod_instance) == EOF)
+ break;
+ aprinc.key_low = ntohl (aprinc.key_low);
+ aprinc.key_high = ntohl (aprinc.key_high);
+ aprinc.max_life = (unsigned char) temp1;
+ aprinc.kdc_key_ver = (unsigned char) temp2;
+ aprinc.key_version = (unsigned char) temp3;
+ aprinc.exp_date = time_explode(exp_date_str);
+ aprinc.mod_date = time_explode(mod_date_str);
+ if (aprinc.instance[0] == '*')
+ aprinc.instance[0] = '\0';
+ if (aprinc.mod_name[0] == '*')
+ aprinc.mod_name[0] = '\0';
+ if (aprinc.mod_instance[0] == '*')
+ aprinc.mod_instance[0] = '\0';
+ if (kerb_db_put_principal(&aprinc, 1) != 1) {
+ fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",
+ aprinc.name, aprinc.instance,
+ sys_errlist[errno]);
+ exit(1);
+ };
+ }
+ if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
+ perror("database rename failed");
+ (void) fclose(input_file);
+ free(temp_db_file);
+}
+
+print_time(file, timeval)
+ FILE *file;
+ unsigned long timeval;
+{
+ struct tm *tm;
+ struct tm *gmtime();
+ tm = gmtime((long *)&timeval);
+ fprintf(file, " %04d%02d%02d%02d%02d",
+ tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min);
+}
+
+/*ARGSUSED*/
+update_ok_file (file_name)
+ char *file_name;
+{
+ /* handle slave locking/failure stuff */
+ char *file_ok;
+ int fd;
+ static char ok[]=".dump_ok";
+
+ if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
+ == NULL) {
+ fprintf(stderr, "kdb_util: out of memory.\n");
+ (void) fflush (stderr);
+ perror ("malloc");
+ exit (1);
+ }
+ strcpy(file_ok, file_name);
+ strcat(file_ok, ok);
+ if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {
+ fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);
+ perror("");
+ (void) fflush (stderr);
+ exit (1);
+ }
+ free(file_ok);
+ close(fd);
+}
+
+void
+convert_key_new_master (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ /* move current key to des_cblock for encryption, special case master key
+ since that's changing */
+ if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
+ (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
+ bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));
+ (p->key_version)++;
+ } else {
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT);
+ }
+
+ kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+
+ (p->kdc_key_ver)++;
+}
+
+convert_new_master_key (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+
+ printf ("\n\nEnter the CURRENT master key.");
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't get master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets ();
+ exit (-1);
+ }
+
+ printf ("\n\nNow enter the NEW master key. Do not forget it!!");
+ if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't get new master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ dump_db (db_file, out, convert_key_new_master);
+}
+
+void
+convert_key_old_db (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);
+
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(des_cblock),master_key_schedule,
+ (des_cblock *)master_key_schedule,DECRYPT);
+#endif
+
+ /* make new key, new style */
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+}
+
+convert_old_format_db (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+ des_cblock key_from_db;
+ Principal principal_data[1];
+ int n, more;
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) {
+ fprintf (stderr, "%s: Couldn't get master key.\n");
+ clear_secrets();
+ exit (-1);
+ }
+
+ /* can't call kdb_verify_master_key because this is an old style db */
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ fprintf(stderr, "verify_master_key: ",
+ "Kerberos error on master key lookup, %d found.\n",
+ n);
+ exit (-1);
+ }
+
+ /* set up the master key */
+ fprintf(stderr, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt (old style) the key in the db, had better
+ * be the same!
+ */
+ bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);
+ bcopy((char *)&principal_data[0].key_high,
+ (char *)(((long *) key_from_db) + 1), 4);
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt(key_from_db,key_from_db,(long)sizeof(key_from_db),
+ master_key_schedule,(des_cblock *)master_key_schedule,DECRYPT);
+#endif
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ bzero((char *)key_from_db, sizeof(key_from_db));
+
+ if (n) {
+ fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, ");
+ fprintf(stderr, "does not match database.\n");
+ exit (-1);
+ }
+
+ fprintf(stderr, "Master key verified.\n");
+ (void) fflush(stderr);
+
+ dump_db (db_file, out, convert_key_old_db);
+}
+
+long
+time_explode(cp)
+register char *cp;
+{
+ char wbuf[5];
+ struct tm tp;
+ long maketime();
+ int local;
+
+ zaptime(&tp); /* clear out the struct */
+
+ if (strlen(cp) > 10) { /* new format */
+ (void) strncpy(wbuf, cp, 4);
+ wbuf[4] = 0;
+ tp.tm_year = atoi(wbuf);
+ cp += 4; /* step over the year */
+ local = 0; /* GMT */
+ } else { /* old format: local time,
+ year is 2 digits, assuming 19xx */
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_year = 1900 + atoi(wbuf);
+ local = 1; /* local */
+ }
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_mon = atoi(wbuf)-1;
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_mday = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_hour = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_min = atoi(wbuf);
+
+
+ return(maketime(&tp, local));
+}
diff --git a/eBones/usr.sbin/kerberos/Makefile b/eBones/usr.sbin/kerberos/Makefile
new file mode 100644
index 0000000..7f36cf7
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:24:22 g89r4222 Exp $
+
+PROG= kerberos
+SRCS= kerberos.c cr_err_reply.c
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kerberos/cr_err_reply.c b/eBones/usr.sbin/kerberos/cr_err_reply.c
new file mode 100644
index 0000000..585fd03
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/cr_err_reply.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $
+ * $Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: cr_err_reply.c,v 1.1 1994/07/19 19:24:24 g89r4222 Exp $";
+#endif /* lint */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+extern int req_act_vno; /* this is defined in the kerberos
+ * server code */
+
+/*
+ * This routine is used by the Kerberos authentication server to
+ * create an error reply packet to send back to its client.
+ *
+ * It takes a pointer to the packet to be built, the name, instance,
+ * and realm of the principal, the client's timestamp, an error code
+ * and an error string as arguments. Its return value is undefined.
+ *
+ * The packet is built in the following format:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char req_ack_vno protocol version number
+ *
+ * unsigned char AUTH_MSG_ERR_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned long e error code
+ *
+ * string e_string error text
+ */
+
+void
+cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
+ KTEXT pkt;
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ u_long time_ws; /* Workstation time */
+ u_long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *v = (u_char *) pkt->dat; /* Prot vers number */
+ u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) req_act_vno; /* KRB_PROT_VERSION; */
+ *t = (unsigned char) AUTH_MSG_ERR_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2),pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *)(pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *)(pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* ws timestamp */
+ bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err code */
+ bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err text */
+ (void) strcpy((char *)(pkt->dat+pkt->length),e_string);
+ pkt->length += 1 + strlen(e_string);
+
+ /* And return */
+ return;
+}
diff --git a/eBones/usr.sbin/kerberos/kerberos.c b/eBones/usr.sbin/kerberos/kerberos.c
new file mode 100644
index 0000000..b980577
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/kerberos.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $
+ * $Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kerberos.c,v 1.3 1994/09/09 21:43:51 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <ctype.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+extern int errno;
+
+struct sockaddr_in s_in = {AF_INET};
+int f;
+
+/* XXX several files in libkdb know about this */
+char *progname;
+
+static Key_schedule master_key_schedule;
+static C_Block master_key;
+
+static struct timeval kerb_time;
+static Principal a_name_data; /* for requesting user */
+static Principal s_name_data; /* for services requested */
+static C_Block session_key;
+static C_Block user_key;
+static C_Block service_key;
+static u_char master_key_version;
+static char k_instance[INST_SZ];
+static char log_text[128];
+static char *lt;
+static int more;
+
+static int mflag; /* Are we invoked manually? */
+static int lflag; /* Have we set an alterate log file? */
+static char *log_file; /* name of alt. log file */
+static int nflag; /* don't check max age */
+static int rflag; /* alternate realm specified */
+
+/* fields within the received request packet */
+static u_char req_msg_type;
+static u_char req_version;
+static char *req_name_ptr;
+static char *req_inst_ptr;
+static char *req_realm_ptr;
+static u_char req_no_req;
+static u_long req_time_ws;
+
+int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */
+
+static char local_realm[REALM_SZ];
+
+/* statistics */
+static long q_bytes; /* current bytes remaining in queue */
+static long q_n; /* how many consecutive non-zero
+ * q_bytes */
+static long max_q_bytes;
+static long max_q_n;
+static long n_auth_req;
+static long n_appl_req;
+static long n_packets;
+static long n_user;
+static long n_server;
+
+static long max_age = -1;
+static long pause_int = -1;
+
+static void check_db_age();
+static void hang();
+
+/*
+ * Print usage message and exit.
+ */
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname,
+ " [-a max_age] [-l log_file] [-r realm]"
+ ," [database_pathname]"
+ );
+ exit(1);
+}
+
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ register int n;
+ int on = 1;
+ int child;
+ struct servent *sp;
+ int fromlen;
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ Principal *p;
+ int more, kerror;
+ C_Block key;
+ int c;
+ extern char *optarg;
+ extern int optind;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) {
+ switch(c) {
+ case 's':
+ /*
+ * Set parameters to slave server defaults.
+ */
+ if (max_age == -1 && !nflag)
+ max_age = ONE_DAY; /* 24 hours */
+ if (pause_int == -1)
+ pause_int = FIVE_MINUTES; /* 5 minutes */
+ if (lflag == 0) {
+ log_file = KRBSLAVELOG;
+ lflag++;
+ }
+ break;
+ case 'n':
+ max_age = -1; /* don't check max age. */
+ nflag++;
+ break;
+ case 'm':
+ mflag++; /* running manually; prompt for master key */
+ break;
+ case 'p':
+ /* Set pause interval. */
+ if (!isdigit(optarg[0]))
+ usage();
+ pause_int = atoi(optarg);
+ if ((pause_int < 5) || (pause_int > ONE_HOUR)) {
+ fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n");
+ usage();
+ }
+ break;
+ case 'a':
+ /* Set max age. */
+ if (!isdigit(optarg[0]))
+ usage();
+ max_age = atoi(optarg);
+ if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) {
+ fprintf(stderr, "max_age must be between one hour and three days, in seconds\n");
+ usage();
+ }
+ break;
+ case 'l':
+ /* Set alternate log file */
+ lflag++;
+ log_file = optarg;
+ break;
+ case 'r':
+ /* Set realm name */
+ rflag++;
+ strcpy(local_realm, optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind == (argc-1)) {
+ if (kerb_db_set_name(argv[optind]) != 0) {
+ fprintf(stderr, "Could not set alternate database name\n");
+ exit(1);
+ }
+ optind++;
+ }
+
+ if (optind != argc)
+ usage();
+
+ printf("Kerberos server starting\n");
+
+ if ((!nflag) && (max_age != -1))
+ printf("\tMaximum database age: %d seconds\n", max_age);
+ if (pause_int != -1)
+ printf("\tSleep for %d seconds on error\n", pause_int);
+ else
+ printf("\tSleep forever on error\n");
+ if (mflag)
+ printf("\tMaster key will be entered manually\n");
+
+ printf("\tLog file is %s\n", lflag ? log_file : KRBLOG);
+
+ if (lflag)
+ kset_logfile(log_file);
+
+ /* find our hostname, and use it as the instance */
+ if (gethostname(k_instance, INST_SZ)) {
+ fprintf(stderr, "%s: gethostname error\n", progname);
+ exit(1);
+ }
+
+ if ((sp = getservbyname("kerberos", "udp")) == 0) {
+ fprintf(stderr, "%s: udp/kerberos unknown service\n", progname);
+ exit(1);
+ }
+ s_in.sin_port = sp->s_port;
+
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "%s: Can't open socket\n", progname);
+ exit(1);
+ }
+ if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+ fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname);
+
+ if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) {
+ fprintf(stderr, "%s: Can't bind socket\n", progname);
+ exit(1);
+ }
+ /* do all the database and cache inits */
+ if (n = kerb_init()) {
+ if (mflag) {
+ printf("Kerberos db and cache init ");
+ printf("failed = %d ...exiting\n", n);
+ exit(-1);
+ } else {
+ klog(L_KRB_PERR,
+ "Kerberos db and cache init failed = %d ...exiting", n);
+ hang();
+ }
+ }
+
+ /* Make sure database isn't stale */
+ check_db_age();
+
+ /* setup master key */
+ if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) {
+ klog (L_KRB_PERR, "kerberos: couldn't get master key.\n");
+ exit (-1);
+ }
+ kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout);
+ if (kerror < 0) {
+ klog (L_KRB_PERR, "Can't verify master key.");
+ bzero (master_key, sizeof (master_key));
+ bzero (master_key_schedule, sizeof (master_key_schedule));
+ exit (-1);
+ }
+
+ master_key_version = (u_char) kerror;
+
+ fprintf(stdout, "\nCurrent Kerberos master key version is %d\n",
+ master_key_version);
+
+ if (!rflag) {
+ /* Look up our local realm */
+ krb_get_lrealm(local_realm, 1);
+ }
+ fprintf(stdout, "Local realm: %s\n", local_realm);
+ fflush(stdout);
+
+ if (set_tgtkey(local_realm)) {
+ /* Ticket granting service unknown */
+ klog(L_KRB_PERR, "Ticket granting ticket service unknown");
+ fprintf(stderr, "Ticket granting ticket service unknown\n");
+ exit(1);
+ }
+ if (mflag) {
+ if ((child = fork()) != 0) {
+ printf("Kerberos started, PID=%d\n", child);
+ exit(0);
+ }
+ setup_disc();
+ }
+ /* receive loop */
+ for (;;) {
+ fromlen = S_AD_SZ;
+ n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from,
+ &fromlen);
+ if (n > 0) {
+ pkt->length = n;
+ pkt->mbz = 0; /* force zeros to catch runaway strings */
+ /* see what is left in the input queue */
+ ioctl(f, FIONREAD, &q_bytes);
+ gettimeofday(&kerb_time, NULL);
+ q_n++;
+ max_q_n = max(max_q_n, q_n);
+ n_packets++;
+ klog(L_NET_INFO,
+ "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d",
+ q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0);
+ max_q_bytes = max(max_q_bytes, q_bytes);
+ if (!q_bytes)
+ q_n = 0; /* reset consecutive packets */
+ kerberos(&from, pkt);
+ } else
+ klog(L_NET_ERR,
+ "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0);
+ }
+}
+
+
+kerberos(client, pkt)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+{
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st;
+ static KTEXT_ST ciph_st;
+ KTEXT ciph = &ciph_st;
+ static KTEXT_ST tk_st;
+ KTEXT tk = &tk_st;
+ static KTEXT_ST auth_st;
+ KTEXT auth = &auth_st;
+ AUTH_DAT ad_st;
+ AUTH_DAT *ad = &ad_st;
+
+
+ static struct in_addr client_host;
+ static int msg_byte_order;
+ static int swap_bytes;
+ static u_char k_flags;
+ char *p_name, *instance;
+ u_long lifetime;
+ int i;
+ C_Block key;
+ Key_schedule key_s;
+ char *ptr;
+
+
+
+ ciph->length = 0;
+
+ client_host = client->sin_addr;
+
+ /* eval macros and correct the byte order and alignment as needed */
+ req_version = pkt_version(pkt); /* 1 byte, version */
+ req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */
+
+ req_act_vno = req_version;
+
+ /* check packet version */
+ if (req_version != KRB_PROT_VERSION) {
+ lt = klog(L_KRB_PERR,
+ "KRB prot version mismatch: KRB =%d request = %d",
+ KRB_PROT_VERSION, req_version, 0);
+ /* send an error reply */
+ kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+ return;
+ }
+ msg_byte_order = req_msg_type & 1;
+
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+ klog(L_KRB_PINFO,
+ "Prot version: %d, Byte order: %d, Message type: %d",
+ req_version, msg_byte_order, req_msg_type);
+
+ switch (req_msg_type & ~1) {
+
+ case AUTH_MSG_KDC_REQUEST:
+ {
+ u_long time_ws; /* Workstation time */
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ int kerno; /* Kerberos error number */
+ n_auth_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+
+ /* set up and correct for byte order and alignment */
+ req_name_ptr = (char *) pkt_a_name(pkt);
+ req_inst_ptr = (char *) pkt_a_inst(pkt);
+ req_realm_ptr = (char *) pkt_a_realm(pkt);
+ bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws));
+ /* time has to be diddled */
+ if (swap_bytes) {
+ swap_u_long(req_time_ws);
+ }
+ ptr = (char *) pkt_time_ws(pkt) + 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ rpkt = &rpkt_st;
+ klog(L_INI_REQ,
+ "Initial ticket request Host: %s User: \"%s\" \"%s\"",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+
+ if (i = check_princ(req_name_ptr, req_inst_ptr, 0,
+ &a_name_data)) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ tk->length = 0; /* init */
+ if (strcmp(service, "krbtgt"))
+ klog(L_NTGT_INTK,
+ "INITIAL request from %s.%s for %s.%s",
+ req_name_ptr, req_inst_ptr, service, instance, 0);
+ /* this does all the checking */
+ if (i = check_princ(service, instance, lifetime,
+ &s_name_data)) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life, ((u_long) s_name_data.max_life));
+ lifetime = min(lifetime, ((u_long) a_name_data.max_life));
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+ krb_create_ticket(tk, k_flags, a_name_data.name,
+ a_name_data.instance, local_realm,
+ client_host.s_addr, session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance, key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ /*
+ * get the user's key, unseal it from the server's key, and
+ * use it to seal the cipher
+ */
+
+ /* a_name_data.key_low a_name_data.key_high */
+ bcopy(&a_name_data.key_low, key, 4);
+ bcopy(&a_name_data.key_high, ((long *) key) + 1, 4);
+
+ /* unseal the a_name key from the master key */
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+
+ create_ciph(ciph, session_key, s_name_data.name,
+ s_name_data.instance, local_realm, lifetime,
+ s_name_data.key_version, tk, kerb_time.tv_sec, key);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(key, sizeof(key));
+
+
+
+ /* always send a reply packet */
+ rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
+ req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
+ a_name_data.key_version, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&a_name_data, sizeof(a_name_data));
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+ case AUTH_MSG_APPL_REQUEST:
+ {
+ u_long time_ws; /* Workstation time */
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ int kerno; /* Kerberos error number */
+ char tktrlm[REALM_SZ];
+
+ n_appl_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+ auth->length = 4 + strlen(pkt->dat + 3);
+ auth->length += (int) *(pkt->dat + auth->length) +
+ (int) *(pkt->dat + auth->length + 1) + 2;
+
+ bcopy(pkt->dat, auth->dat, auth->length);
+
+ strncpy(tktrlm, auth->dat + 3, REALM_SZ);
+ if (set_tgtkey(tktrlm)) {
+ lt = klog(L_ERR_UNK,
+ "FAILED realm %s unknown. Host: %s ",
+ tktrlm, inet_ntoa(client_host));
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr,
+ ad, 0);
+
+ if (kerno) {
+ klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
+ inet_ntoa(client_host), krb_err_txt[kerno]);
+ kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+ return;
+ }
+ ptr = (char *) pkt->dat + auth->length;
+
+ bcopy(ptr, &time_ws, 4);
+ ptr += 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
+ ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host),
+ service, instance, 0);
+
+ if (strcmp(ad->prealm, tktrlm)) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't hop realms");
+ return;
+ }
+ if (!strcmp(service, "changepw")) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't authorize password changed based on TGT");
+ return;
+ }
+ kerno = check_princ(service, instance, req_life,
+ &s_name_data);
+ if (kerno) {
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life,
+ (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300)));
+ lifetime = min(lifetime, ((u_long) s_name_data.max_life));
+
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+
+ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
+ ad->prealm, client_host,
+ session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance,
+ key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ create_ciph(ciph, session_key, service, instance,
+ local_realm,
+ lifetime, s_name_data.key_version, tk,
+ kerb_time.tv_sec, ad->session);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(ad->session, sizeof(ad->session));
+
+ rpkt = create_auth_reply(ad->pname, ad->pinst,
+ ad->prealm, time_ws,
+ 0, 0, 0, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+
+
+#ifdef notdef_DIE
+ case AUTH_MSG_DIE:
+ {
+ lt = klog(L_DEATH_REQ,
+ "Host: %s User: \"%s\" \"%s\" Kerberos killed",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+ exit(0);
+ }
+#endif notdef_DIE
+
+ default:
+ {
+ lt = klog(L_KRB_PERR,
+ "Unknown message type: %d from %s port %u",
+ req_msg_type, inet_ntoa(client_host),
+ ntohs(client->sin_port));
+ break;
+ }
+ }
+}
+
+
+/*
+ * setup_disc
+ *
+ * disconnect all descriptors, remove ourself from the process
+ * group that spawned us.
+ */
+
+setup_disc()
+{
+
+ int s;
+
+ for (s = 0; s < 3; s++) {
+ (void) close(s);
+ }
+
+ (void) open("/dev/null", 0);
+ (void) dup2(0, 1);
+ (void) dup2(0, 2);
+
+ s = open("/dev/tty", 2);
+
+ if (s >= 0) {
+ ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
+ (void) close(s);
+ }
+ (void) chdir("/tmp");
+ return;
+}
+
+
+/*
+ * kerb_er_reply creates an error reply packet and sends it to the
+ * client.
+ */
+
+kerb_err_reply(client, pkt, err, string)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+ long err;
+ char *string;
+
+{
+ static KTEXT_ST e_pkt_st;
+ KTEXT e_pkt = &e_pkt_st;
+ static char e_msg[128];
+
+ strcpy(e_msg, "\nKerberos error -- ");
+ strcat(e_msg, string);
+ cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
+ req_time_ws, err, e_msg);
+ sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+
+}
+
+/*
+ * Make sure that database isn't stale.
+ *
+ * Exit if it is; we don't want to tell lies.
+ */
+
+static void check_db_age()
+{
+ long age;
+
+ if (max_age != -1) {
+ /* Requires existance of kerb_get_db_age() */
+ gettimeofday(&kerb_time, 0);
+ age = kerb_get_db_age();
+ if (age == 0) {
+ klog(L_KRB_PERR, "Database currently being updated!");
+ hang();
+ }
+ if ((age + max_age) < kerb_time.tv_sec) {
+ klog(L_KRB_PERR, "Database out of date!");
+ hang();
+ /* NOTREACHED */
+ }
+ }
+}
+
+check_princ(p_name, instance, lifetime, p)
+ char *p_name;
+ char *instance;
+ unsigned lifetime;
+
+ Principal *p;
+{
+ static int n;
+ static int more;
+ long trans;
+
+ n = kerb_get_principal(p_name, instance, p, 1, &more);
+ klog(L_ALL_REQ,
+ "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
+ p_name, instance, lifetime, n, 0);
+
+ if (n < 0) {
+ lt = klog(L_KRB_PERR, "Database unavailable!");
+ hang();
+ }
+
+ /*
+ * if more than one p_name, pick one, randomly create a session key,
+ * compute maximum lifetime, lookup authorizations if applicable,
+ * and stuff into cipher.
+ */
+ if (n == 0) {
+ /* service unknown, log error, skip to next request */
+ lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_PRINCIPAL_UNKNOWN;
+ }
+ if (more) {
+ /* not unique, log error */
+ lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
+ p_name, instance, 0);
+ return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
+ }
+ /* If the user's key is null, we want to return an error */
+ if ((p->key_low == 0) && (p->key_high == 0)) {
+ /* User has a null key */
+ lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_NULL_KEY;
+ }
+ if (master_key_version != p->kdc_key_ver) {
+ /* log error reply */
+ lt = klog(L_ERR_MKV,
+ "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d",
+ master_key_version, p->name, p->instance, p->kdc_key_ver,
+ 0);
+ return KERB_ERR_NAME_MAST_KEY_VER;
+ }
+ /* make sure the service hasn't expired */
+ if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) {
+ /* service did expire, log it */
+ lt = klog(L_ERR_SEXP,
+ "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance,
+ stime(&(p->exp_date)), 0);
+ return KERB_ERR_NAME_EXP;
+ }
+ /* ok is zero */
+ return 0;
+}
+
+
+/* Set the key for krb_rd_req so we can check tgt */
+set_tgtkey(r)
+ char *r; /* Realm for desired key */
+{
+ int n;
+ static char lastrealm[REALM_SZ];
+ Principal p_st;
+ Principal *p = &p_st;
+ C_Block key;
+
+ if (!strcmp(lastrealm, r))
+ return (KSUCCESS);
+
+ log("Getting key for %s", r);
+
+ n = kerb_get_principal("krbtgt", r, p, 1, &more);
+ if (n == 0)
+ return (KFAILURE);
+
+ /* unseal tgt key from master key */
+ bcopy(&p->key_low, key, 4);
+ bcopy(&p->key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ krb_set_key(key, 0);
+ strcpy(lastrealm, r);
+ return (KSUCCESS);
+}
+
+static void
+hang()
+{
+ if (pause_int == -1) {
+ klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
+ for (;;)
+ pause();
+ } else {
+ char buf[256];
+ sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int);
+ klog(L_KRB_PERR, buf);
+ sleep(pause_int);
+ klog(L_KRB_PERR, "Do svedania....\n");
+ exit(1);
+ }
+}
diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.8 b/eBones/usr.sbin/ksrvutil/ksrvutil.8
new file mode 100644
index 0000000..a7fed82
--- /dev/null
+++ b/eBones/usr.sbin/ksrvutil/ksrvutil.8
@@ -0,0 +1,93 @@
+.\" from: /mit/kerberos/src/man/RCS/ksrvutil.8,v 4.0 89/07/27 18:35:33 jtkohl Exp $
+.\" $Id: ksrvutil.8,v 1.2 1994/07/19 19:27:53 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSRVUTIL 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+ksrvutil \- host kerberos keyfile (srvtab) manipulation utility
+.SH SYNOPSIS
+ksrvutil
+.B operation
+[
+.B \-k
+] [
+.B \-i
+] [
+.B \-f filename
+]
+.SH DESCRIPTION
+.I ksrvutil
+allows a system manager to list or change keys currently in his
+keyfile or to add new keys to the keyfile.
+.PP
+
+Operation must be one of the following:
+.TP 10n
+.I list
+lists the keys in a keyfile showing version number and principal
+name. If the \-k option is given, keys will also be shown.
+.TP 10n
+.I change
+changes all the keys in the keyfile by using the regular admin
+protocol. If the \-i flag is given,
+.I ksrvutil
+will prompt for yes or no before changing each key. If the \-k
+option is used, the old and new keys will be displayed.
+.TP 10n
+.I add
+allows the user to add a key.
+.I add
+prompts for name, instance, realm, and key version number, asks
+for confirmation, and then asks for a password.
+.I ksrvutil
+then converts the password to a key and appends the keyfile with
+the new information. If the \-k option is used, the key is
+displayed.
+
+.PP
+In all cases, the default file used is KEY_FILE as defined in
+krb.h unless this is overridden by the \-f option.
+
+.PP
+A good use for
+.I ksrvutil
+would be for adding keys to a keyfile. A system manager could
+ask a kerberos administrator to create a new service key with
+.IR kadmin (8)
+and could supply an initial password. Then, he could use
+.I ksrvutil
+to add the key to the keyfile and then to change the key so that
+it will be random and unknown to either the system manager or
+the kerberos administrator.
+
+.I ksrvutil
+always makes a backup copy of the keyfile before making any
+changes.
+
+.SH DIAGNOSTICS
+If
+.I ksrvutil
+should exit on an error condition at any time during a change or
+add, a copy of the
+original keyfile can be found in
+.IR filename .old
+where
+.I filename
+is the name of the keyfile, and a copy of the file with all new
+keys changed or added so far can be found in
+.IR filename .work.
+The original keyfile is left unmodified until the program exits
+at which point it is removed and replaced it with the workfile.
+Appending the workfile to the backup copy and replacing the
+keyfile with the result should always give a usable keyfile,
+although the resulting keyfile will have some out of date keys
+in it.
+
+.SH SEE ALSO
+kadmin(8), ksrvtgt(1)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt, MIT Project Athena
diff --git a/eBones/usr.sbin/kstash/Makefile b/eBones/usr.sbin/kstash/Makefile
new file mode 100644
index 0000000..8331c97a
--- /dev/null
+++ b/eBones/usr.sbin/kstash/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.2 (Berkeley) 3/5/91
+# $Id: Makefile,v 1.2 1994/07/19 19:27:04 g89r4222 Exp $
+
+PROG= kstash
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kstash/kstash.8 b/eBones/usr.sbin/kstash/kstash.8
new file mode 100644
index 0000000..d83379a
--- /dev/null
+++ b/eBones/usr.sbin/kstash/kstash.8
@@ -0,0 +1,41 @@
+.\" from: kstash.8,v 4.1 89/01/23 11:11:39 jtkohl Exp $
+.\" $Id: kstash.8,v 1.2 1994/07/19 19:27:55 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KSTASH 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kstash \- stash Kerberos key distribution center database master key
+.SH SYNOPSIS
+kstash
+.SH DESCRIPTION
+.I kstash
+saves the Kerberos key distribution center (KDC) database master key in
+the master key cache file.
+.PP
+The user is prompted to enter the key, to verify the authenticity of the
+key and the authorization to store the key in the file.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.TP
+"kstash: Unable to open master key file"
+The attempt to open the cache file for writing failed (probably due to a
+system or access permission error).
+.TP
+"kstash: Write I/O error on master key file"
+The
+.BR write (2)
+system call returned an error while
+.I kstash
+was attempting to write the key to the file.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/usr.sbin/kstash/kstash.c b/eBones/usr.sbin/kstash/kstash.c
new file mode 100644
index 0000000..696e4e1
--- /dev/null
+++ b/eBones/usr.sbin/kstash/kstash.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $
+ * $Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kstash.c,v 1.2 1994/07/19 19:27:05 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+extern int errno;
+
+/* change this later, but krblib_dbm needs it for now */
+char *progname;
+
+static C_Block master_key;
+static Key_schedule master_key_schedule;
+static Principal s_name_data; /* for services requested */
+static unsigned char master_key_version;
+int debug;
+static int more;
+static int kfile;
+static void clear_secrets();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ long n;
+ if (n = kerb_init()) {
+ fprintf(stderr, "Kerberos db and cache init failed = %d\n", n);
+ exit(1);
+ }
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]);
+ fflush (stderr);
+ clear_secrets();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets();
+ exit (-1);
+ }
+
+ kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600);
+ if (kfile < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n\07\07%s: Unable to open master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ if (write(kfile, (char *) master_key, 8) < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n%s: Write I/O error on master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ (void) close(kfile);
+ clear_secrets();
+}
+
+static void
+clear_secrets()
+{
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(master_key, sizeof(master_key));
+}
diff --git a/eBones/usr.sbin/make_keypair/Makefile b/eBones/usr.sbin/make_keypair/Makefile
new file mode 100644
index 0000000..b00048e
--- /dev/null
+++ b/eBones/usr.sbin/make_keypair/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+
+PROG= make_keypair
+MAN8= make_keypair.8
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../register
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/make_keypair/make_keypair.8 b/eBones/usr.sbin/make_keypair/make_keypair.8
new file mode 100644
index 0000000..d0b7b88
--- /dev/null
+++ b/eBones/usr.sbin/make_keypair/make_keypair.8
@@ -0,0 +1,87 @@
+.\" Copyright (c) 1988, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)make_keypair.8 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt MAKE_KEYPAIR 8
+.Os
+.Sh NAME
+.Nm make_keypair
+.Nd generate Kerberos host key pair
+.Sh SYNOPSIS
+.Nm make_keypair
+.Ar hostname
+.Op Ar hostname ...
+.Sh DESCRIPTION
+The
+.Nm make_keypair
+command
+is used to create pairs of
+.Tn DES
+keys for
+each
+.Ar hostname .
+The keys are used by privileged programs such as
+.Xr register 1
+to make remote updates to the Kerberos database without
+having to have first acquired a Kerberos ticket granting ticket
+.Pq Tn TGT .
+The keys created by
+.Nm make_keypair
+are placed (by hand) in the filesystems of the
+kerberos server in
+.Pa /etc/kerberosIV/register_keys ,
+and in the root directory of the clients.
+For example, the file
+.Pa /.update.key128.32.130.3
+would
+contain a copy of the key of the client with
+IP address 128.32.130.3.
+These keys provide a shared secret which may be used to establish
+a secure channel between the client hosts and the Kerberos server.
+.Sh FILES
+.Bl -tag -width /etc/kerberosIV/register_keysxx -compact
+.It Pa /.update.keyxx.xx.xx.xx
+shared
+.Tn DES
+key with server
+.It Pa /etc/kerberosIV/register_keys
+server's key storage directory
+.El
+.Sh SEE ALSO
+.Xr register 1 ,
+.Xr registerd 8 ,
+.Xr kerberos 1
+.Sh HISTORY
+The
+.Nm make_keypair
+utility first appeared in 4.4BSD.
diff --git a/eBones/usr.sbin/make_keypair/make_keypair.c b/eBones/usr.sbin/make_keypair/make_keypair.c
new file mode 100644
index 0000000..c9883ed
--- /dev/null
+++ b/eBones/usr.sbin/make_keypair/make_keypair.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+extern void random_key(), herror();
+void make_key(), usage();
+
+char * progname;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ char *addr;
+ int i;
+ struct sockaddr_in sin;
+
+ progname = *argv; /* argv[0] */
+
+ if (argc != 2) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if ((hp = gethostbyname(argv[1])) == NULL) {
+ herror(argv[1]);
+ exit(1);
+ }
+
+ for (i = 0; addr = hp->h_addr_list[i]; i++) {
+ addr = hp->h_addr_list[i];
+ bcopy(addr, &sin.sin_addr, hp->h_length);
+
+ printf("Making key for host %s (%s)\n",
+ argv[1], inet_ntoa(sin.sin_addr));
+ make_key(sin.sin_addr);
+ }
+ printf("==========\n");
+ printf("One copy of the each key should be put in %s on the\n",
+ SERVER_KEYDIR);
+ printf("Kerberos server machine (mode 600, owner root).\n");
+ printf("Another copy of each key should be put on the named\n");
+ printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n",
+ CLIENT_KEYFILE);
+ printf("where the X's refer to digits of the host's inet address.\n");
+ (void)fflush(stdout);
+ exit(0);
+}
+
+void
+make_key(addr)
+ struct in_addr addr;
+{
+ struct keyfile_data kfile;
+ char namebuf[255];
+ int fd;
+
+ (void)sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(addr));
+ fd = open(namebuf, O_WRONLY|O_CREAT, 0600);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ random_key(kfile.kf_key);
+ printf("writing to file -> %s ...", namebuf);
+ if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) {
+ fprintf(stderr, "error writing file %s\n", namebuf);
+ }
+ printf("done.\n");
+ (void)close(fd);
+ return;
+}
+
+void
+usage(name)
+ char *name;
+{
+ fprintf(stderr, "usage: %s host\n", name);
+}
diff --git a/usr.bin/compile_et/Makefile b/usr.bin/compile_et/Makefile
new file mode 100644
index 0000000..9b988267
--- /dev/null
+++ b/usr.bin/compile_et/Makefile
@@ -0,0 +1,15 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.2 1994/07/19 19:21:23 g89r4222 Exp $
+
+PROG= compile_et
+CFLAGS+=-I. -I${.CURDIR}
+SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c
+OBJS+= error_table.o
+DPADD= ${LIBL}
+LDADD= -ll
+CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c
+NOMAN= noman
+
+error_table.c: et_lex.lex.c
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/compile_et/compile_et.c b/usr.bin/compile_et/compile_et.c
new file mode 100644
index 0000000..25be70b
--- /dev/null
+++ b/usr.bin/compile_et/compile_et.c
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright 1986, 1987 by MIT Student Information Processing Board
+ * For copyright info, see "Copyright.SIPB".
+ *
+ * $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include <sys/file.h>
+#include <strings.h>
+#include <sys/param.h>
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+extern char *gensym();
+extern char *current_token;
+extern int table_number, current;
+char buffer[BUFSIZ];
+char *table_name = (char *)NULL;
+FILE *hfile, *cfile;
+
+/* C library */
+extern char *malloc();
+extern int errno;
+
+/* lex stuff */
+extern FILE *yyin;
+extern int yylineno;
+
+/* pathnames */
+char c_file[MAXPATHLEN]; /* temporary file */
+char h_file[MAXPATHLEN]; /* output */
+char o_file[MAXPATHLEN]; /* output */
+char et_file[MAXPATHLEN]; /* input */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ register char *p;
+ int n_flag = 0, debug = 0;
+
+ while (argc > 2) {
+ register char *arg, ch;
+ arg = argv[--argc];
+ if (strlen(arg) != 2 || arg[0] != '-')
+ goto usage;
+ ch = arg[1];
+ if (ch == 'n')
+ n_flag++;
+ else if (ch == 'd')
+ debug++;
+ else
+ goto usage;
+ }
+
+ if (argc != 2) {
+ usage:
+ fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]);
+ exit(1);
+ }
+
+ strcpy(et_file, argv[1]);
+ p = rindex(et_file, '/');
+ if (p == (char *)NULL)
+ p = et_file;
+ else
+ p++;
+ p = rindex(p, '.');
+ if (!strcmp(p, ".et"))
+ *++p = '\0';
+ else {
+ if (!p)
+ p = et_file;
+ while (*p)
+ p++;
+ *p++ = '.';
+ *p = '\0';
+ }
+ /* p points at null where suffix should be */
+ strcpy(p, "et.c");
+ strcpy(c_file, et_file);
+ p[0] = 'h';
+ p[1] = '\0';
+ strcpy(h_file, et_file);
+ p[0] = 'o';
+ strcpy(o_file, et_file);
+ p[0] = 'e';
+ p[1] = 't';
+ p[2] = '\0';
+
+ yyin = fopen(et_file, "r");
+ if (!yyin) {
+ perror(et_file);
+ exit(1);
+ }
+
+ hfile = fopen(h_file, "w");
+ if (hfile == (FILE *)NULL) {
+ perror(h_file);
+ exit(1);
+ }
+
+ cfile = fopen(c_file, "w");
+ if (cfile == (FILE *)NULL) {
+ perror("Can't open temp file");
+ exit(1);
+ }
+
+ /* parse it */
+ fputs("#define NULL 0\n", cfile);
+ fputs("static char *_et[] = {\n", cfile);
+
+ yyparse();
+ fclose(yyin); /* bye bye input file */
+
+ fputs("\t(char *)0\n};\n", cfile);
+ fputs("extern int init_error_table();\n\n", cfile);
+ fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number);
+ fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name);
+ fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n",
+ table_number, current);
+ fclose(cfile);
+
+ fputs("extern int init_", hfile);
+ fputs(table_name, hfile);
+ fputs("_err_tbl();\nextern int ", hfile);
+ fputs(table_name, hfile);
+ fputs("_err_base;\n", hfile);
+ fclose(hfile); /* bye bye hfile */
+
+ if (n_flag)
+ exit(0);
+
+ if (!fork()) {
+ p = rindex(c_file, '/');
+ if (p) {
+ *p++ = '\0';
+ chdir(c_file);
+ }
+ else
+ p = c_file;
+ execlp("cc", "cc", "-c", "-R", "-O", p, 0);
+ perror("cc");
+ exit(1);
+ }
+ else wait(0);
+
+ if (!debug)
+ (void) unlink(c_file);
+ /* make it .o file name */
+ c_file[strlen(c_file)-1] = 'o';
+ if (!fork()) {
+ execlp("cp", "cp", c_file, o_file, 0);
+ perror("cp");
+ exit(1);
+ }
+ else wait(0);
+ if (!debug)
+ (void) unlink(c_file);
+
+ exit(0);
+}
+
+yyerror(s)
+ char *s;
+{
+ fputs(s, stderr);
+ fprintf(stderr, "\nLine number %d; last token was '%s'\n",
+ yylineno, current_token);
+}
diff --git a/usr.bin/compile_et/error_message.c b/usr.bin/compile_et/error_message.c
new file mode 100644
index 0000000..92cec57
--- /dev/null
+++ b/usr.bin/compile_et/error_message.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1987 by the Student Information Processing Board
+ * of the Massachusetts Institute of Technology
+ * For copyright info, see "Copyright.SIPB".
+ *
+ * from: error_message.c,v 1.1 86/11/10 21:34:34 spook Exp $
+ * $Id: error_message.c,v 1.3 1994/09/09 21:43:22 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include "error_table.h"
+extern int sys_nerr;
+
+static char buffer[25];
+
+char *
+error_message(code)
+ int code;
+{
+ register int offset;
+ register error_table **et;
+ register int table_num;
+ register int div;
+ register char *cp;
+
+ offset = code & ((1<<ERRCODE_RANGE)-1);
+ table_num = code - offset;
+ if ((_et_list == (error_table **)NULL) && table_num)
+ goto oops;
+ if (!table_num) {
+ if (offset < sys_nerr)
+ return(sys_errlist[offset]);
+ else
+ goto oops;
+ }
+ for (et = _et_list; *et != (error_table *)NULL; et++) {
+ if ((*et)->base == table_num) {
+ /* This is the right table */
+ if ((*et)->n_msgs <= offset)
+ goto oops;
+ return((*et)->msgs[offset]);
+ }
+ }
+ oops:
+ cp = buffer;
+ {
+ register char *cp1;
+ for (cp1 = "Unknown code "; *cp1; cp1++, cp++)
+ *cp = *cp1;
+ if (table_num) {
+ for (cp1 = error_table_name(table_num); *cp1; cp1++, cp++)
+ *cp = *cp1;
+ *cp++ = ' ';
+ *cp = '\0';
+ }
+ }
+ div = 1000000000;
+ if (offset == 0) {
+ *cp++ = '0';
+ *cp = '\0';
+ return(buffer);
+ }
+ while (div > offset)
+ div /= 10;
+ do {
+ register int n = offset / div;
+ *cp++ = '0' + n;
+ offset -= n * div;
+ div /= 10;
+ } while (offset && div);
+ while (div) {
+ *cp++ = '0';
+ div /= 10;
+ }
+ *cp = '\0';
+ return(buffer);
+}
diff --git a/usr.bin/compile_et/error_table.h b/usr.bin/compile_et/error_table.h
new file mode 100644
index 0000000..e32ec30
--- /dev/null
+++ b/usr.bin/compile_et/error_table.h
@@ -0,0 +1,17 @@
+#ifndef _ET
+extern int errno;
+typedef struct {
+ char **msgs;
+ int base;
+ int n_msgs;
+} error_table;
+extern error_table **_et_list;
+
+#define ERROR_CODE "int" /* type used for error codes */
+
+#define ERRCODE_RANGE 8 /* # of bits to shift table number */
+#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
+
+extern char *error_table_name();
+#define _ET
+#endif
diff --git a/usr.bin/compile_et/error_table.y b/usr.bin/compile_et/error_table.y
new file mode 100644
index 0000000..3913a84
--- /dev/null
+++ b/usr.bin/compile_et/error_table.y
@@ -0,0 +1,205 @@
+%{
+#include <stdio.h>
+char *str_concat(), *ds(), *quote(), *malloc(), *realloc();
+char *current_token = (char *)NULL;
+extern char *table_name;
+%}
+%union {
+ char *dynstr;
+}
+
+%token ERROR_TABLE ERROR_CODE_ENTRY END
+%token <dynstr> STRING QUOTED_STRING
+%type <dynstr> ec_name description table_id
+%{
+%}
+%start error_table
+%%
+
+error_table : ERROR_TABLE table_id error_codes END
+ { table_name = ds($2);
+ current_token = table_name;
+ put_ecs(); }
+ ;
+
+table_id : STRING
+ { current_token = $1;
+ set_table_num($1);
+ $$ = $1; }
+ ;
+
+error_codes : error_codes ec_entry
+ | ec_entry
+ ;
+
+ec_entry : ERROR_CODE_ENTRY ec_name ',' description
+ { add_ec($2, $4);
+ free($2);
+ free($4); }
+ | ERROR_CODE_ENTRY ec_name '=' STRING ',' description
+ { add_ec_val($2, $4, $6);
+ free($2);
+ free($4);
+ free($6);
+ }
+ ;
+
+ec_name : STRING
+ { $$ = ds($1);
+ current_token = $$; }
+ ;
+
+description : QUOTED_STRING
+ { $$ = ds($1);
+ current_token = $$; }
+ ;
+
+%%
+/*
+ * Copyright 1986, 1987 by the MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include "error_table.h"
+
+extern FILE *hfile, *cfile;
+
+static long gensym_n = 0;
+char *
+gensym(x)
+ char *x;
+{
+ char *symbol;
+ if (!gensym_n) {
+ struct timeval tv;
+ struct timezone tzp;
+ gettimeofday(&tv, &tzp);
+ gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
+ }
+ symbol = malloc(32 * sizeof(char));
+ gensym_n++;
+ sprintf(symbol, "et%ld", gensym_n);
+ return(symbol);
+}
+
+char *
+ds(string)
+ char *string;
+{
+ char *rv;
+ rv = malloc(strlen(string)+1);
+ strcpy(rv, string);
+ return(rv);
+}
+
+char *
+quote(string)
+ char *string;
+{
+ char *rv;
+ rv = malloc(strlen(string)+3);
+ strcpy(rv, "\"");
+ strcat(rv, string);
+ strcat(rv, "\"");
+ return(rv);
+}
+
+int table_number;
+int current = 0;
+char **error_codes = (char **)NULL;
+
+add_ec(name, description)
+ char *name, *description;
+{
+ fprintf(cfile, "\t\"%s\",\n", description);
+ if (error_codes == (char **)NULL) {
+ error_codes = (char **)malloc(sizeof(char *));
+ *error_codes = (char *)NULL;
+ }
+ error_codes = (char **)realloc((char *)error_codes,
+ (current + 2)*sizeof(char *));
+ error_codes[current++] = ds(name);
+ error_codes[current] = (char *)NULL;
+}
+
+add_ec_val(name, val, description)
+ char *name, *val, *description;
+{
+ int ncurrent = atoi(val);
+ if (ncurrent < current) {
+ printf("Error code %s (%d) out of order", name,
+ current);
+ return;
+ }
+
+ while (ncurrent > current)
+ fputs("\t(char *)NULL,\n", cfile), current++;
+
+ fprintf(cfile, "\t\"%s\",\n", description);
+ if (error_codes == (char **)NULL) {
+ error_codes = (char **)malloc(sizeof(char *));
+ *error_codes = (char *)NULL;
+ }
+ error_codes = (char **)realloc((char *)error_codes,
+ (current + 2)*sizeof(char *));
+ error_codes[current++] = ds(name);
+ error_codes[current] = (char *)NULL;
+}
+
+put_ecs()
+{
+ int i;
+ for (i = 0; i < current; i++) {
+ if (error_codes[i] != (char *)NULL)
+ fprintf(hfile, "#define %-40s ((%s)%d)\n",
+ error_codes[i], ERROR_CODE, table_number + i);
+ }
+}
+
+/*
+ * char_to_num -- maps letters and numbers into a small numbering space
+ * uppercase -> 1-26
+ * lowercase -> 27-52
+ * digits -> 53-62
+ * underscore-> 63
+ */
+int
+char_to_num(c)
+ char c;
+{
+ if (isupper(c))
+ return(c-'A'+1);
+ else if (islower(c))
+ return(c-'a'+27);
+ else if (isdigit(c))
+ return(c-'0'+53);
+ else {
+ fprintf(stderr, "Illegal character in name: %c\n", c);
+ exit(1);
+ /*NOTREACHED*/
+ }
+}
+
+set_table_num(string)
+ char *string;
+{
+ if (strlen(string) > 4) {
+ fprintf(stderr, "Table name %s too long, truncated ",
+ string);
+ string[4] = '\0';
+ fprintf(stderr, "to %s\n", string);
+ }
+ while (*string != '\0') {
+ table_number = (table_number << BITS_PER_CHAR)
+ + char_to_num(*string);
+ string++;
+ }
+ table_number = table_number << ERRCODE_RANGE;
+}
+
+#include "et_lex.lex.c"
diff --git a/usr.bin/compile_et/et_lex.lex.l b/usr.bin/compile_et/et_lex.lex.l
new file mode 100644
index 0000000..c041819
--- /dev/null
+++ b/usr.bin/compile_et/et_lex.lex.l
@@ -0,0 +1,29 @@
+%{
+extern int yylineno;
+int yylineno = 1;
+%}
+
+PC [^\"\n]
+AN [A-Z_a-z0-9]
+%%
+
+error_table return ERROR_TABLE;
+et return ERROR_TABLE;
+error_code return ERROR_CODE_ENTRY;
+ec return ERROR_CODE_ENTRY;
+end return END;
+
+[\t ]+ ;
+\n ++yylineno;
+
+\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1);
+ if (p=rindex(yylval.dynstr, '"')) *p='\0';
+ return QUOTED_STRING;
+ }
+
+{AN}* { yylval.dynstr = ds(yytext); return STRING; }
+
+#.*\n ++yylineno;
+
+. { return (*yytext); }
+%%
diff --git a/usr.bin/compile_et/et_name.c b/usr.bin/compile_et/et_name.c
new file mode 100644
index 0000000..98ccb08
--- /dev/null
+++ b/usr.bin/compile_et/et_name.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ *
+ * $Id: et_name.c,v 1.2 1994/07/19 19:21:27 g89r4222 Exp $
+ */
+
+#include "error_table.h"
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+char *malloc();
+
+char *
+error_table_name(num)
+ int num;
+{
+ register int ch;
+ register int i;
+ register char *buf, *p;
+
+ /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+ buf = malloc(5);
+ p = buf;
+ num >>= ERRCODE_RANGE;
+ /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+ num &= 077777777;
+ /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+ for (i = 0; i < 5; i++) {
+ ch = (num >> 24-6*i) & 077;
+ if (ch == 0)
+ continue;
+ else if (ch < 27)
+ *p++ = ch - 1 + 'A';
+ else if (ch < 53)
+ *p++ = ch - 27 + 'a';
+ else if (ch < 63)
+ *p++ = ch - 53 + '0';
+ else /* ch == 63 */
+ *p++ = '_';
+ }
+ return(buf);
+}
+
diff --git a/usr.bin/compile_et/init_et.c b/usr.bin/compile_et/init_et.c
new file mode 100644
index 0000000..c23facb
--- /dev/null
+++ b/usr.bin/compile_et/init_et.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1986 by MIT Information Systems and
+ * MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB.
+ *
+ * form: init_et.c,v 1.1 86/11/10 21:42:26 spook Exp $
+ * $Id: init_et.c,v 1.2 1994/07/19 19:21:28 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include "error_table.h"
+
+static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
+
+extern char *malloc(), *realloc();
+
+/* useful */
+typedef error_table *etp;
+typedef etp *etpp;
+
+etpp _et_list = (etpp)NULL;
+static int n_allocated = 0, n_used = 0;
+
+int
+init_error_table(msgs, base, count)
+ char **msgs;
+ register int base;
+ int count;
+{
+ register int i;
+ register etp new_et;
+ register etpp list;
+
+ if (!base || !count || !msgs)
+ return;
+
+ new_et = (etp)malloc(sizeof(error_table));
+ new_et->msgs = msgs;
+ new_et->base = base;
+ new_et->n_msgs= count;
+
+ list = _et_list;
+ if (list == (etpp)NULL) {
+ _et_list = (etpp) malloc(10*sizeof(etp));
+ list = _et_list;
+ if (list == (etpp)NULL)
+ return; /* oops */
+ list[0] = new_et;
+ list[1] = (etp)NULL;
+ n_allocated = 10;
+ n_used = 1;
+ return;
+ }
+ for (i = 0; i < n_used; i++)
+ if (list[i]->base == base)
+ return; /* avoid duplicates */
+ if (n_used+2 > n_allocated) {
+ n_allocated += 10; /* don't re-allocate too often */
+ list = (etpp) realloc((char *)list,
+ (unsigned)n_allocated * sizeof(etp));
+ _et_list = list;
+ if (list == (etpp)NULL)
+ return; /* oops */
+ }
+ list[n_used++] = new_et;
+ list[n_used] = (etp)NULL;
+}
diff --git a/usr.bin/compile_et/perror.c b/usr.bin/compile_et/perror.c
new file mode 100644
index 0000000..ef50e07
--- /dev/null
+++ b/usr.bin/compile_et/perror.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ * For copyright info, see Copyright.SIPB
+ *
+ * $Id: perror.c,v 1.2 1994/07/19 19:21:30 g89r4222 Exp $
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include "error_table.h"
+
+typedef int (*int_func)();
+
+#if defined(mips) && defined(ultrix)
+int errno; /* this is needed to keep the loader from complaining */
+#endif
+
+int_func com_err_hook = (int_func) NULL;
+char *error_message();
+
+void
+com_err(whoami, code, message)
+ char *whoami;
+ int code;
+ char *message;
+{
+ struct iovec strings[6];
+
+ if (com_err_hook) {
+ (*com_err_hook)(whoami, code, message);
+ return;
+ }
+
+ strings[0].iov_base = whoami;
+ strings[0].iov_len = strlen(whoami);
+ if (whoami) {
+ strings[1].iov_base = ": ";
+ strings[1].iov_len = 2;
+ } else
+ strings[1].iov_len = 0;
+ if (code) {
+ register char *errmsg = error_message(code);
+ strings[2].iov_base = errmsg;
+ strings[2].iov_len = strlen(errmsg);
+ } else
+ strings[2].iov_len = 0;
+ strings[3].iov_base = " ";
+ strings[3].iov_len = 1;
+ strings[4].iov_base = message;
+ strings[4].iov_len = strlen(message);
+ strings[5].iov_base = "\n";
+ strings[5].iov_len = 1;
+ (void) writev(2, strings, 6);
+}
+
+int_func
+set_com_err_hook(new_proc)
+ int_func new_proc;
+{
+ register int_func x = com_err_hook;
+ com_err_hook = new_proc;
+ return (x);
+}
+
+reset_com_err_hook()
+{
+ com_err_hook = (int_func) NULL;
+}
+
+void
+perror(msg)
+ register const char *msg;
+{
+ com_err(msg, errno, (char *)NULL);
+}
diff --git a/usr.bin/compile_et/test/test.c b/usr.bin/compile_et/test/test.c
new file mode 100644
index 0000000..df430da
--- /dev/null
+++ b/usr.bin/compile_et/test/test.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <errno.h>
+#include "test1.h"
+#include "test2.h"
+char *error_message();
+extern int sys_nerr, errno;
+
+main()
+{
+ printf("\nBefore initiating error table:\n\n");
+ printf("Table name '%s'\n", error_table_name(KRB_MK_AP_TGTEXP));
+ printf("UNIX name '%s'\n", error_table_name(EPERM));
+ printf("Msg TGT-expired is '%s'\n", error_message(KRB_MK_AP_TGTEXP));
+ printf("Msg EPERM is '%s'\n", error_message(EPERM));
+ printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
+ printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
+ printf("Msg {sys_nerr} is '%s'\n", error_message(sys_nerr));
+
+ init_error_table(0, 0, 0);
+ printf("With 0: tgt-expired -> %s\n", error_message(KRB_MK_AP_TGTEXP));
+
+ init_krb_err_tbl();
+ printf("KRB error table initialized: base %d (%s), name %s\n",
+ krb_err_base, error_message(krb_err_base),
+ error_table_name(krb_err_base));
+ printf("With krb: tgt-expired -> %s\n",
+ error_message(KRB_MK_AP_TGTEXP));
+
+ init_quux_err_tbl();
+ printf("QUUX error table initialized: base %d (%s), name %s\n",
+ quux_err_base, error_message(quux_err_base),
+ error_table_name(quux_err_base));
+
+ printf("Msg for TGT-expired is '%s'\n",
+ error_message(KRB_MK_AP_TGTEXP));
+ printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
+ printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
+ printf("Msg KRB_SKDC_CANT is '%s'\n",
+ error_message(KRB_SKDC_CANT));
+ printf("Msg 1e6 is '%s'\n", error_message(1000000));
+ errno = FOO_ERR;
+ perror("FOO_ERR");
+}
diff --git a/usr.bin/compile_et/test/test1.et b/usr.bin/compile_et/test/test1.et
new file mode 100644
index 0000000..4c7b77f
--- /dev/null
+++ b/usr.bin/compile_et/test/test1.et
@@ -0,0 +1,69 @@
+ error_table krb
+
+ error_code KRB_MK_AP_TKFIL,
+ "Can't read ticket file"
+
+ ec KRB_MK_AP_NOTKT,
+ "Can't find ticket or TGT"
+
+ ec KRB_MK_AP_TGTEXP,
+ "TGT expired"
+
+ ec KRB_RD_AP_UNDEC,
+ "Can't decode authenticator"
+
+ ec KRB_RD_AP_EXP,
+ "Ticket expired"
+
+ ec KRB_RD_AP_REPEAT,
+ "Repeated request"
+
+ ec KRB_RD_AP_NOT_US,
+ "The ticket isn't for us"
+
+ ec KRB_RD_AP_INCON,
+ "Request is inconsistent"
+
+ ec KRB_RD_AP_TIME,
+ "Delta-T too big"
+
+ ec KRB_RD_AP_BADD,
+ "Incorrect net address"
+
+ ec KRB_RD_AP_VERSION,
+ "Protocol version mismatch"
+
+ ec KRB_RD_AP_MSG_TYPE,
+ "Invalid message type"
+
+ ec KRB_RD_AP_MODIFIED,
+ "Message stream modified"
+
+ ec KRB_RD_AP_ORDER,
+ "Message out of order"
+
+ ec KRB_RD_AP_UNAUTHOR,
+ "Unauthorized request"
+
+ ec KRB_GT_PW_NULL,
+ "Current password is null"
+
+ ec KRB_GT_PW_BADPW,
+ "Incorrect current password"
+
+ ec KRB_GT_PW_PROT,
+ "Protocol error"
+
+ ec KRB_GT_PW_KDCERR,
+ "Error returned by KDC"
+
+ ec KRB_GT_PW_NULLTKT,
+ "Null ticket returned by KDC"
+
+ ec KRB_SKDC_RETRY,
+ "Retry count exceeded"
+
+ ec KRB_SKDC_CANT,
+ "Can't send request"
+
+ end
diff --git a/usr.bin/compile_et/test/test2.et b/usr.bin/compile_et/test/test2.et
new file mode 100644
index 0000000..55ad74e
--- /dev/null
+++ b/usr.bin/compile_et/test/test2.et
@@ -0,0 +1,9 @@
+ error_table quux
+
+ ec FOO_ERR, "foo"
+
+ ec BAR_ERR, "bar"
+
+ ec BAZ_ERR, "meow"
+
+ end
OpenPOWER on IntegriCloud