summaryrefslogtreecommitdiffstats
path: root/eBones
diff options
context:
space:
mode:
authorcsgr <csgr@FreeBSD.org>1994-09-30 14:50:09 +0000
committercsgr <csgr@FreeBSD.org>1994-09-30 14:50:09 +0000
commit105186eeeeb6aa85d5ff5818e8abf65e3912cb7d (patch)
tree785c4a61d39a776700a06b092960ec07c3629dd6 /eBones
parentd011ad6fdacef9638bbc4bd1d25bae91e6f1515b (diff)
downloadFreeBSD-src-105186eeeeb6aa85d5ff5818e8abf65e3912cb7d.zip
FreeBSD-src-105186eeeeb6aa85d5ff5818e8abf65e3912cb7d.tar.gz
Initial import of eBones.
(Including all changes for FreeBSD - importing the original eBones distribution would be too complex at this stage, since I don't have access to Piero's CVS.) (If you want to include eBones in your system, don't forget to include MAKE_EBONES in /etc/make.conf.) (This stuff is now also suppable from braae.ru.ac.za.) Bones originally from MIT SIPB. Original port to FreeBSD 1.x by Piero Serini. Moved to FreeBSD 2.0 by Doug Rabson and Geoff Rehmet. Nice bug fixes from Doug Rabson.
Diffstat (limited to 'eBones')
-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
378 files changed, 46132 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);
+}
OpenPOWER on IntegriCloud