From 1440ab035ba04550ddbbfbff1ee9b5571e3d95db Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Fri, 30 Oct 1998 02:56:35 +0000 Subject: [PATCH] pull up 3des implementation from the marc-3des branch git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11001 dc483132-0cff-0310-8789-dd5450dbe970 --- src/ChangeLog | 17 + src/aclocal.m4 | 17 +- src/appl/bsd/ChangeLog | 23 + src/appl/bsd/kcmd.c | 125 +- src/appl/bsd/krlogin.c | 175 +- src/appl/bsd/krlogind.c | 175 +- src/appl/bsd/login.c | 2306 ++++++++--------- src/appl/gss-sample/ChangeLog | 12 + src/appl/gss-sample/gss-client.c | 35 +- src/appl/gss-sample/gss-server.c | 22 +- src/appl/gssftp/ftp/ChangeLog | 7 + src/appl/gssftp/ftp/ftp.c | 91 +- src/appl/telnet/libtelnet/ChangeLog | 7 + src/appl/telnet/libtelnet/enc_des.c | 109 +- src/appl/telnet/libtelnet/kerberos.c | 200 +- src/appl/telnet/telnet/ChangeLog | 7 + src/appl/telnet/telnet/commands.c | 8 - src/clients/ChangeLog | 8 + src/clients/Makefile.in | 2 +- src/clients/configure.in | 1 + src/clients/kinit/ChangeLog | 4 + src/clients/kinit/kinit.c | 536 ++-- src/clients/klist/ChangeLog | 6 + src/clients/klist/klist.c | 89 +- src/include/ChangeLog | 18 + src/include/k5-int.h | 173 +- src/include/kerberosIV/ChangeLog | 6 + src/include/kerberosIV/krb_db.h | 2 + src/include/krb5.hin | 203 +- src/include/krb5/ChangeLog | 5 + src/include/krb5/kdb.h | 46 +- src/include/krb5/kdb_dbc.h | 28 +- src/kadmin/cli/ChangeLog | 5 + src/kadmin/cli/keytab.c | 53 +- src/kadmin/dbutil/ChangeLog | 17 + src/kadmin/dbutil/dumpv4.c | 47 +- src/kadmin/dbutil/kadm5_create.c | 27 +- src/kadmin/dbutil/kdb5_create.c | 97 +- src/kadmin/dbutil/kdb5_stash.c | 34 +- src/kadmin/dbutil/kdb5_util.c | 216 +- src/kadmin/dbutil/loadv4.c | 82 +- src/kadmin/server/ChangeLog | 7 + src/kadmin/server/ovsec_kadmd.c | 42 +- src/kadmin/v4server/ChangeLog | 15 + src/kadmin/v4server/acl_files.c | 2 +- src/kadmin/v4server/admin_server.c | 5 +- src/kadmin/v4server/kadm_funcs.c | 2 + src/kadmin/v4server/kadm_ser_wrap.c | 24 +- src/kadmin/v4server/kadm_server.h | 1 - src/kdc/ChangeLog | 53 + src/kdc/do_as_req.c | 27 +- src/kdc/do_tgs_req.c | 59 +- src/kdc/extern.h | 2 - src/kdc/kdc_preauth.c | 256 +- src/kdc/kdc_util.c | 115 +- src/kdc/kerberos_v4.c | 240 +- src/kdc/main.c | 84 +- src/krb524/ChangeLog | 23 + src/krb524/cnv_tkt_skey.c | 46 +- src/krb524/krb524d.c | 46 +- src/lib/crypto/ChangeLog | 31 + src/lib/crypto/Makefile.in | 213 +- src/lib/crypto/block_size.c | 49 + src/lib/crypto/checksum_length.c | 53 + src/lib/crypto/cksumtype_to_string.c | 49 + src/lib/crypto/cksumtypes.c | 74 + src/lib/crypto/cksumtypes.h | 31 + src/lib/crypto/coll_proof_cksum.c | 44 + src/lib/crypto/configure.in | 130 +- src/lib/crypto/crc32/ChangeLog | 4 + src/lib/crypto/crc32/Makefile.in | 26 +- src/lib/crypto/crc32/crc-32.h | 32 +- src/lib/crypto/crc32/crc32.c | 166 ++ src/lib/crypto/cryptoconf.c | 168 -- src/lib/crypto/decrypt.c | 56 + src/lib/crypto/decrypt_data.c | 66 - src/lib/crypto/des/.rconf | 8 - src/lib/crypto/des/ChangeLog | 4 + src/lib/crypto/des/FUNCTIONS | 26 - src/lib/crypto/des/Makefile.in | 114 +- src/lib/crypto/des/afsstring2key.c | 32 +- src/lib/crypto/des/cbc_cksum.c | 164 -- src/lib/crypto/des/d3_ecb.c | 47 - src/lib/crypto/des/d3_procky.c | 60 - src/lib/crypto/des/d3_str2ky.c | 137 - src/lib/crypto/des/des.h | 59 - src/lib/crypto/des/des_int.h | 29 +- src/lib/crypto/des/destest.c | 68 +- src/lib/crypto/des/f_README | 69 - src/lib/crypto/des/f_ecb.c | 95 - src/lib/crypto/des/f_pcbc.c | 207 -- src/lib/crypto/des/fin_rndkey.c | 51 - src/lib/crypto/des/finish_key.c | 48 - src/lib/crypto/des/init_rkey.c | 167 -- src/lib/crypto/des/process_ky.c | 70 - src/lib/crypto/des/random_key.c | 95 - src/lib/crypto/des/string2key.c | 40 +- src/lib/crypto/des/t_random.c | 117 - src/lib/crypto/des/t_verify.c | 146 +- src/lib/crypto/des/u_nfold.c | 99 - src/lib/crypto/des/u_rn_key.c | 139 - src/lib/crypto/des3_raw.c | 104 - src/lib/crypto/des3_sha.c | 178 -- src/lib/crypto/des_crc.c | 170 -- src/lib/crypto/des_md5.c | 171 -- src/lib/crypto/encrypt.c | 56 + src/lib/crypto/encrypt_data.c | 70 - src/lib/crypto/encrypt_length.c | 52 + src/lib/crypto/enctype_compare.c | 58 + src/lib/crypto/enctype_to_string.c | 49 + src/lib/crypto/etypes.c | 82 + src/lib/crypto/etypes.h | 30 + src/lib/crypto/hmac.c | 131 + src/lib/crypto/keyed_checksum_types.c | 95 + src/lib/crypto/keyed_cksum.c | 49 + src/lib/crypto/krb5_glue.c | 233 -- src/lib/crypto/make_checksum.c | 111 + src/lib/crypto/make_random_key.c | 84 + src/lib/crypto/md4/.rconf | 2 - src/lib/crypto/md4/ChangeLog | 4 + src/lib/crypto/md4/Makefile.in | 30 +- src/lib/crypto/md4/md4crypto.c | 385 --- src/lib/crypto/md4/md4driver.c | 202 -- src/lib/crypto/md4/md4glue.c | 115 - src/lib/crypto/md5/ChangeLog | 4 + src/lib/crypto/md5/Makefile.in | 22 +- src/lib/crypto/md5/md5crypto.c | 353 --- src/lib/crypto/md5/md5glue.c | 89 - src/lib/crypto/md5/t_cksum.c | 203 -- src/lib/crypto/nfold.c | 132 + src/lib/crypto/old_api_glue.c | 360 +++ src/lib/crypto/os/.Sanitize | 39 - src/lib/crypto/os/ChangeLog | 204 -- src/lib/crypto/os/Makefile.in | 28 - src/lib/crypto/os/c_localaddr.c | 348 --- src/lib/crypto/os/rnd_confoun.c | 98 - src/lib/crypto/prng.c | 155 ++ src/lib/crypto/raw_des.c | 100 - src/lib/crypto/sha/.Sanitize | 42 - src/lib/crypto/sha/ChangeLog | 89 - src/lib/crypto/sha/Makefile.in | 43 - src/lib/crypto/sha/hmac_sha.c | 101 - src/lib/crypto/sha/sha_crypto.c | 76 - src/lib/crypto/sha/sha_glue.c | 97 - src/lib/crypto/sha/shs.c | 392 --- src/lib/crypto/sha/shs.h | 59 - src/lib/crypto/sha/t_shs.c | 132 - src/lib/crypto/string_to_cksumtype.c | 45 + src/lib/crypto/string_to_enctype.c | 45 + src/lib/crypto/string_to_key.c | 68 + src/lib/crypto/t_nfold.c | 76 + src/lib/crypto/valid_cksumtype.c | 41 + src/lib/crypto/valid_enctype.c | 41 + src/lib/crypto/verify_checksum.c | 84 + src/lib/des425/ChangeLog | 8 +- src/lib/des425/Makefile.in | 5 +- src/lib/des425/new_rnd_key.c | 124 +- src/lib/des425/random_key.c | 49 +- src/lib/gssapi/Makefile.in | 2 +- src/lib/gssapi/generic/ChangeLog | 5 + src/lib/gssapi/generic/gssapi.hin | 8 +- src/lib/gssapi/generic/gssapi_err_generic.et | 3 + src/lib/gssapi/generic/util_token.c | 7 +- src/lib/gssapi/krb5/ChangeLog | 39 + src/lib/gssapi/krb5/Makefile.in | 6 + src/lib/gssapi/krb5/accept_sec_context.c | 980 ++++--- src/lib/gssapi/krb5/acquire_cred.c | 115 +- src/lib/gssapi/krb5/add_cred.c | 309 +++ src/lib/gssapi/krb5/canon_name.c | 17 +- src/lib/gssapi/krb5/delete_sec_context.c | 15 +- src/lib/gssapi/krb5/disp_status.c | 10 +- src/lib/gssapi/krb5/gssapiP_krb5.h | 77 +- src/lib/gssapi/krb5/gssapi_err_krb5.et | 1 + src/lib/gssapi/krb5/gssapi_krb5.c | 39 + src/lib/gssapi/krb5/gssapi_krb5.h | 3 + src/lib/gssapi/krb5/init_sec_context.c | 604 ++++- src/lib/gssapi/krb5/inq_cred.c | 57 +- src/lib/gssapi/krb5/inq_names.c | 3 +- src/lib/gssapi/krb5/k5seal.c | 356 ++- src/lib/gssapi/krb5/k5unseal.c | 585 ++++- src/lib/gssapi/krb5/rel_oid.c | 3 +- src/lib/gssapi/krb5/ser_sctx.c | 305 +-- src/lib/gssapi/krb5/util_cksum.c | 27 +- src/lib/gssapi/krb5/util_crypt.c | 161 +- src/lib/gssapi/krb5/util_ctxsetup.c | 208 ++ src/lib/gssapi/krb5/util_seed.c | 16 +- src/lib/gssapi/krb5/util_seqnum.c | 12 +- src/lib/gssapi/krb5/wrap_size_limit.c | 108 +- src/lib/kadm5/ChangeLog | 11 + src/lib/kadm5/alt_prof.c | 11 +- src/lib/kadm5/clnt/ChangeLog | 9 + src/lib/kadm5/clnt/Makefile.in | 2 +- src/lib/kadm5/clnt/client_init.c | 42 +- src/lib/kadm5/srv/ChangeLog | 8 + src/lib/kadm5/srv/Makefile.in | 2 +- src/lib/kadm5/srv/server_kdb.c | 27 +- src/lib/kadm5/srv/svr_principal.c | 72 +- src/lib/kdb/ChangeLog | 30 + src/lib/kdb/Makefile.in | 4 +- src/lib/kdb/decrypt_key.c | 88 +- src/lib/kdb/encrypt_key.c | 80 +- src/lib/kdb/fetch_mkey.c | 40 +- src/lib/kdb/kdb_cpw.c | 209 +- src/lib/kdb/kdb_db2.c | 38 +- src/lib/kdb/kdb_db2.h | 2 +- src/lib/kdb/kdb_dbm.c | 12 +- src/lib/kdb/kdb_xdr.c | 39 +- src/lib/kdb/keytab.c | 2 +- src/lib/kdb/verify_mky.c | 21 +- src/lib/krb4/ChangeLog | 31 + src/lib/krb4/Makefile.in | 2 +- src/lib/krb4/cr_tkt.c | 92 +- src/lib/krb4/decomp_tkt.c | 85 +- src/lib/krb4/rd_req.c | 47 +- src/lib/krb4/tf_util.c | 2 +- src/lib/krb5/ChangeLog | 8 + src/lib/krb5/Makefile.in | 4 +- src/lib/krb5/asn.1/ChangeLog | 7 + src/lib/krb5/asn.1/asn1buf.c | 2 +- src/lib/krb5/ccache/ChangeLog | 4 + src/lib/krb5/ccache/ccapi/Makefile.in | 21 - src/lib/krb5/ccache/ccapi/stdcc.c | 394 --- src/lib/krb5/ccache/ccapi/stdcc.h | 73 - src/lib/krb5/ccache/ccapi/stdcc_util.c | 368 --- src/lib/krb5/ccache/ccapi/stdcc_util.h | 25 - src/lib/krb5/ccache/ccbase.c | 6 +- src/lib/krb5/configure.in | 1 + src/lib/krb5/error_tables/krb5_err.et | 2 + src/lib/krb5/keytab/file/ChangeLog | 5 + src/lib/krb5/keytab/file/ktf_g_ent.c | 87 +- src/lib/krb5/krb/ChangeLog | 36 + src/lib/krb5/krb/Makefile.in | 3 + src/lib/krb5/krb/auth_con.c | 70 +- src/lib/krb5/krb/auth_con.h | 1 + src/lib/krb5/krb/decode_kdc.c | 18 +- src/lib/krb5/krb/decrypt_tk.c | 24 +- src/lib/krb5/krb/enc_helper.c | 53 + src/lib/krb5/krb/encode_kdc.c | 66 +- src/lib/krb5/krb/encrypt_tk.c | 61 +- src/lib/krb5/krb/gen_seqnum.c | 70 +- src/lib/krb5/krb/gen_subkey.c | 27 +- src/lib/krb5/krb/get_creds.c | 107 +- src/lib/krb5/krb/gic_pwd.c | 8 +- src/lib/krb5/krb/in_tkt_pwd.c | 9 +- src/lib/krb5/krb/init_ctx.c | 183 +- src/lib/krb5/krb/kdc_rep_dc.c | 29 +- src/lib/krb5/krb/kfree.c | 11 + src/lib/krb5/krb/mk_cred.c | 47 +- src/lib/krb5/krb/mk_priv.c | 59 +- src/lib/krb5/krb/mk_rep.c | 44 +- src/lib/krb5/krb/mk_req_ext.c | 65 +- src/lib/krb5/krb/mk_safe.c | 15 +- src/lib/krb5/krb/preauth.c | 16 +- src/lib/krb5/krb/preauth2.c | 23 +- src/lib/krb5/krb/rd_cred.c | 26 +- src/lib/krb5/krb/rd_priv.c | 41 +- src/lib/krb5/krb/rd_rep.c | 27 +- src/lib/krb5/krb/rd_req_dec.c | 93 +- src/lib/krb5/krb/rd_safe.c | 11 +- src/lib/krb5/krb/send_tgs.c | 100 +- src/lib/krb5/krb/ser_actx.c | 39 +- src/lib/krb5/krb/ser_eblk.c | 4 + src/lib/krb5/krb/str_conv.c | 148 -- src/lib/krb5/krb/vfy_increds.c | 104 +- src/lib/krb5/os/ChangeLog | 13 + src/lib/krb5/os/Makefile.in | 3 + src/lib/{crypto => krb5}/os/c_ustime.c | 2 +- src/lib/krb5/os/ktdefname.c | 22 +- src/lib/krb5/os/localaddr.c | 317 ++- src/lib/krb5/os/locate_kdc.c | 31 +- src/lib/rpc/ChangeLog | 9 + src/lib/rpc/Makefile.in | 2 +- src/lib/rpc/auth_gssapi.h | 6 +- src/lib/rpc/svc_auth_gssapi.c | 43 +- src/mac/TestTrack/ChangeLog | 24 - src/mac/TestTrack/MITAthenaLib | 1 - src/mac/TestTrack/ShlibTestTrack.c | 115 - src/mac/TestTrack/ShlibTestTrack.h | 19 - src/mac/TestTrack/TestTrackLib.h | 59 - src/mac/TestTrack/testtrack.h | 30 - .../CCache API/bin/CCacheGlobalsLib.68K | 1 - .../CCache API/bin/CCacheGlobalsLib.PPC | 1 - .../libraries/CCache API/bin/CCacheLib.68K | 1 - .../CCache API/bin/CCacheLib.68K.debug | 1 - .../libraries/CCache API/bin/CCacheLib.PPC | 1 - .../CCache API/bin/CCacheLib.PPC.debug | 1 - src/mac/libraries/CCache API/include/CCache.h | 350 --- .../libraries/CCache API/include/CCacheUtil.h | 28 - .../CodeWarrior Dependencies/Pro2.prj | Bin 17459 -> 0 bytes .../CodeWarrior Dependencies/Pro4.prj | Bin 18655 -> 0 bytes src/mac/libraries/DES/bin/deslib.68K | 1 - src/mac/libraries/DES/bin/deslib.68K.debug | 1 - src/mac/libraries/DES/bin/deslib.PPC | 1 - src/mac/libraries/DES/bin/deslib.PPC.debug | 1 - src/mac/libraries/DES/doc/ChangeLog | 369 --- src/mac/libraries/DES/doc/READ_ME | 21 - src/mac/libraries/DES/doc/f_README | 69 - src/mac/libraries/DES/doc/ren.msg | 32 - src/mac/libraries/DES/include/des.h | 158 -- .../libraries/DES/include/deslib.CFMGlue.c | 842 ------ .../libraries/DES/include/deslib.CFMGlue.h | 8 - src/mac/libraries/DES/include/mit-copyright.h | 20 - .../Metrowerks/CW Pro 2/MIT C.CFM68K DLL.doc | 31 - .../Metrowerks/CW Pro 2/MIT C.CFM68K DLL.prj | Bin 86057 -> 0 bytes .../Metrowerks/CW Pro 2/MIT C.PPC DLL.doc | 31 - .../Metrowerks/CW Pro 2/MIT C.PPC DLL.prj | Bin 97000 -> 0 bytes .../CW Pro 2/MIT RuntimeCFM68K DLL.doc | 31 - .../CW Pro 2/MIT RuntimeCFM68K DLL.prj | Bin 83326 -> 0 bytes .../CW Pro 2/MIT RuntimePPC DLL.doc | 31 - .../CW Pro 2/MIT RuntimePPC DLL.prj | Bin 80572 -> 0 bytes .../Metrowerks/CW Pro 4/MIT C.CFM68K DLL.doc | 30 - .../Metrowerks/CW Pro 4/MIT C.CFM68K DLL.prj | Bin 89611 -> 0 bytes .../Metrowerks/CW Pro 4/MIT C.PPC DLL.doc | 33 - .../Metrowerks/CW Pro 4/MIT C.PPC DLL.prj | Bin 95479 -> 0 bytes .../CW Pro 4/MIT RuntimeCFM68K DLL.doc | 30 - .../CW Pro 4/MIT RuntimeCFM68K DLL.prj | Bin 80278 -> 0 bytes .../CW Pro 4/MIT RuntimePPC DLL.doc | 32 - .../CW Pro 4/MIT RuntimePPC DLL.prj | Bin 91916 -> 0 bytes src/slave/ChangeLog | 5 + src/slave/kpropd.c | 80 +- src/tests/create/ChangeLog | 4 + src/tests/create/kdb5_mkdums.c | 36 +- src/tests/misc/test_nfold.c | 65 + src/tests/verify/ChangeLog | 4 + src/tests/verify/kdb5_verify.c | 8 +- src/util/profile/ChangeLog | 4 + src/util/profile/Makefile.in | 5 + src/util/profile/configure.in | 3 +- src/util/pty/ChangeLog | 4 + src/util/pty/Makefile.in | 5 + src/util/pty/configure.in | 2 +- src/util/ss/execute_cmd.c | 8 +- src/windows/lib/ChangeLog | 16 - src/windows/lib/Makefile.in | 19 - src/windows/lib/gic.c | 156 -- src/windows/lib/gic.h | 28 - src/windows/lib/registry.c | 231 -- src/windows/lib/registry.h | 40 - src/windows/lib/vardlg.c | 450 ---- src/windows/lib/vardlg.h | 32 - 340 files changed, 11806 insertions(+), 15571 deletions(-) create mode 100644 src/lib/crypto/block_size.c create mode 100644 src/lib/crypto/checksum_length.c create mode 100644 src/lib/crypto/cksumtype_to_string.c create mode 100644 src/lib/crypto/cksumtypes.c create mode 100644 src/lib/crypto/cksumtypes.h create mode 100644 src/lib/crypto/coll_proof_cksum.c create mode 100644 src/lib/crypto/crc32/crc32.c delete mode 100644 src/lib/crypto/cryptoconf.c create mode 100644 src/lib/crypto/decrypt.c delete mode 100644 src/lib/crypto/decrypt_data.c delete mode 100644 src/lib/crypto/des/.rconf delete mode 100644 src/lib/crypto/des/FUNCTIONS delete mode 100644 src/lib/crypto/des/cbc_cksum.c delete mode 100644 src/lib/crypto/des/d3_ecb.c delete mode 100644 src/lib/crypto/des/d3_procky.c delete mode 100644 src/lib/crypto/des/d3_str2ky.c delete mode 100644 src/lib/crypto/des/des.h delete mode 100644 src/lib/crypto/des/f_README delete mode 100644 src/lib/crypto/des/f_ecb.c delete mode 100644 src/lib/crypto/des/f_pcbc.c delete mode 100644 src/lib/crypto/des/fin_rndkey.c delete mode 100644 src/lib/crypto/des/finish_key.c delete mode 100644 src/lib/crypto/des/init_rkey.c delete mode 100644 src/lib/crypto/des/process_ky.c delete mode 100644 src/lib/crypto/des/random_key.c delete mode 100644 src/lib/crypto/des/t_random.c delete mode 100644 src/lib/crypto/des/u_nfold.c delete mode 100644 src/lib/crypto/des/u_rn_key.c delete mode 100644 src/lib/crypto/des3_raw.c delete mode 100644 src/lib/crypto/des3_sha.c delete mode 100644 src/lib/crypto/des_crc.c delete mode 100644 src/lib/crypto/des_md5.c create mode 100644 src/lib/crypto/encrypt.c delete mode 100644 src/lib/crypto/encrypt_data.c create mode 100644 src/lib/crypto/encrypt_length.c create mode 100644 src/lib/crypto/enctype_compare.c create mode 100644 src/lib/crypto/enctype_to_string.c create mode 100644 src/lib/crypto/etypes.c create mode 100644 src/lib/crypto/etypes.h create mode 100644 src/lib/crypto/hmac.c create mode 100644 src/lib/crypto/keyed_checksum_types.c create mode 100644 src/lib/crypto/keyed_cksum.c delete mode 100644 src/lib/crypto/krb5_glue.c create mode 100644 src/lib/crypto/make_checksum.c create mode 100644 src/lib/crypto/make_random_key.c delete mode 100644 src/lib/crypto/md4/.rconf delete mode 100644 src/lib/crypto/md4/md4crypto.c delete mode 100644 src/lib/crypto/md4/md4driver.c delete mode 100644 src/lib/crypto/md4/md4glue.c delete mode 100644 src/lib/crypto/md5/md5crypto.c delete mode 100644 src/lib/crypto/md5/md5glue.c delete mode 100644 src/lib/crypto/md5/t_cksum.c create mode 100644 src/lib/crypto/nfold.c create mode 100644 src/lib/crypto/old_api_glue.c delete mode 100644 src/lib/crypto/os/.Sanitize delete mode 100644 src/lib/crypto/os/ChangeLog delete mode 100644 src/lib/crypto/os/Makefile.in delete mode 100644 src/lib/crypto/os/c_localaddr.c delete mode 100644 src/lib/crypto/os/rnd_confoun.c create mode 100644 src/lib/crypto/prng.c delete mode 100644 src/lib/crypto/raw_des.c delete mode 100644 src/lib/crypto/sha/.Sanitize delete mode 100644 src/lib/crypto/sha/ChangeLog delete mode 100644 src/lib/crypto/sha/Makefile.in delete mode 100644 src/lib/crypto/sha/hmac_sha.c delete mode 100644 src/lib/crypto/sha/sha_crypto.c delete mode 100644 src/lib/crypto/sha/sha_glue.c delete mode 100644 src/lib/crypto/sha/shs.c delete mode 100644 src/lib/crypto/sha/shs.h delete mode 100644 src/lib/crypto/sha/t_shs.c create mode 100644 src/lib/crypto/string_to_cksumtype.c create mode 100644 src/lib/crypto/string_to_enctype.c create mode 100644 src/lib/crypto/string_to_key.c create mode 100644 src/lib/crypto/t_nfold.c create mode 100644 src/lib/crypto/valid_cksumtype.c create mode 100644 src/lib/crypto/valid_enctype.c create mode 100644 src/lib/crypto/verify_checksum.c create mode 100644 src/lib/gssapi/krb5/add_cred.c create mode 100644 src/lib/gssapi/krb5/util_ctxsetup.c delete mode 100644 src/lib/krb5/ccache/ccapi/Makefile.in delete mode 100644 src/lib/krb5/ccache/ccapi/stdcc.c delete mode 100644 src/lib/krb5/ccache/ccapi/stdcc.h delete mode 100644 src/lib/krb5/ccache/ccapi/stdcc_util.c delete mode 100644 src/lib/krb5/ccache/ccapi/stdcc_util.h create mode 100644 src/lib/krb5/krb/enc_helper.c rename src/lib/{crypto => krb5}/os/c_ustime.c (99%) delete mode 100644 src/mac/TestTrack/ChangeLog delete mode 100644 src/mac/TestTrack/MITAthenaLib delete mode 100644 src/mac/TestTrack/ShlibTestTrack.c delete mode 100644 src/mac/TestTrack/ShlibTestTrack.h delete mode 100644 src/mac/TestTrack/TestTrackLib.h delete mode 100644 src/mac/TestTrack/testtrack.h delete mode 100644 src/mac/libraries/CCache API/bin/CCacheGlobalsLib.68K delete mode 100644 src/mac/libraries/CCache API/bin/CCacheGlobalsLib.PPC delete mode 100644 src/mac/libraries/CCache API/bin/CCacheLib.68K delete mode 100644 src/mac/libraries/CCache API/bin/CCacheLib.68K.debug delete mode 100644 src/mac/libraries/CCache API/bin/CCacheLib.PPC delete mode 100644 src/mac/libraries/CCache API/bin/CCacheLib.PPC.debug delete mode 100644 src/mac/libraries/CCache API/include/CCache.h delete mode 100644 src/mac/libraries/CCache API/include/CCacheUtil.h delete mode 100644 src/mac/libraries/CodeWarrior Dependencies/Pro2.prj delete mode 100644 src/mac/libraries/CodeWarrior Dependencies/Pro4.prj delete mode 100644 src/mac/libraries/DES/bin/deslib.68K delete mode 100644 src/mac/libraries/DES/bin/deslib.68K.debug delete mode 100644 src/mac/libraries/DES/bin/deslib.PPC delete mode 100644 src/mac/libraries/DES/bin/deslib.PPC.debug delete mode 100644 src/mac/libraries/DES/doc/ChangeLog delete mode 100644 src/mac/libraries/DES/doc/READ_ME delete mode 100644 src/mac/libraries/DES/doc/f_README delete mode 100644 src/mac/libraries/DES/doc/ren.msg delete mode 100644 src/mac/libraries/DES/include/des.h delete mode 100644 src/mac/libraries/DES/include/deslib.CFMGlue.c delete mode 100644 src/mac/libraries/DES/include/deslib.CFMGlue.h delete mode 100644 src/mac/libraries/DES/include/mit-copyright.h delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT C.PPC DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT C.PPC DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimePPC DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimePPC DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT C.CFM68K DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT C.CFM68K DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT C.PPC DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT C.PPC DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.prj delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.doc delete mode 100644 src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.prj create mode 100644 src/tests/misc/test_nfold.c delete mode 100644 src/windows/lib/ChangeLog delete mode 100644 src/windows/lib/Makefile.in delete mode 100644 src/windows/lib/gic.c delete mode 100644 src/windows/lib/gic.h delete mode 100644 src/windows/lib/registry.c delete mode 100644 src/windows/lib/registry.h delete mode 100644 src/windows/lib/vardlg.c delete mode 100644 src/windows/lib/vardlg.h diff --git a/src/ChangeLog b/src/ChangeLog index 2189342e5..409a200cb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,9 +1,26 @@ +Wed Sep 23 15:24:44 1998 Tom Yu + + * aclocal.m4 (KRB5_LIB_AUX): Do what Sam originally meant to do by + moving the explicit resetting of DEPLIB=$SHLIBEXT and forcing + SHLIBEXT=.so-nobuild to avoid duplicate rules on AIX and such. + 1998-08-24 Theodore Ts'o * Makefile.in: Add support to build the lib/krb5/ccache api directory and include it in the Windows kerbsrc-nt.zip file. +Wed Aug 19 20:14:31 1998 Tom Yu + + * aclocal.m4 (KRB5_LIB_AUX): Back out Sam's change to reorder the + "force_static" logic, as it would cause problems where a + forced-static library is built in the same directory as a + program, due to explicit setting of CC_LINK, etc. + +Mon Aug 17 18:10:29 1998 Tom Yu + + * aclocal.m4: Fix Sam's fixes (variable capitalization). + Wed Jul 8 01:10:44 1998 Matthew D Hancher * aclocal.m4: Allow shared libraries to build properly under Irix diff --git a/src/aclocal.m4 b/src/aclocal.m4 index af2d8a923..1bfd92606 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -868,8 +868,8 @@ if test "$enableval" = no && test "$krb5_force_static" != yes; then LIBLIST= OBJLISTS= else - LIBLIST="lib\$(LIB)$STLIBEXT" - LIBLINKS="\$(TOPLIBD)/lib\$(LIB)$STLIBEXT" + LIBLIST='lib$(LIB)$(STLIBEXT)' + LIBLINKS='$(TOPLIBD)/lib$(LIB)$(STLIBEXT)' OBJLISTS=OBJS.ST LIBINSTLIST=install-static DEPLIBEXT=$STLIBEXT @@ -886,8 +886,12 @@ AC_ARG_ENABLE([shared], CC_LINK="$CC_LINK_STATIC" ;; *) + # set this now because some logic below may reset SHLIBEXT + DEPLIBEXT=$SHLIBEXT if test "$krb5_force_static" = "yes"; then AC_MSG_RESULT([Forcing static libraries.]) + # avoid duplicate rules generation for AIX and such + SHLIBEXT=.so-nobuild else AC_MSG_RESULT([Enabling shared libraries.]) LIBLIST="$LIBLIST "'lib$(LIB)$(SHLIBEXT)' @@ -904,7 +908,6 @@ AC_ARG_ENABLE([shared], esac OBJLISTS="$OBJLISTS OBJS.SH" fi - DEPLIBEXT=$SHLIBEXT CC_LINK="$CC_LINK_SHARED" if test "$STLIBEXT" = "$SHLIBEXT" ; then STLIBEXT=".a-no-build" @@ -1018,7 +1021,7 @@ mips-sgi-irix6.3) # This is a Kludge; see below SHLIBEXT=.so SHOBJEXT=.o # Kludge follows: (gcc makes n32 object files but ld expects o32, so we reeducate ld) - if test "$GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then LDCOMBINE='ld -n32 -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname lib$(LIB)$(SHLIBSEXT)' else LDCOMBINE='ld -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname lib$(LIB)$(SHLIBSEXT)' @@ -1047,7 +1050,7 @@ mips-sgi-irix*) # untested... mips-sni-sysv4) - if test "$GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then PICFLAGS=-fpic LDCOMBINE='$(CC) -G -Wl,-h -Wl,lib$(LIB)$(SHLIBSEXT)' else @@ -1114,7 +1117,7 @@ mips-*-netbsd*) ;; *-*-solaris*) - if test "$GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then PICFLAGS=-fpic LDCOMBINE='$(CC) -shared -h lib$(LIB)$(SHLIBSEXT)' else @@ -1171,7 +1174,7 @@ mips-*-netbsd*) LDCOMBINE='$(BUILDTOP)/util/makeshlib $(LIBMAJOR).$(LIBMINOR)' SHLIB_EXPFLAGS=' $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg - if test "$gcc" = "yes" ; then + if test "$krb5_cv_prog_gcc" = "yes" ; then CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -Xlinker -bex4:$(BUILDTOP)/util/aix.bincmds ' else CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -bex4:$(BUILDTOP)/util/aix.bincmds ' diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 6eaa52942..8f7e9a8fc 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,17 @@ +1998-10-24 Marc Horowitz + + * login.c: update to new get_creds API + + * krlogin.c (main, oob, server_message, control), krlogind.c + (sendoob, protocol, recvauth): If the enctype is not + similar to DES, use an inband signalling protocol instead + of MSG_OOB data to indicate status changes. + + * kcmd.c (rcmd_stream_init_krb5, v5_des_read, v5_des_write): + update to new crypto API. Add ivec chaining to + encryption when the enctype is not similar to DES as part + of the new protocol. + 1998-10-06 Theodore Ts'o * krshd.c (doit): Apply ghudson's patch so that rshd passes the @@ -8,6 +22,10 @@ the foreign and local ports so that encrypted rcp for the same machine. [krb5-appl/638] +Tue Aug 18 16:48:02 1998 Tom Yu + + * krlogin.c: Add for FIONREAD. + Sat Aug 15 00:01:15 1998 Geoffrey King * krcp.c (error): Don't call rcmd_stream_write if iamremote is not @@ -19,6 +37,11 @@ Mon Jul 27 00:06:20 1998 Geoffrey King * krlogin.c (main): Apply ghudson's patch so that rlogin -a no longer dumps core. [krb5-appl/612] +Sun Jul 26 23:46:36 1998 Sam Hartman + + * login.c (main): Allow krb524 conversion for forwarded tickets + (try_convert524): Don't check to see if we have tickets here; caller does that and actually gets it right. + 1998-05-26 Theodore Ts'o * login.c (dolastlog): BSD 4.4 systems don't have lastlog.h, but diff --git a/src/appl/bsd/kcmd.c b/src/appl/bsd/kcmd.c index c6f21e02f..f77571917 100644 --- a/src/appl/bsd/kcmd.c +++ b/src/appl/bsd/kcmd.c @@ -19,6 +19,32 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88 */ #ifdef HAVE_UNISTD_H @@ -76,6 +102,8 @@ extern Key_schedule v4_schedule; #define START_PORT 5120 /* arbitrary */ char *default_service = "host"; +#define KCMD_KEYUSAGE 1026 + /* * Note that the encrypted rlogin packets take the form of a four-byte * length followed by encrypted data. On writing the data out, a significant @@ -89,7 +117,8 @@ static char des_inbuf[2*RCMD_BUFSIZ]; /* needs to be > largest read size */ static char des_outpkt[2*RCMD_BUFSIZ+4]; /* needs to be > largest write size */ static krb5_data desinbuf; static krb5_data desoutbuf; -static krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */ +static krb5_data encivec; +static krb5_keyblock *keyblock; /* key for encrypt/decrypt */ static int (*input)(); static int (*output)(); static char storage[2*RCMD_BUFSIZ]; /* storage for the decryption */ @@ -713,12 +742,14 @@ void rcmd_stream_init_normal() output = twrite; } -void rcmd_stream_init_krb5(keyblock, encrypt_flag, lencheck) - krb5_keyblock *keyblock; +void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck) + krb5_keyblock *in_keyblock; int encrypt_flag; int lencheck; { krb5_error_code status; + size_t blocksize; + krb5_boolean similar; if (!encrypt_flag) { rcmd_stream_init_normal(); @@ -726,15 +757,39 @@ void rcmd_stream_init_krb5(keyblock, encrypt_flag, lencheck) } desinbuf.data = des_inbuf; desoutbuf.data = des_outpkt+4; /* Set up des buffers */ - krb5_use_enctype(bsd_context, &eblock, keyblock->enctype); - if ( status = krb5_process_key(bsd_context, &eblock, keyblock)) { - fprintf(stderr, "rcmd: Cannot process session key: %s\n", - error_message(status)); - exit(1); - } + keyblock = in_keyblock; + do_lencheck = lencheck; input = v5_des_read; output = v5_des_write; + + if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, + keyblock->enctype, + &similar)) { + /* XXX what do I do? */ + abort(); + } + + if (similar) { + encivec.length = 0; + return; + } + + if (status = krb5_c_block_size(bsd_context, keyblock->enctype, + &blocksize)) { + /* XXX what do I do? */ + abort(); + } + + encivec.length = blocksize; + + if ((encivec.data = malloc(encivec.length)) == NULL) { + /* XXX what do I do? */ + abort(); + } + + /* is there a better way to initialize this? */ + memset(encivec.data, '\0', blocksize); } #ifdef KRB5_KRB4_COMPAT @@ -787,9 +842,12 @@ static int v5_des_read(fd, buf, len) int len; { int nreturned = 0; - long net_len,rd_len; + size_t net_len,rd_len; int cc; unsigned char c; + krb5_error_code ret; + krb5_data plain; + krb5_enc_data cipher; if (nstored >= len) { memcpy(buf, store_ptr, len); @@ -823,7 +881,12 @@ static int v5_des_read(fd, buf, len) if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0; rd_len = (rd_len << 8) | c; - net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry); + if (ret = krb5_c_encrypt_length(bsd_context, keyblock->enctype, + rd_len, &net_len)) { + errno = ret; + return(-1); + } + if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) { /* preposterous length, probably out of sync */ errno = EIO; @@ -834,11 +897,17 @@ static int v5_des_read(fd, buf, len) errno = EIO; return(-1); } + + cipher.enctype = ENCTYPE_UNKNOWN; + cipher.ciphertext.length = net_len; + cipher.ciphertext.data = desinbuf.data; + plain.length = sizeof(storage); + plain.data = storage; + /* decrypt info */ - if ((krb5_decrypt(bsd_context, desinbuf.data, - (krb5_pointer) storage, - net_len, - &eblock, 0))) { + if (krb5_c_decrypt(bsd_context, keyblock, KCMD_KEYUSAGE, + encivec.length?&encivec:0, + &cipher, &plain)) { /* probably out of sync */ errno = EIO; return(-1); @@ -867,21 +936,24 @@ static int v5_des_write(fd, buf, len) int len; { unsigned char *len_buf = (unsigned char *) des_outpkt; - - desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry); - if (desoutbuf.length > sizeof(des_outpkt)-4){ - errno = EIO; - return(-1); - } - if ((krb5_encrypt(bsd_context, (krb5_pointer)buf, - desoutbuf.data, - len, - &eblock, - 0))){ + krb5_data plain; + krb5_enc_data cipher; + + plain.data = buf; + plain.length = len; + + cipher.ciphertext.length = sizeof(des_outpkt)-4; + cipher.ciphertext.data = desoutbuf.data; + + if (krb5_c_encrypt(bsd_context, keyblock, KCMD_KEYUSAGE, + encivec.length?&encivec:0, + &plain, &cipher)) { errno = EIO; return(-1); } + desoutbuf.length = cipher.ciphertext.length; + len_buf[0] = (len & 0xff000000) >> 24; len_buf[1] = (len & 0xff0000) >> 16; len_buf[2] = (len & 0xff00) >> 8; @@ -891,6 +963,7 @@ static int v5_des_write(fd, buf, len) errno = EIO; return(-1); } + else return(len); } diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index 54d048b65..0bfb3ef57 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -19,6 +19,32 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef lint char copyright[] = "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ @@ -61,6 +87,11 @@ char copyright[] = #include #include +#ifdef HAVE_SYS_FILIO_H +/* Solaris needs for FIONREAD */ +#include +#endif + #ifdef HAVE_STDLIB_H #include #endif @@ -175,6 +206,7 @@ char *getenv(); char *name; int rem = -1; /* Remote socket fd */ +int do_inband = 0; char cmdchar = '~'; int eight = 1; /* Default to 8 bit transmission */ int no_local_escape = 0; @@ -219,6 +251,7 @@ char *host=0; /* external, so it can be reached from confirm_death() */ krb5_sigtype sigwinch KRB5_PROTOTYPE((int)); +int server_message KRB5_PROTOTYPE((int)); void oob KRB5_PROTOTYPE((void)); krb5_sigtype lostpeer KRB5_PROTOTYPE((int)); #if __STDC__ @@ -593,8 +626,22 @@ main(argc, argv) #else try_normal(orig_argv); #endif - } else + } else { + krb5_boolean similar; + rcmd_stream_init_krb5(&cred->keyblock, encrypt_flag, 1); + + if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, + cred->keyblock.enctype, &similar)) + try_normal(orig_argv); /* doesn't return */ + + if (!similar) { + do_inband = 1; + if (debug_port) + fprintf(stderr, "DEBUG: setting do_inband\n"); + } + } + rem = sock; #else @@ -1185,15 +1232,16 @@ int rcvcnt; int rcvstate; int ppid; +/* returns 1 if flush, 0 otherwise */ -void oob() +int server_message(mark) + int mark; { #ifndef POSIX_TERMIOS int out = FWRITE; #endif - int atmark, n; + int n; int rcvd = 0; - char waste[RLOGIN_BUFSIZ], mark; #ifdef POSIX_TERMIOS struct termios tty; #else @@ -1203,9 +1251,7 @@ void oob() struct sgttyb sb; #endif #endif - mark = 0; - - recv(rem, &mark, 1, MSG_OOB); + if (mark & TIOCPKT_WINDOW) { /* * Let server know about window size changes @@ -1263,27 +1309,62 @@ void oob() (void) ioctl(1, TCFLSH, 1); #endif #endif - for (;;) { - if (ioctl(rem, SIOCATMARK, &atmark) < 0) { - perror("ioctl"); - break; - } - if (atmark) - break; - n = read(rem, waste, sizeof (waste)); - if (n <= 0) - break; -return; - } + return(1); } + + return(0); +} + +void oob() +{ + char mark; + char waste[RLOGIN_BUFSIZ]; + int atmark; + + mark = 0; - + recv(rem, &mark, 1, MSG_OOB); + + if (server_message(mark)) { + if (ioctl(rem, SIOCATMARK, &atmark) < 0) { + perror("ioctl"); + return; + } + if (!atmark) + read(rem, waste, sizeof (waste)); + } } +/* two control messages are defined: + a double flag byte of 'o' indicates a one-byte message which is + identical to what was once carried out of band. + + a double flag byte of 'q' indicates a zero-byte message. This + message is interpreted as two \377 data bytes. This is just a + quote rule so that binary data from the server does not confuse the + client. */ + +int control(cp, n) + unsigned char *cp; + int n; +{ + if ((n >= 5) && (cp[2] == 'o') && (cp[3] == 'o')) { + if (server_message(cp[4])) + return(-5); + return(5); + } else if ((n >= 4) && (cp[2] == 'q') && (cp[3] == 'q')) { + /* this is somewhat of a hack */ + cp[2] = '\377'; + cp[3] = '\377'; + return(2); + } + + return(0); +} /* - * reader: read from remote: line -> 1 + * reader: read from remote: line -> 1 */ reader(oldmask) #ifdef POSIX_SIGNALS @@ -1298,8 +1379,9 @@ reader(oldmask) int pid = -getpid(); #endif fd_set readset, excset, writeset; - int n, remaining; + int n, remaining, left; char *bufp = rcvbuf; + char *cp; #ifdef POSIX_SIGNALS struct sigaction sa; @@ -1326,24 +1408,23 @@ fd_set readset, excset, writeset; #endif /* POSIX_SIGNALS */ for (;;) { - if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) - { + if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { FD_SET(1,&writeset); rcvstate = WRITING; FD_CLR(rem, &readset); + } else { + bufp = rcvbuf; + rcvcnt = 0; + rcvstate = READING; + FD_SET(rem,&readset); + FD_CLR(1,&writeset); } - else { - - bufp = rcvbuf; - rcvcnt = 0; - rcvstate = READING; - FD_SET(rem,&readset); - FD_CLR(1,&writeset); - } - FD_SET(rem,&excset); + if (!do_inband) + FD_SET(rem,&excset); if (select(rem+1, &readset, &writeset, &excset, 0) > 0 ) { - if (FD_ISSET(rem, &excset)) - oob(); + if (!do_inband) + if (FD_ISSET(rem, &excset)) + oob(); if (FD_ISSET(1,&writeset)) { n = write(1, bufp, remaining); if (n < 0) { @@ -1359,6 +1440,30 @@ fd_set readset, excset, writeset; return (0); if (rcvcnt < 0) goto error; + + if (do_inband) { + for (cp = rcvbuf; cp < rcvbuf+rcvcnt-1; cp++) { + if (cp[0] == '\377' && + cp[1] == '\377') { + left = (rcvbuf+rcvcnt) - cp; + n = control(cp, left); + if (n < 0) { + left -= (-n); + rcvcnt = 0; + /* flush before, and (-n) bytes */ + if (left > 0) + memmove(rcvbuf, cp+(-n), left); + cp = rcvbuf-1; + } else if (n) { + left -= n; + rcvcnt -= n; + if (left > 0) + memmove(cp, cp+n, left); + cp--; + } + } + } + } } } else error: diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index bd376ff09..f43389719 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -19,6 +19,32 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef lint char copyright[] = "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ @@ -266,6 +292,7 @@ char *krusername = 0; char term[64]; char rhost_name[128]; krb5_principal client; +int do_inband = 0; int reapchild(); char *progname; @@ -837,6 +864,31 @@ unsigned char oobdata[] = {TIOCPKT_WINDOW}; char oobdata[] = {0}; #endif +int sendoob(fd, byte) + int fd; + char *byte; +{ + char message[5]; + int cc; + + if (do_inband) { + message[0] = '\377'; + message[1] = '\377'; + message[2] = 'o'; + message[3] = 'o'; + message[4] = *byte; + + cc = rcmd_stream_write(fd, message, sizeof(message)); + while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + /* also shouldn't happen */ + sleep(5); + cc = rcmd_stream_write(fd, message, sizeof(message)); + } + } else { + send(fd, byte, 1, MSG_OOB); + } +} + /* * Handle a "control" request (signaled by magic being present) * in the data stream. For now, we are only willing to handle @@ -880,7 +932,7 @@ int control(pty, cp, n) void protocol(f, p) int f, p; { - unsigned char pibuf[BUFSIZ], fibuf[BUFSIZ], *pbp, *fbp; + unsigned char pibuf[BUFSIZ], qpibuf[BUFSIZ*2], fibuf[BUFSIZ], *pbp, *fbp; register pcc = 0, fcc = 0; int cc; char cntl; @@ -915,7 +967,7 @@ void protocol(f, p) signal(SIGTTOU, SIG_IGN); #endif #ifdef TIOCSWINSZ - send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ + sendoob(f, oobdata); #endif for (;;) { fd_set ibits, obits, ebits; @@ -933,7 +985,6 @@ void protocol(f, p) FD_SET(f, &obits); else FD_SET(p, &ibits); - FD_SET(p, &ebits); if (select(8*sizeof(ibits), &ibits, &obits, &ebits, 0) < 0) { if (errno == EINTR) @@ -941,43 +992,32 @@ void protocol(f, p) fatalperror(f, "select"); } #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) - if (FD_ISSET(p, &ebits)) { - cc = read(p, &cntl, 1); - if (cc == 1 && pkcontrol(cntl)) { - cntl |= oobdata[0]; - send(f, &cntl, 1, MSG_OOB); - if (cntl & TIOCPKT_FLUSHWRITE) { - pcc = 0; - FD_CLR(p, &ibits); - } - } - } if (FD_ISSET(f, &ibits)) { fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf)); - if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) - fcc = 0; - else { + if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + fcc = 0; + } else { register unsigned char *cp; int left, n; if (fcc <= 0) - break; + break; fbp = fibuf; - top: - for (cp = fibuf; cp < fibuf+fcc-1; cp++) - if (cp[0] == magic[0] && - cp[1] == magic[1]) { - left = fcc - (cp-fibuf); - n = control(p, cp, left); - if (n) { - left -= n; - if (left > 0) - memmove(cp, cp+n, left); - fcc -= n; - goto top; /* n^2 */ - } - } + for (cp = fibuf; cp < fibuf+fcc-1; cp++) { + if (cp[0] == magic[0] && + cp[1] == magic[1]) { + left = (fibuf+fcc) - cp; + n = control(p, cp, left); + if (n) { + left -= n; + fcc -= n; + if (left > 0) + memmove(cp, cp+n, left); + cp--; + } + } + } } } @@ -992,24 +1032,54 @@ void protocol(f, p) if (FD_ISSET(p, &ibits)) { pcc = read(p, pibuf, sizeof (pibuf)); pbp = pibuf; - if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) - pcc = 0; - else if (pcc <= 0) - break; + if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + pcc = 0; + } else if (pcc <= 0) { + break; + } #ifdef TIOCPKT else if (tiocpkt_on) { - if (pibuf[0] == 0) - pbp++, pcc--; - else { - if (pkcontrol(pibuf[0])) { - pibuf[0] |= oobdata[0]; - send(f, &pibuf[0], 1, MSG_OOB); - } - pcc = 0; - } + if (pibuf[0] == 0) { + pbp++, pcc--; + } else { + if (pkcontrol(pibuf[0])) { + pibuf[0] |= oobdata[0]; + sendoob(f, pibuf); + } + pcc = 0; + } } #endif + + /* quote any double-\377's if necessary */ + + if (do_inband) { + unsigned char *qpbp; + int qpcc, i; + + qpbp = qpibuf; + qpcc = 0; + + for (i=0; i 0) { cc = rcmd_stream_write(f, pbp, pcc); if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { @@ -1411,6 +1481,21 @@ recvauth(valid_checksum) rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 1); + { + krb5_boolean similar; + + if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, + ticket->enc_part2->session->enctype, + &similar)) + return(status); + + if (!similar) { + do_inband = 1; + syslog(LOG_DEBUG, "setting do_inband"); + } + } + + getstr(netf, rusername, sizeof(rusername), "remuser"); if ((status = krb5_unparse_name(bsd_context, client, &krusername))) diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c index cb18f4c2c..c8017cc77 100644 --- a/src/appl/bsd/login.c +++ b/src/appl/bsd/login.c @@ -48,6 +48,7 @@ char copyright[] = */ #define KRB5_GET_TICKETS int login_krb5_get_tickets = 1; + #ifdef KRB5_KRB4_COMPAT #define KRB4_GET_TICKETS int login_krb4_get_tickets = 0; @@ -56,6 +57,7 @@ int login_krb4_convert = 0; #define KRB_RUN_AKLOG int login_krb_run_aklog = 0; #endif /* KRB5_KRB4_COMPAT */ + int login_accept_passwd = 0; /* @@ -189,10 +191,10 @@ typedef sigtype (*handler)(); #ifndef HAVE_KRB_GET_ERR_TEXT -static const char * krb_get_err_text(kerror) - int kerror; +static const char *krb_get_err_text(kerror) + int kerror; { - return krb_err_txt[kerror]; + return krb_err_txt[kerror]; } #endif /*HAVE_KRB_GET_ERR_TEXT*/ @@ -326,52 +328,58 @@ typedef krb5_sigtype sigtype; #ifndef HAVE_INITGROUPS static int initgroups(char* name, gid_t basegid) { - gid_t others[NGROUPS_MAX+1]; - int ngrps; + gid_t others[NGROUPS_MAX+1]; + int ngrps; - others[0] = basegid; - ngrps = getgroups(NGROUPS_MAX, others+1); - return setgroups(ngrps+1, others); + others[0] = basegid; + ngrps = getgroups(NGROUPS_MAX, others+1); + return setgroups(ngrps+1, others); } #endif -#ifdef KRB5_GET_TICKETS static struct login_confs { - char *flagname; - int *flag; + char *flagname; + int *flag; } login_conf_set[] = { - "krb5_get_tickets", &login_krb5_get_tickets, +#ifdef KRB5_GET_TICKETS + "krb5_get_tickets", &login_krb5_get_tickets, +#endif #ifdef KRB5_KRB4_COMPAT - "krb4_get_tickets", &login_krb4_get_tickets, - "krb4_convert", &login_krb4_convert, - "krb4_run_aklog", &login_krb_run_aklog, + "krb4_get_tickets", &login_krb4_get_tickets, + "krb4_convert", &login_krb4_convert, + "krb4_run_aklog", &login_krb_run_aklog, #endif /* KRB5_KRB4_COMPAT */ }; + static char *conf_yes[] = { - "y", "yes", "true", "t", "1", "on", - 0 + "y", "yes", "true", "t", "1", "on", + 0 }; + static char *conf_no[] = { - "n", "no", "false", "nil", "0", "off", - 0 + "n", "no", "false", "nil", "0", "off", + 0 }; + /* 1 = true, 0 = false, -1 = ambiguous */ static int conf_affirmative(s) - char *s; + char *s; { - char **p; - for(p=conf_yes; *p; p++) { - if (!strcasecmp(*p,s)) - return 1; - } - for(p=conf_no; *p; p++) { - if (!strcasecmp(*p,s)) - return 0; - } - /* ambiguous */ - return -1; + char **p; + + for(p=conf_yes; *p; p++) { + if (!strcasecmp(*p,s)) + return 1; + } + + for(p=conf_no; *p; p++) { + if (!strcasecmp(*p,s)) + return 0; + } + + /* ambiguous */ + return -1; } -#endif /* KRB5_GET_TICKETS */ #ifdef KRB5_GET_TICKETS krb5_data tgtname = { @@ -381,46 +389,43 @@ krb5_data tgtname = { }; #endif -#ifdef KRB5_GET_TICKETS /* get flags (listed above) from the profile */ void login_get_kconf(k) - krb5_context k; + krb5_context k; { - int i, max_i; - const char* kconf_names[3]; - char **kconf_val; - int retval; - - max_i = sizeof(login_conf_set)/sizeof(struct login_confs); - for (i = 0; iprofile, - kconf_names, &kconf_val); - if (retval) { - /* ignore most (all?) errors */ - } else if (kconf_val) { - switch(conf_affirmative(*kconf_val)) { - case 1: - *login_conf_set[i].flag = 1; - break; - case 0: - *login_conf_set[i].flag = 0; - break; - default: - case -1: - com_err("login/kconf", 0, - "invalid flag value %s for flag %s", - *kconf_val, kconf_names[1]); - break; - } - } + int i, max_i; + const char* kconf_names[3]; + char **kconf_val; + int retval; + + max_i = sizeof(login_conf_set)/sizeof(struct login_confs); + for (i = 0; iprofile, + kconf_names, &kconf_val); + if (retval) { + /* ignore most (all?) errors */ + } else if (kconf_val) { + switch(conf_affirmative(*kconf_val)) { + case 1: + *login_conf_set[i].flag = 1; + break; + case 0: + *login_conf_set[i].flag = 0; + break; + default: + case -1: + com_err("login/kconf", 0, + "invalid flag value %s for flag %s", + *kconf_val, kconf_names[1]); + break; + } } + } } -#endif /* KRB5_GET_TICKETS */ - /* UNIX password support */ struct passwd *pwd; @@ -475,16 +480,19 @@ int unix_passwd_okay (pass) #endif return !strcmp (namep, pwd->pw_passwd); } - + /* Kerberos support */ #ifdef KRB5_GET_TICKETS krb5_context kcontext; krb5_ccache ccache; -static int got_v5_tickets, got_v4_tickets; +krb5_creds my_creds; +static int got_v5_tickets, forwarded_v5_tickets; char ccfile[MAXPATHLEN+6]; /* FILE:path+\0 */ int krbflag; /* set if tickets have been obtained */ +#endif /* KRB5_GET_TICKETS */ #ifdef KRB4_GET_TICKETS +static int got_v4_tickets; AUTH_DAT *kdata = (AUTH_DAT *) NULL; KTEXT ticket = (KTEXT) NULL; char tkfile[MAXPATHLEN]; @@ -494,6 +502,7 @@ char realm[REALM_SZ]; void k_init (ttyn) char *ttyn; { +#ifdef KRB5_GET_TICKETS krb5_error_code retval; retval = krb5_init_context(&kcontext); @@ -501,6 +510,7 @@ void k_init (ttyn) com_err("login", retval, "while initializing krb5"); exit(1); } + krb5_secure_config_files (kcontext); login_get_kconf(kcontext); @@ -514,6 +524,7 @@ void k_init (ttyn) strncpy(ccfile, getenv(KRB5_ENV_CCNAME), sizeof(ccfile)); ccfile[sizeof(ccfile) - 1] = '\0'; } +#endif #ifdef KRB4_GET_TICKETS if (krb_get_lrealm(realm, 1) != KSUCCESS) { @@ -539,6 +550,7 @@ void k_init (ttyn) #endif /* BIND_HACK */ } +#ifdef KRB5_GET_TICKETS int k5_get_password (user_pwstring, pwsize) char *user_pwstring; { @@ -561,76 +573,23 @@ int k5_get_password (user_pwstring, pwsize) return 1; } -#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ -int krb5_options = 0; -krb5_deltat krb5_ticket_lifetime = KRB5_DEFAULT_LIFE; - int try_krb5 (me_p, pass) krb5_principal *me_p; char *pass; { krb5_error_code code; - krb5_principal server, me; - krb5_creds my_creds; - krb5_timestamp now; - krb5_deltat lifetime = krb5_ticket_lifetime; - - /* set up credential cache -- obeying KRB5_ENV_CCNAME - set earlier */ - /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */ - if ((code = krb5_cc_default(kcontext, &ccache))) { - com_err("login", code, "while getting default ccache"); - return 0; - } - /* setup code from v5 kinit */ - memset((char *)&my_creds, 0, sizeof(my_creds)); + krb5_principal me; - code = krb5_parse_name (kcontext, username, &me); - if (code) { + if (code = krb5_parse_name(kcontext, username, &me)) { com_err ("login", code, "when parsing name %s",username); return 0; } - *me_p = my_creds.client = me; - code = krb5_cc_initialize (kcontext, ccache, me); - if (code) { - com_err ("login", code, - "when initializing cache"); - return 0; - } + *me_p = me; - code = krb5_build_principal_ext(kcontext, &server, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - tgtname.length, tgtname.data, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - 0); - if (code) { - com_err("login", code, - "while building server name"); - goto nuke_ccache; - } - - my_creds.server = server; - code = krb5_timeofday(kcontext, &now); - if (code) { - com_err("login", code, - "while getting time of day"); - goto nuke_ccache; - } - my_creds.times.starttime = 0; /* start timer when - request gets to KDC */ - my_creds.times.endtime = now + lifetime; - my_creds.times.renew_till = 0; - - code = krb5_get_in_tkt_with_password(kcontext, krb5_options, - 0, NULL, 0 /*preauth*/, - pass, - ccache, - &my_creds, 0); - - if (code) { + if (code = krb5_get_init_creds_password(kcontext, &my_creds, me, pass, + krb5_prompter_posix, NULL, + 0, NULL, NULL)) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) fprintf (stderr, "%s: Kerberos password incorrect\n", @@ -638,17 +597,12 @@ int try_krb5 (me_p, pass) else com_err ("login", code, "while getting initial credentials"); - nuke_ccache: - krb5_cc_destroy (kcontext, ccache); return 0; - } else { - /* get_name pulls out just the name not the - type */ - strncpy(ccfile, krb5_cc_get_name(kcontext, ccache), sizeof(ccfile)); - ccfile[sizeof(ccfile) - 1] = '\0'; - krbflag = got_v5_tickets = 1; - return 1; } + + krbflag = got_v5_tickets = 1; + + return 1; } int have_v5_tickets (me) @@ -663,6 +617,7 @@ int have_v5_tickets (me) krbflag = 1; return 1; } +#endif /* KRB5_GET_TICKETS */ #ifdef KRB4_CONVERT try_convert524 (kcontext, me) @@ -675,8 +630,6 @@ try_convert524 (kcontext, me) krb5_creds increds, *v5creds; CREDENTIALS v4creds; - if (!got_v5_tickets) - return 0; /* or do this directly with krb524_convert_creds_kdc */ krb524_init_ets(kcontext); @@ -886,162 +839,23 @@ EGRESS: } #endif /* KRB4_GET_TICKETS */ -/* call already conditionalized on login_krb5_get_tickets */ -/* - * Verify the Kerberos ticket-granting ticket just retrieved for the - * user. If the Kerberos server doesn't respond, assume the user is - * trying to fake us out (since we DID just get a TGT from what is - * supposedly our KDC). If the host/ service is unknown (i.e., - * the local keytab doesn't have it), let her in. - * - * Returns 1 for confirmation, -1 for failure, 0 for uncertainty. - */ -int verify_krb_v5_tgt (c) - krb5_context c; +void destroy_tickets() { - char phost[BUFSIZ]; - krb5_ccache ccdef; - int retval, have_keys; - krb5_principal princ; - krb5_keyblock *kb = 0; - krb5_error_code krbval; - krb5_data packet; - krb5_auth_context auth_context = NULL; - krb5_ticket *ticket = NULL; - - /* XXX This is to work around a library bug. I'm not sure if it's - been fixed for beta-7, so leave this in for now. Remove it (and - fix the bug if necessary) after beta-7 ships. - - Whoever wrote that comment didn't mention what the bug is! Ted - says it is something about the starttime of the ticket and - "now" being equal. He thinks it is fixed, but isn't sure. - */ - sleep(2); - - /* get the server principal for the local host */ - /* (use defaults of "host" and canonicalized local name) */ - krbval = krb5_sname_to_principal(c, 0, 0, KRB5_NT_SRV_HST, &princ); - if (krbval) { - com_err ("login", krbval, "constructing local service name"); - return -1; - } +#ifdef KRB5_GET_TICKETS + krb5_ccache cache; + krb5_error_code retval; - /* since krb5_sname_to_principal has done the work for us, just - extract the name directly */ - strncpy(phost, krb5_princ_component(c, princ, 1)->data, sizeof(phost)); - phost[sizeof(phost) - 1] = '\0'; - - /* Do we have host/ keys? */ - /* (use default keytab, kvno IGNORE_VNO to get the first match, - and enctype is currently ignored anyhow.) */ - krbval = krb5_kt_read_service_key (c, NULL, princ, 0, ENCTYPE_DES_CBC_CRC, &kb); - if (kb) - krb5_free_keyblock (c, kb); - /* any failure means we don't have keys at all. */ - have_keys = krbval ? 0 : 1; - - /* set up credential cache -- obeying KRB5_ENV_CCNAME set earlier */ - /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */ - if (krbval = krb5_cc_default(c, &ccdef)) { - com_err("login", krbval, "while getting default ccache"); - return -1; - } - /* talk to the kdc and construct the ticket */ - krbval = krb5_mk_req(c, &auth_context, 0, "host", phost, - 0, ccdef, &packet); - /* wipe the auth context for mk_req */ - if (auth_context) { - krb5_auth_con_free(c, auth_context); - auth_context = NULL; - } - if (krbval == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) { - /* we have a service key, so something should be - in the database, therefore this error packet could - have come from an attacker. */ - if (have_keys) { retval = -1; goto EGRESS; } - /* but if it is unknown and we've got no key, we don't - have any security anyhow, so it is ok. */ - else { retval = 0; goto EGRESS; } - } - else if (krbval) { - com_err("login", krbval, - "Unable to verify Kerberos V5 TGT: %s", phost); -#ifndef SYSLOG42 - syslog (LOG_NOTICE|LOG_AUTH, "Kerberos V5 TGT bad: %s", - error_message(krbval)); -#endif - retval = -1; - goto EGRESS; - } - /* got ticket, try to use it */ - krbval = krb5_rd_req(c, &auth_context, &packet, - princ, NULL, NULL, &ticket); - if (krbval) { - if (!have_keys) - /* The krb5 errors aren't specified well, but I think - these values cover the cases we expect. */ - switch (krbval) { - /* no keytab */ - case ENOENT: - /* keytab found, missing entry */ -#if 0 /* Don't depend on the nameserver for security. Assume that if - we have a keytab, it must contain the right host/FQDN key. */ - case KRB5_KT_NOTFOUND: -#endif - retval = 0; - break; - default: - /* unexpected error: fail */ - retval = -1; - break; - } - else - /* Any error here is bad. */ - retval = -1; - com_err("login", krbval, "Unable to verify host ticket"); -#ifndef SYSLOG42 - syslog (LOG_NOTICE|LOG_AUTH, "can't verify v5 ticket: %s; %s\n", - error_message(krbval), - retval - ? "keytab found, assuming failure" - : "no keytab found, assuming success"); -#endif - goto EGRESS; + if (login_krb5_get_tickets) { + if(!krb5_cc_default(kcontext, &cache)) + krb5_cc_destroy (kcontext, cache); } - /* - * The host/ ticket has been received _and_ verified. - */ - retval = 1; - /* do cleanup and return */ -EGRESS: - if (auth_context) krb5_auth_con_free(c, auth_context); - krb5_free_principal(c, princ); - /* possibly ticket and packet need freeing here as well */ - /* memset (&ticket, 0, sizeof (ticket)); */ - return retval; -} - -destroy_tickets() -{ - krb5_context c; - krb5_ccache cache; - krb5_error_code retval; - -#ifdef KRB5_GET_TICKETS - if (login_krb5_get_tickets) { - if(!krb5_cc_default(kcontext, &cache)) - krb5_cc_destroy (kcontext, cache); - } #endif #ifdef KRB4_GET_TICKETS - if (login_krb4_get_tickets||login_krb4_convert) + if (login_krb4_get_tickets || login_krb4_convert) dest_tkt(); #endif /* KRB4_GET_TICKETS */ } -#endif /* KRB5_GET_TICKETS */ - /* AFS support routines */ #ifdef SETPAG @@ -1086,15 +900,13 @@ static int try_afscall (scall) void afs_login () { -#ifdef KRB4_GET_TICKETS -#ifdef SETPAG +#if defined(KRB4_GET_TICKETS) && defined(SETPAG) if (login_krb4_get_tickets && pwd->pw_uid) { /* Only reset the pag for non-root users. */ /* This allows root to become anything. */ pagflag = try_setpag (); } #endif -#endif /* KRB4_GET_TICKETS */ #ifdef KRB_RUN_AKLOG if (got_v4_tickets && login_krb_run_aklog) { /* KPROGDIR is $(prefix)/bin */ @@ -1120,19 +932,19 @@ afs_cleanup () try_unlog (); #endif } - + /* Main routines */ #define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag || fflag ) { \ - fprintf(stderr, \ - "login: only one of -r, -k, -K, -e, -F, and -f allowed.\n"); \ - exit(1);\ - } + fprintf(stderr, \ + "login: only one of -r, -k, -K, -e, -F, and -f allowed.\n"); \ + exit(1); \ +} #define EXCL_HOST_TEST if (rflag || kflag || Kflag || hflag) { \ - fprintf(stderr, \ - "login: only one of -r, -k, -K, and -h allowed.\n"); \ - exit(1);\ - } + fprintf(stderr, \ + "login: only one of -r, -k, -K, and -h allowed.\n"); \ + exit(1); \ +} static void read_env_vars_from_file (filename) @@ -1142,7 +954,7 @@ read_env_vars_from_file (filename) char *p, *eq; char tbuf[MAXPATHLEN+2]; - if ((fp = fopen("/etc/environment", "r")) != NULL) { + if ((fp = fopen(filename, "r")) != NULL) { while (fgets(tbuf, sizeof(tbuf), fp)) { if (tbuf[0] == '#') continue; @@ -1176,467 +988,480 @@ log_repeated_failures (tty, hostname) tty, hostname, UT_NAMESIZE, username); #endif - } - else + } else { syslog(LOG_ERR, "REPEATED LOGIN FAILURES ON %s, %.*s", tty, UT_NAMESIZE, username); + } } int main(argc, argv) - int argc; - char **argv; + int argc; + char **argv; { - extern int optind; - extern char *optarg, **environ; - struct group *gr; - int ch; - char *p; - int fflag, hflag, pflag, rflag, cnt; - int kflag, Kflag, eflag; - int quietlog, passwd_req, ioctlval; - sigtype timedout(); - char *domain, **envinit, *ttyn, *tty; - char tbuf[MAXPATHLEN + 2]; - char *ttyname(), *stypeof(), *crypt(), *getpass(); - time_t login_time; - int retval; -int rewrite_ccache = 1; /*try to write out ccache*/ + extern int optind; + extern char *optarg, **environ; + struct group *gr; + int ch; + char *p; + int fflag, hflag, pflag, rflag, cnt; + int kflag, Kflag, eflag; + int quietlog, passwd_req, ioctlval; + sigtype timedout(); + char *domain, **envinit, *ttyn, *tty; + char tbuf[MAXPATHLEN + 2]; + char *ttyname(), *stypeof(), *crypt(), *getpass(); + time_t login_time; + int retval; + int rewrite_ccache = 1; /*try to write out ccache*/ #ifdef KRB5_GET_TICKETS - krb5_principal me; - krb5_creds save_v5creds; + krb5_principal me; + krb5_creds save_v5creds; + krb5_ccache xtra_creds = NULL; #endif #ifdef KRB4_GET_TICKETS - CREDENTIALS save_v4creds; + CREDENTIALS save_v4creds; #endif - char *ccname = 0; /* name of forwarded cache */ - char *tz = 0; + char *ccname = 0; /* name of forwarded cache */ + char *tz = 0; - off_t lseek(); - handler sa; + off_t lseek(); + handler sa; - handler_init (sa, timedout); - handler_set (SIGALRM, sa); - (void)alarm((u_int)timeout); + handler_init (sa, timedout); + handler_set (SIGALRM, sa); + (void)alarm((u_int)timeout); - handler_init (sa, SIG_IGN); - handler_set (SIGQUIT, sa); - handler_set (SIGINT, sa); - setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); + handler_init (sa, SIG_IGN); + handler_set (SIGQUIT, sa); + handler_set (SIGINT, sa); + setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); #ifdef OQUOTA - (void)quota(Q_SETUID, 0, 0, 0); + (void)quota(Q_SETUID, 0, 0, 0); #endif - /* - * -p is used by getty to tell login not to destroy the environment - * -r is used by rlogind to cause the autologin protocol; - * -f is used to skip a second login authentication - * -F is used to skip a second login authentication, allows login as root - * -e is used to skip a second login authentication, but allows - * login as root. - * -h is used by other servers to pass the name of the - * remote host to login so that it may be placed in utmp and wtmp - * -k is used by klogind to cause the Kerberos V4 autologin protocol; - * -K is used by klogind to cause the Kerberos V4 autologin - * protocol with restricted access. - */ - (void)gethostname(tbuf, sizeof(tbuf)); - domain = strchr(tbuf, '.'); - - fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0; - passwd_req = 1; - while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:")) != -1) - switch (ch) { - case 'f': - EXCL_AUTH_TEST; - fflag = 1; - break; - case 'F': - EXCL_AUTH_TEST; - fflag = 1; - break; - case 'h': - EXCL_HOST_TEST; - if (getuid()) { - fprintf(stderr, - "login: -h for super-user only.\n"); - exit(1); - } - hflag = 1; - if (domain && (p = strchr(optarg, '.')) && - strcmp(p, domain) == 0) - *p = 0; - hostname = optarg; - break; - case 'p': - pflag = 1; - break; - case 'r': - EXCL_AUTH_TEST; - EXCL_HOST_TEST; - if (getuid()) { - fprintf(stderr, - "login: -r for super-user only.\n"); - exit(1); - } - /* "-r hostname" must be last args */ - if (optind != argc) { - fprintf(stderr, "Syntax error.\n"); - exit(1); - } - rflag = 1; - passwd_req = (doremotelogin(optarg) == -1); - if (domain && (p = strchr(optarg, '.')) && - !strcmp(p, domain)) - *p = '\0'; - hostname = optarg; - break; + /* + * -p is used by getty to tell login not to destroy the environment + * -r is used by rlogind to cause the autologin protocol; + * -f is used to skip a second login authentication + * -F is used to skip a second login authentication, allows login as root + * -e is used to skip a second login authentication, but allows + * login as root. + * -h is used by other servers to pass the name of the + * remote host to login so that it may be placed in utmp and wtmp + * -k is used by klogind to cause the Kerberos V4 autologin protocol; + * -K is used by klogind to cause the Kerberos V4 autologin + * protocol with restricted access. + */ + (void)gethostname(tbuf, sizeof(tbuf)); + domain = strchr(tbuf, '.'); + + fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0; + passwd_req = 1; + while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:")) != -1) + switch (ch) { + case 'f': + EXCL_AUTH_TEST; + fflag = 1; + break; + case 'F': + EXCL_AUTH_TEST; + fflag = 1; + break; + case 'h': + EXCL_HOST_TEST; + if (getuid()) { + fprintf(stderr, + "login: -h for super-user only.\n"); + exit(1); + } + hflag = 1; + if (domain && (p = strchr(optarg, '.')) && strcmp(p, domain) == 0) + *p = 0; + hostname = optarg; + break; + case 'p': + pflag = 1; + break; + case 'r': + EXCL_AUTH_TEST; + EXCL_HOST_TEST; + if (getuid()) { + fprintf(stderr, + "login: -r for super-user only.\n"); + exit(1); + } + /* "-r hostname" must be last args */ + if (optind != argc) { + fprintf(stderr, "Syntax error.\n"); + exit(1); + } + rflag = 1; + passwd_req = (doremotelogin(optarg) == -1); + if (domain && (p = strchr(optarg, '.')) && !strcmp(p, domain)) + *p = '\0'; + hostname = optarg; + break; #ifdef KRB4_KLOGIN - case 'k': - case 'K': - EXCL_AUTH_TEST; - EXCL_HOST_TEST; - if (getuid()) { - fprintf(stderr, - "login: -%c for super-user only.\n", ch); - exit(1); - } - /* "-k hostname" must be last args */ - if (optind != argc) { - fprintf(stderr, "Syntax error.\n"); - exit(1); - } - if (ch == 'K') - Kflag = 1; - else - kflag = 1; - passwd_req = (do_krb_login(optarg, - Kflag ? 1 : 0) == -1); - if (domain && (p = strchr(optarg, '.')) && - !strcmp(p, domain)) - *p = '\0'; - hostname = optarg; - break; + case 'k': + case 'K': + EXCL_AUTH_TEST; + EXCL_HOST_TEST; + if (getuid()) { + fprintf(stderr, + "login: -%c for super-user only.\n", ch); + exit(1); + } + /* "-k hostname" must be last args */ + if (optind != argc) { + fprintf(stderr, "Syntax error.\n"); + exit(1); + } + if (ch == 'K') + Kflag = 1; + else + kflag = 1; + passwd_req = (do_krb_login(optarg, Kflag ? 1 : 0) == -1); + if (domain && + (p = strchr(optarg, '.')) && + (!strcmp(p, domain))) + *p = '\0'; + hostname = optarg; + break; #endif /* KRB4_KLOGIN */ - case 'e': - EXCL_AUTH_TEST; - if (getuid()) { - fprintf(stderr, - "login: -e for super-user only.\n"); - exit(1); - } - eflag = 1; - passwd_req = 0; - break; - case '?': - default: - fprintf(stderr, "usage: login [-fp] [username]\n"); - exit(1); - } - argc -= optind; - argv += optind; - if (*argv) - username = *argv; + case 'e': + EXCL_AUTH_TEST; + if (getuid()) { + fprintf(stderr, + "login: -e for super-user only.\n"); + exit(1); + } + eflag = 1; + passwd_req = 0; + break; + case '?': + default: + fprintf(stderr, "usage: login [-fp] [username]\n"); + exit(1); + } + argc -= optind; + argv += optind; + if (*argv) + username = *argv; #if !defined(POSIX_TERMIOS) && defined(TIOCLSET) - ioctlval = 0; - /* Only do this we we're not using POSIX_TERMIOS */ - (void)ioctl(0, TIOCLSET, (char *)&ioctlval); + ioctlval = 0; + /* Only do this we we're not using POSIX_TERMIOS */ + (void)ioctl(0, TIOCLSET, (char *)&ioctlval); #endif #ifdef TIOCNXCL - (void)ioctl(0, TIOCNXCL, (char *)0); + (void)ioctl(0, TIOCNXCL, (char *)0); #endif - ioctlval = fcntl(0, F_GETFL); + ioctlval = fcntl(0, F_GETFL); #ifdef O_NONBLOCK - ioctlval &= ~O_NONBLOCK; + ioctlval &= ~O_NONBLOCK; #endif #ifdef O_NDELAY - ioctlval &= ~O_NDELAY; + ioctlval &= ~O_NDELAY; #endif - (void)fcntl(0, F_SETFL, ioctlval); + (void)fcntl(0, F_SETFL, ioctlval); /* * If talking to an rlogin process, propagate the terminal type and * baud rate across the network. */ - if (eflag) - lgetstr(term, sizeof(term), "Terminal type"); - else if (!(kflag || Kflag )) /*Preserve terminal if not read over net */ - { - if (getenv("TERM")) { - strncpy(term, getenv("TERM"), sizeof(term)); - term[sizeof(term) - 1] = '\0'; - } - } + if (eflag) { + lgetstr(term, sizeof(term), "Terminal type"); + } else if (!(kflag || Kflag)) {/* Preserve terminal if not read over net */ + if (getenv("TERM")) { + strncpy(term, getenv("TERM"), sizeof(term)); + term[sizeof(term) - 1] = '\0'; + } + } - term_init (rflag || kflag || Kflag || eflag); + term_init (rflag || kflag || Kflag || eflag); - for (cnt = getdtablesize(); cnt > 2; cnt--) - (void) close(cnt); + for (cnt = getdtablesize(); cnt > 2; cnt--) + (void) close(cnt); - ttyn = ttyname(0); - if (ttyn == NULL || *ttyn == '\0') - ttyn = "/dev/tty??"; + ttyn = ttyname(0); + if (ttyn == NULL || *ttyn == '\0') + ttyn = "/dev/tty??"; - /* This allows for tty names of the form /dev/pts/4 as well */ - if ((tty = strchr(ttyn, '/')) && (tty = strchr(tty+1, '/'))) - ++tty; - else - tty = ttyn; + /* This allows for tty names of the form /dev/pts/4 as well */ + if ((tty = strchr(ttyn, '/')) && (tty = strchr(tty+1, '/'))) + ++tty; + else + tty = ttyn; #ifndef LOG_ODELAY /* 4.2 syslog ... */ - openlog("login", 0); + openlog("login", 0); #else - openlog("login", LOG_ODELAY, LOG_AUTH); + openlog("login", LOG_ODELAY, LOG_AUTH); #endif /* 4.2 syslog */ /******* begin askpw *******/ - /* overall: - ask for username if we don't have it already - look it up in local pw or shadow file (to get crypt string) - ask for password - try and get v4, v5 tickets with it - try and use the tickets against the local srvtab - if the password matches, always let them in - if the ticket decrypts, let them in. - v5 needs to work, does v4? - */ - + /* overall: + ask for username if we don't have it already + look it up in local pw or shadow file (to get crypt string) + ask for password + try and get v4, v5 tickets with it + try and use the tickets against the local srvtab + if the password matches, always let them in + if the ticket decrypts, let them in. + v5 needs to work, does v4? + */ + + k_init (ttyn); + + for (cnt = 0;; username = NULL) { #ifdef KRB5_GET_TICKETS - k_init (ttyn); -#endif - - for (cnt = 0;; username = NULL) { -#ifdef KRB5_GET_TICKETS - int kpass_ok,lpass_ok; - char user_pwstring[MAXPWSIZE]; - /* variables from v5 kinit */ + int kpass_ok, lpass_ok; + char user_pwstring[MAXPWSIZE]; #endif /* KRB5_GET_TICKETS */ - if (username == NULL) { - fflag = 0; - getloginname(); - } - - lookup_user (username); /* sets pwd */ - - /* if user not super-user, check for disabled logins */ - if (pwd == NULL || pwd->pw_uid) - checknologin(); + if (username == NULL) { + fflag = 0; + getloginname(); + } - /* - * Allows automatic login by root. - * If not invoked by root, disallow if the uid's differ. - */ + lookup_user(username); /* sets pwd */ - if (fflag && pwd) { - int uid = (int) getuid(); - passwd_req = (uid && uid != pwd->pw_uid); - } + /* if user not super-user, check for disabled logins */ + if (pwd == NULL || pwd->pw_uid) + checknologin(); - /* - * If no remote login authentication and a password exists - * for this user, prompt for one and verify it. - */ - if (!passwd_req) - break; + /* + * Allows automatic login by root. + * If not invoked by root, disallow if the uid's differ. + */ - if (! unix_needs_passwd ()) - break; + if (fflag && pwd) { + int uid = (int) getuid(); + passwd_req = (uid && uid != pwd->pw_uid); + } - /* we have several sets of code: - 1) get v5 tickets alone -DKRB5_GET_TICKETS - 2) get v4 tickets alone [** don't! only get them *with* v5 **] - 3) get both tickets -DKRB5_GET_TICKETS -DKRB4_GET_TICKETS - 3a) use krb524 calls to get the v4 tickets -DKRB4_CONVERT plus (3). - 4) get no tickets and use the password file (none of thes defined.) + /* + * If no remote login authentication and a password exists + * for this user, prompt for one and verify it. + */ + if (!passwd_req) + break; + + if (!unix_needs_passwd()) + break; + + /* we have several sets of code: + 1) get v5 tickets alone -DKRB5_GET_TICKETS + 2) get v4 tickets alone [** don't! only get them *with* v5 **] + 3) get both tickets -DKRB5_GET_TICKETS -DKRB4_GET_TICKETS + 3a) use krb524 calls to get the v4 tickets -DKRB4_CONVERT plus (3). + 4) get no tickets and use the password file (none of thes defined.) - Likewise we need to (optionally?) test these tickets against local srvtabs. - */ + Likewise we need to (optionally?) test these tickets against + local srvtabs. + */ + #ifdef KRB5_GET_TICKETS - if (login_krb5_get_tickets) { - /* rename these to something more verbose */ - kpass_ok = 0; - lpass_ok = 0; - - setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET); - if (! k5_get_password (user_pwstring, sizeof (user_pwstring))) { - goto bad_login; - } + if (login_krb5_get_tickets) { + /* rename these to something more verbose */ + kpass_ok = 0; + lpass_ok = 0; - /* now that we have the password, we've obscured things - sufficiently, and can avoid trying tickets */ - if (!pwd) - goto bad_login; + setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET); + if (! k5_get_password(user_pwstring, sizeof (user_pwstring))) { + goto bad_login; + } + + /* now that we have the password, we've obscured things + sufficiently, and can avoid trying tickets */ + if (!pwd) + goto bad_login; - lpass_ok = unix_passwd_okay (user_pwstring); + lpass_ok = unix_passwd_okay(user_pwstring); - if (pwd->pw_uid != 0) { /* Don't get tickets for root */ - try_krb5 (&me, user_pwstring); + if (pwd->pw_uid != 0) { /* Don't get tickets for root */ + try_krb5(&me, user_pwstring); #ifdef KRB4_GET_TICKETS - if (login_krb4_get_tickets - && (!got_v5_tickets - || !login_krb4_convert)) - try_krb4 (me, user_pwstring); + if (login_krb4_get_tickets && + !(got_v5_tickets && login_krb4_convert)) + try_krb4(me, user_pwstring); +#endif + krbflag = (got_v5_tickets +#ifdef KRB4_GET_TICKETS + || got_v4_tickets #endif - krbflag = got_v5_tickets || got_v4_tickets; - memset (user_pwstring, 0, sizeof(user_pwstring)); - /* password wiped, so we can relax */ - setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); + ); + memset (user_pwstring, 0, sizeof(user_pwstring)); + /* password wiped, so we can relax */ + setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); + } else { + memset(user_pwstring, 0, sizeof(user_pwstring)); + setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); + } + + /* Policy: If local password is good, user is good. + We really can't trust the Kerberos password, + because somebody on the net could spoof the + Kerberos server (not easy, but possible). + Some sites might want to use it anyways, in + which case they should change this line + to: + if (kpass_ok) + */ + + if (lpass_ok) + break; + if (got_v5_tickets) { + if (retval = krb5_verify_init_creds(kcontext, &my_creds, NULL, + NULL, &xtra_creds, + NULL)) { + com_err("login", retval, "while verifying initial ticket"); +#ifndef SYSLOG42 + syslog(LOG_NOTICE|LOG_AUTH, + "can't verify v5 ticket: %s\n", + error_message(retval)); +#endif } else { - memset (user_pwstring, 0, sizeof(user_pwstring)); - setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); + break; /* we're ok */ } - - /* Policy: If local password is good, user is good. - We really can't trust the Kerberos password, - because somebody on the net could spoof the - Kerberos server (not easy, but possible). - Some sites might want to use it anyways, in - which case they should change this line - to: - if (kpass_ok) - */ - if (lpass_ok) - break; - if (got_v5_tickets - && verify_krb_v5_tgt(kcontext) != -1) - break; /* we're ok */ + } #ifdef KRB4_GET_TICKETS - if (login_krb4_get_tickets) { - if (got_v4_tickets - && ! got_v5_tickets - && verify_krb_v4_tgt(realm) != -1) - break; /* we're ok */ - } + else if (got_v4_tickets) { + if (login_krb4_get_tickets && + (verify_krb_v4_tgt(realm) != -1)) + break; /* we're ok */ + } #endif /* KRB4_GET_TICKETS */ + bad_login: - setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); - if (krbflag) - destroy_tickets(); /* clean up tickets if login fails */ + setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); - } + if (krbflag) + destroy_tickets(); /* clean up tickets if login fails */ + } #endif /* KRB5_GET_TICKETS */ + #ifdef OLD_PASSWD - p = getpass ("Password:"); - /* conventional password only */ - if (unix_passwd_okay (p)) - break; + p = getpass ("Password:"); + /* conventional password only */ + if (unix_passwd_okay (p)) + break; #endif /* OLD_PASSWD */ - printf("Login incorrect\n"); - if (++cnt >= 5) { - log_repeated_failures (tty, hostname); -/* irix has no tichpcl */ + printf("Login incorrect\n"); + if (++cnt >= 5) { + log_repeated_failures (tty, hostname); + /* irix has no tichpcl */ #ifdef TIOCHPCL - (void)ioctl(0, TIOCHPCL, (char *)0); + (void)ioctl(0, TIOCHPCL, (char *)0); #endif - sleepexit(1); - } - } /* end of password retry loop */ + sleepexit(1); + } + } /* end of password retry loop */ - /* committed to login -- turn off timeout */ - (void)alarm((u_int)0); + /* committed to login -- turn off timeout */ + (void) alarm((u_int) 0); - /* - * If valid so far and root is logging in, see if root logins on - * this terminal are permitted. - * - * We allow authenticated remote root logins (except -r style) - */ - if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) { - if (hostname) + /* + * If valid so far and root is logging in, see if root logins on + * this terminal are permitted. + * + * We allow authenticated remote root logins (except -r style) + */ + + if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) { + if (hostname) { #ifdef UT_HOSTSIZE - syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s", - tty, UT_HOSTSIZE, hostname); + syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s", + tty, UT_HOSTSIZE, hostname); #else - syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s", - tty, hostname); + syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s", + tty, hostname); #endif - else - syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty); - printf("Login incorrect\n"); - sleepexit(1); + } else { + syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty); } + printf("Login incorrect\n"); + sleepexit(1); + } #ifdef OQUOTA - if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { - switch(errno) { - case EUSERS: - fprintf(stderr, - "Too many users logged on already.\nTry again later.\n"); - break; - case EPROCLIM: - fprintf(stderr, - "You have too many processes running.\n"); - break; - default: - perror("quota (Q_SETUID)"); - } - sleepexit(0); + if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { + switch(errno) { + case EUSERS: + fprintf(stderr, + "Too many users logged on already.\nTry again later.\n"); + break; + case EPROCLIM: + fprintf(stderr, + "You have too many processes running.\n"); + break; + default: + perror("quota (Q_SETUID)"); } + sleepexit(0); + } #endif - if (chdir(pwd->pw_dir) < 0) { - printf("No directory %s!\n", pwd->pw_dir); - if (chdir("/")) - exit(0); - pwd->pw_dir = "/"; - printf("Logging in with home = \"/\".\n"); - } - /* nothing else left to fail -- really log in */ - { - struct utmp utmp; - - login_time = time(&utmp.ut_time); - if ( (retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, ttyn, hostname, PTY_TTYSLOT_USABLE)) < 0 ) - com_err (argv[0], retval, "while updating utmp"); - } + if (chdir(pwd->pw_dir) < 0) { + printf("No directory %s!\n", pwd->pw_dir); + if (chdir("/")) + exit(0); + pwd->pw_dir = "/"; + printf("Logging in with home = \"/\".\n"); + } - quietlog = access(HUSHLOGIN, F_OK) == 0; - dolastlog(quietlog, tty); + /* nothing else left to fail -- really log in */ + { + struct utmp utmp; - if (!hflag && !rflag && !kflag && !Kflag && !eflag) { /* XXX */ - static struct winsize win = { 0, 0, 0, 0 }; + login_time = time(&utmp.ut_time); + if ((retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, + ttyn, hostname, + PTY_TTYSLOT_USABLE)) < 0) + com_err (argv[0], retval, "while updating utmp"); + } - (void)ioctl(0, TIOCSWINSZ, (char *)&win); - } + quietlog = access(HUSHLOGIN, F_OK) == 0; + dolastlog(quietlog, tty); - (void)chown(ttyn, pwd->pw_uid, - (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); + if (!hflag && !rflag && !kflag && !Kflag && !eflag) { /* XXX */ + static struct winsize win = { 0, 0, 0, 0 }; - (void)chmod(ttyn, 0620); -#ifdef KRB5_GET_TICKETS - /* Maybe telnetd got tickets for us? */ - if (!got_v5_tickets && have_v5_tickets (&me)) - got_v5_tickets = 1; -#endif /* GET_KRB_TICKETS */ + (void)ioctl(0, TIOCSWINSZ, (char *)&win); + } -#ifdef KRB4_GET_TICKETS - if ( login_krb4_convert && !got_v4_tickets) { + (void)chown(ttyn, pwd->pw_uid, + (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); + (void)chmod(ttyn, 0620); - if (got_v5_tickets) - try_convert524 (kcontext, me); +#ifdef KRB5_GET_TICKETS + /* Maybe telnetd got tickets for us? */ + if (!got_v5_tickets && have_v5_tickets (&me)) + forwarded_v5_tickets = 1; +#endif /* KRB5_GET_TICKETS */ - } +#if defined(KRB5_GET_TICKETS) && defined(KRB4_CONVERT) + if (login_krb4_convert && !got_v4_tickets) { + if (got_v5_tickets||forwarded_v5_tickets) + try_convert524 (kcontext, me); + } #endif -#if defined(KRB5_GET_TICKETS) || defined(KRB4_GET_TICKETS) -#if defined(KRB5_GET_TICKETS) && defined(KRB4_GET_TICKETS) - if (login_krb4_get_tickets || login_krb5_get_tickets) { -#elif defined(KRB4_GET_TICKETS) - if (login_krb4_get_tickets) { -#else - if (login_krb5_get_tickets) { +#ifdef KRB5_GET_TICKETS + if (login_krb5_get_tickets) + dofork(); + else #endif - /* Fork so that we can call kdestroy */ +#ifdef KRB4_GET_TICKETS + if (login_krb4_get_tickets) dofork(); - } -#endif /* KRB4_GET_TICKETS */ +#endif /* If the user's shell does not do job control we should put it in a different process group than than us, and set the tty process group @@ -1644,335 +1469,364 @@ int rewrite_ccache = 1; /*try to write out ccache*/ telnetd or rlogind if they don't properly detach from their controlling tty, which is the case (under SunOS at least.) */ - { - int p = getpid(); - struct sigaction sa, osa; + { + int p = getpid(); + struct sigaction sa, osa; - /* this will set the PGID to the PID. */ + /* this will set the PGID to the PID. */ #ifdef HAVE_SETPGID - if (setpgid(p,p) < 0) perror("login.krb5: setpgid"); + if (setpgid(p,p) < 0) + perror("login.krb5: setpgid"); +#elif defined(SETPGRP_TWOARG) + if (setpgrp(p,p) < 0) + perror("login.krb5: setpgrp"); #else -#ifdef SETPGRP_TWOARG - if (setpgrp(p,p) < 0) perror("login.krb5: setpgrp"); -#else - if (setpgrp() < 0) perror("login.krb5: setpgrp"); -#endif + if (setpgrp() < 0) + perror("login.krb5: setpgrp"); #endif - /* This will cause SIGTTOU to be ignored for the duration - of the TIOCSPGRP. If this is not done, and the parent's - process group is the foreground pgrp of the tty, then - this will suspend the child, which is bad. */ + /* This will cause SIGTTOU to be ignored for the duration + of the TIOCSPGRP. If this is not done, and the parent's + process group is the foreground pgrp of the tty, then + this will suspend the child, which is bad. */ - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - sigemptyset(&(sa.sa_mask)); + sa.sa_flags = 0; + sa.sa_handler = SIG_IGN; + sigemptyset(&(sa.sa_mask)); - if (sigaction(SIGTTOU, &sa, &osa)) - perror("login.krb5: sigaction(SIGTTOU, SIG_IGN)"); + if (sigaction(SIGTTOU, &sa, &osa)) + perror("login.krb5: sigaction(SIGTTOU, SIG_IGN)"); - /* This will set the foreground process group of the - controlling terminal to this process group (containing - only this process). */ + /* This will set the foreground process group of the + controlling terminal to this process group (containing + only this process). */ #ifdef HAVE_TCSETPGRP - if (tcsetpgrp(0, p) < 0) perror("login.krb5: tcsetpgrp"); + if (tcsetpgrp(0, p) < 0) + perror("login.krb5: tcsetpgrp"); #else - if (ioctl(0, TIOCSPGRP, &p) < 0) perror("login.krb5: tiocspgrp"); + if (ioctl(0, TIOCSPGRP, &p) < 0) + perror("login.krb5: tiocspgrp"); #endif - /* This will reset the SIGTTOU handler */ + /* This will reset the SIGTTOU handler */ - if (sigaction(SIGTTOU, &osa, NULL)) - perror("login.krb5: sigaction(SIGTTOU, [old handler])"); - } + if (sigaction(SIGTTOU, &osa, NULL)) + perror("login.krb5: sigaction(SIGTTOU, [old handler])"); + } - (void)setgid((gid_t) pwd->pw_gid); - (void) initgroups(username, pwd->pw_gid); + (void) setgid((gid_t) pwd->pw_gid); + (void) initgroups(username, pwd->pw_gid); - /* - * The V5 ccache and V4 ticket file are both created as root. - * They need to be owned by the user, and chown (a) assumes - * they are stored in a file and (b) allows a race condition - * in which a user can delete the file (if the directory - * sticky bit is not set) and make it a symlink to somewhere - * else; on some platforms, chown() on a symlink actually - * changes the owner of the pointed-to file. This is Bad. - * - * So, we suck the V5 and V4 krbtgts into memory here, destroy - * the ccache/ticket file, and recreate them later after the - * setuid. - */ + /* + * The V5 ccache and V4 ticket file are both created as root. + * They need to be owned by the user, and chown (a) assumes + * they are stored in a file and (b) allows a race condition + * in which a user can delete the file (if the directory + * sticky bit is not set) and make it a symlink to somewhere + * else; on some platforms, chown() on a symlink actually + * changes the owner of the pointed-to file. This is Bad. + * + * So, we suck the V5 and V4 krbtgts into memory here, destroy + * the ccache/ticket file, and recreate them later after the + * setuid. + * + * With the new v5 api, v5 tickets are kept in memory until written + * out after the setuid. However, forwarded tickets still + * need to be read in and recreated later + */ #ifdef KRB5_GET_TICKETS - if (got_v5_tickets) { - krb5_creds mcreds; - - memset(&mcreds, 0, sizeof(mcreds)); - memset(&save_v5creds, 0, sizeof(save_v5creds)); - - mcreds.client = me; - retval = krb5_build_principal_ext(kcontext, &mcreds.server, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - tgtname.length, tgtname.data, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - 0); - if (retval) { - syslog(LOG_ERR, - "%s while creating V5 krbtgt principal", - error_message(retval)); - goto skip_ccache_rewrite; - } - - mcreds.ticket_flags =0; - - if (retval = krb5_cc_retrieve_cred(kcontext, ccache, - 0, - &mcreds, &save_v5creds)) { - syslog(LOG_ERR, - "%s while retrieiving V5 initial ticket for copy", - error_message(retval)); - skip_ccache_rewrite: rewrite_ccache = 0; - - } - krb5_free_principal(kcontext, mcreds.server); + if (forwarded_v5_tickets) { + krb5_creds mcreds; + + memset(&mcreds, 0, sizeof(mcreds)); + memset(&save_v5creds, 0, sizeof(save_v5creds)); + + mcreds.client = me; + retval = + krb5_build_principal_ext(kcontext, &mcreds.server, + krb5_princ_realm(kcontext, me)->length, + krb5_princ_realm(kcontext, me)->data, + tgtname.length, tgtname.data, + krb5_princ_realm(kcontext, me)->length, + krb5_princ_realm(kcontext, me)->data, + 0); + if (retval) { + syslog(LOG_ERR, + "%s while creating V5 krbtgt principal", + error_message(retval)); + rewrite_ccache = 0; + } else { + mcreds.ticket_flags = 0; + + if (retval = krb5_cc_retrieve_cred(kcontext, ccache, 0, + &mcreds, &save_v5creds)) { + syslog(LOG_ERR, + "%s while retrieiving V5 initial ticket for copy", + error_message(retval)); + rewrite_ccache = 0; + } } + + krb5_free_principal(kcontext, mcreds.server); + } #endif /* KRB5_GET_TICKETS */ + #ifdef KRB4_GET_TICKETS - if (got_v4_tickets) { - memset(&save_v4creds, 0, sizeof(save_v4creds)); - - retval = krb_get_cred("krbtgt", realm, realm, &save_v4creds); - if (retval != KSUCCESS) { - syslog(LOG_ERR, - "%s while retrieving V4 initial ticket for copy", - error_message(retval)); - rewrite_ccache = 0; + if (got_v4_tickets) { + memset(&save_v4creds, 0, sizeof(save_v4creds)); - } + retval = krb_get_cred("krbtgt", realm, realm, &save_v4creds); + if (retval != KSUCCESS) { + syslog(LOG_ERR, + "%s while retrieving V4 initial ticket for copy", + error_message(retval)); + rewrite_ccache = 0; } + } #endif /* KRB4_GET_TICKETS */ -#if defined(KRB5_GET_TICKETS) || defined(KRB4_GET_TICKETS) - if (got_v5_tickets || got_v4_tickets) - destroy_tickets(); + +#ifdef KRB5_GET_TICKETS + if (forwarded_v5_tickets) + destroy_tickets(); + else +#endif +#ifdef KRB4_GET_TICKETS + if (got_v4_tickets) + destroy_tickets(); #endif #ifdef OQUOTA - quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); + quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); #endif #ifdef HAVE_SETLOGIN - if (setlogin(pwd->pw_name) < 0) - syslog(LOG_ERR, "setlogin() failure %d",errno); + if (setlogin(pwd->pw_name) < 0) + syslog(LOG_ERR, "setlogin() failure %d",errno); #endif #ifdef HAVE_SETLUID - /* - * If we're on a system which keeps track of login uids, then - * attempt to set the login uid, but don't get too unhappy when/if - * it doesn't succeed. - */ - if ((uid_t) getluid() < (uid_t) 0) { - setluid((uid_t) pwd->pw_uid); - } + /* + * If we're on a system which keeps track of login uids, then + * attempt to set the login uid, but don't get too unhappy when/if + * it doesn't succeed. + */ + if ((uid_t) getluid() < (uid_t) 0) { + setluid((uid_t) pwd->pw_uid); + } #endif /* HAVE_SETLUID */ #ifdef _IBMR2 - setuidx(ID_LOGIN, pwd->pw_uid); + setuidx(ID_LOGIN, pwd->pw_uid); #endif - /* This call MUST succeed */ - if(setuid((uid_t) pwd->pw_uid) < 0) { - perror("setuid"); - sleepexit(1); - } + /* This call MUST succeed */ + if (setuid((uid_t) pwd->pw_uid) < 0) { + perror("setuid"); + sleepexit(1); + } + + /* + * We are the user now. Re-create the destroyed ccache and + * ticket file. + */ - /* - * We are the user now. Re-create the destroyed ccache and - * ticket file. - */ #ifdef KRB5_GET_TICKETS - if (got_v5_tickets && rewrite_ccache) { - retval = krb5_cc_initialize (kcontext, ccache, me); - if (retval) { - syslog(LOG_ERR, - "%s while re-initializing V5 ccache as user", - error_message(retval)); - goto skip_ccache_output; - } - if (retval = krb5_cc_store_cred(kcontext, ccache, &save_v5creds)) { - syslog(LOG_ERR, - "%s while re-storing V5 credentials as user", - error_message(retval)); - - } - skip_ccache_output: krb5_free_cred_contents(kcontext, &save_v5creds); + if (got_v5_tickets) { + /* set up credential cache -- obeying KRB5_ENV_CCNAME + set earlier */ + /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */ + if (retval = krb5_cc_default(kcontext, &ccache)) { + com_err(argv[0], retval, "while getting default ccache"); + } else if (retval = krb5_cc_initialize(kcontext, ccache, me)) { + com_err(argv[0], retval, "when initializing cache"); + } else if (retval = krb5_cc_store_cred(kcontext, ccache, &my_creds)) { + com_err(argv[0], retval, "while storing credentials"); + } else if (xtra_creds && + (retval = krb5_cc_copy_creds(kcontext, xtra_creds, + ccache))) { + com_err(argv[0], retval, "while storing credentials"); } + + krb5_cc_destroy(kcontext, xtra_creds); + } else if (forwarded_v5_tickets && rewrite_ccache) { + if ((retval = krb5_cc_initialize (kcontext, ccache, me))) { + syslog(LOG_ERR, + "%s while re-initializing V5 ccache as user", + error_message(retval)); + } else if (retval = krb5_cc_store_cred(kcontext, ccache, + &save_v5creds)) { + syslog(LOG_ERR, + "%s while re-storing V5 credentials as user", + error_message(retval)); + + } + krb5_free_cred_contents(kcontext, &save_v5creds); + } #endif /* KRB5_GET_TICKETS */ + #ifdef KRB4_GET_TICKETS - if (got_v4_tickets&&rewrite_ccache) { - retval = in_tkt(save_v4creds.pname, save_v4creds.pinst); - if (retval != KSUCCESS) { - syslog(LOG_ERR, - "%s while re-initializing V4 ticket cache as user", - error_message((retval == -1)?errno:retval)); - goto skip_output_tkfile; - } - retval = krb_save_credentials(save_v4creds.service, - save_v4creds.instance, - save_v4creds.realm, - save_v4creds.session, - save_v4creds.lifetime, - save_v4creds.kvno, - &(save_v4creds.ticket_st), - save_v4creds.issue_date); - if (retval != KSUCCESS) { - syslog(LOG_ERR, - "%s while re-storing V4 tickets as user", - error_message(retval)); - - } + if (got_v4_tickets && rewrite_ccache) { + if ((retval = in_tkt(save_v4creds.pname, save_v4creds.pinst)) + != KSUCCESS) { + syslog(LOG_ERR, + "%s while re-initializing V4 ticket cache as user", + error_message((retval == -1)?errno:retval)); + } else if ((retval = krb_save_credentials(save_v4creds.service, + save_v4creds.instance, + save_v4creds.realm, + save_v4creds.session, + save_v4creds.lifetime, + save_v4creds.kvno, + &(save_v4creds.ticket_st), + save_v4creds.issue_date)) + != KSUCCESS) { + syslog(LOG_ERR, + "%s while re-storing V4 tickets as user", + error_message(retval)); } + } #endif /* KRB4_GET_TICKETS */ - skip_output_tkfile: /*null*/; + if (*pwd->pw_shell == '\0') + pwd->pw_shell = BSHELL; - if (*pwd->pw_shell == '\0') - pwd->pw_shell = BSHELL; #if defined(NTTYDISC) && defined(TIOCSETD) - /* turn on new line discipline for all shells */ - ioctlval = NTTYDISC; - (void)ioctl(0, TIOCSETD, (char *)&ioctlval); + /* turn on new line discipline for all shells */ + ioctlval = NTTYDISC; + (void)ioctl(0, TIOCSETD, (char *)&ioctlval); #endif - ccname = getenv("KRB5CCNAME"); /* save cache */ - tz = getenv("TZ"); /* and time zone */ + ccname = getenv("KRB5CCNAME"); /* save cache */ + tz = getenv("TZ"); /* and time zone */ - /* destroy environment unless user has requested preservation */ - if (!pflag) { - envinit = (char **)malloc(MAXENVIRON * sizeof(char *)); - if (envinit == 0) { - fprintf(stderr, "Can't malloc empty environment.\n"); - sleepexit(1); - } - envinit[0] = NULL; - environ = envinit; + /* destroy environment unless user has requested preservation */ + if (!pflag) { + envinit = (char **) malloc(MAXENVIRON * sizeof(char *)); + if (envinit == 0) { + fprintf(stderr, "Can't malloc empty environment.\n"); + sleepexit(1); } + envinit[0] = NULL; + environ = envinit; + } - setenv ("LOGNAME", pwd->pw_name, 1); - setenv ("LOGIN", pwd->pw_name, 1); + setenv ("LOGNAME", pwd->pw_name, 1); + setenv ("LOGIN", pwd->pw_name, 1); - /* read the /etc/environment file on AIX */ + /* read the /etc/environment file on AIX */ #ifdef HAVE_ETC_ENVIRONMENT - read_env_vars_from_file ("/etc/environment"); + read_env_vars_from_file ("/etc/environment"); #endif - /* Set login timezone for date information (sgi PDG) */ + /* Set login timezone for date information (sgi PDG) */ #ifdef HAVE_ETC_TIMEZONE - read_env_vars_from_file ("/etc/TIMEZONE"); + read_env_vars_from_file ("/etc/TIMEZONE"); #else - if (tz) - setenv ("TZ", tz, 1); + if (tz) + setenv ("TZ", tz, 1); #endif - if (ccname) - setenv("KRB5CCNAME", ccname, 1); + if (ccname) + setenv("KRB5CCNAME", ccname, 1); - setenv("HOME", pwd->pw_dir, 1); - setenv("PATH", LPATH, 1); - setenv("USER", pwd->pw_name, 1); - setenv("SHELL", pwd->pw_shell, 1); + setenv("HOME", pwd->pw_dir, 1); + setenv("PATH", LPATH, 1); + setenv("USER", pwd->pw_name, 1); + setenv("SHELL", pwd->pw_shell, 1); + + if (term[0] == '\0') { + (void) strncpy(term, stypeof(tty), sizeof(term)); + term[sizeof(term) - 1] = '\0'; + } + if (term[0]) + (void)setenv("TERM", term, 0); - if (term[0] == '\0') { - (void) strncpy(term, stypeof(tty), sizeof(term)); - term[sizeof(term) - 1] = '\0'; - } - if (term[0]) - (void)setenv("TERM", term, 0); #ifdef KRB4_GET_TICKETS - /* tkfile[0] is only set if we got tickets above */ - if (login_krb4_get_tickets && tkfile[0]) - (void) setenv(KRB_ENVIRON, tkfile, 1); + /* tkfile[0] is only set if we got tickets above */ + if (login_krb4_get_tickets && tkfile[0]) + (void) setenv(KRB_ENVIRON, tkfile, 1); #endif /* KRB4_GET_TICKETS */ + #ifdef KRB5_GET_TICKETS - /* ccfile[0] is only set if we got tickets above */ - if (login_krb5_get_tickets && ccfile[0]) - (void) setenv(KRB5_ENV_CCNAME, ccfile, 1); + /* ccfile[0] is only set if we got tickets above */ + if (login_krb5_get_tickets && ccfile[0]) + (void) setenv(KRB5_ENV_CCNAME, ccfile, 1); #endif /* KRB5_GET_TICKETS */ - if (tty[sizeof("tty")-1] == 'd') - syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); - if (pwd->pw_uid == 0) - if (hostname) + if (tty[sizeof("tty")-1] == 'd') + syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); + if (pwd->pw_uid == 0) #ifdef KRB4_KLOGIN - if (kdata) { - /* @*$&@#*($)#@$ syslog doesn't handle very - many arguments */ - char buf[BUFSIZ]; + if (kdata) { + if (hostname) { + char buf[BUFSIZ]; #ifdef UT_HOSTSIZE - (void) sprintf(buf, - "ROOT LOGIN (krb) %s from %.*s, %s.%s@%s", - tty, UT_HOSTSIZE, hostname, - kdata->pname, kdata->pinst, - kdata->prealm); + (void) sprintf(buf, + "ROOT LOGIN (krb) %s from %.*s, %s.%s@%s", + tty, UT_HOSTSIZE, hostname, + kdata->pname, kdata->pinst, + kdata->prealm); #else - (void) sprintf(buf, - "ROOT LOGIN (krb) %s from %s, %s.%s@%s", - tty, hostname, - kdata->pname, kdata->pinst, - kdata->prealm); -#endif - syslog(LOG_NOTICE, "%s", buf); - } else { + (void) sprintf(buf, + "ROOT LOGIN (krb) %s from %s, %s.%s@%s", + tty, hostname, + kdata->pname, kdata->pinst, + kdata->prealm); +#endif + syslog(LOG_NOTICE, "%s", buf); + } else { + syslog(LOG_NOTICE, + "ROOT LOGIN (krb) %s, %s.%s@%s", + tty, + kdata->pname, kdata->pinst, + kdata->prealm); + } + } else #endif /* KRB4_KLOGIN */ + { + if (hostname) { #ifdef UT_HOSTSIZE - syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", - tty, UT_HOSTSIZE, hostname); + syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", + tty, UT_HOSTSIZE, hostname); #else - syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s", - tty, hostname); + syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s", + tty, hostname); #endif -#ifdef KRB4_KLOGIN - } - else - if (kdata) { - syslog(LOG_NOTICE, - "ROOT LOGIN (krb) %s, %s.%s@%s", - tty, - kdata->pname, kdata->pinst, - kdata->prealm); - } -#endif /* KRB4_KLOGIN */ - else - syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); + } else { + syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); + } + } - afs_login (); + afs_login(); - if (!quietlog) { + if (!quietlog) { #ifdef KRB4_KLOGIN - if (!krbflag && !fflag && !eflag ) - printf("\nWarning: No Kerberos tickets obtained.\n\n"); + if (!krbflag && !fflag && !eflag ) + printf("\nWarning: No Kerberos tickets obtained.\n\n"); #endif /* KRB4_KLOGIN */ - motd (); - check_mail (); - } + motd(); + check_mail(); + } #ifndef OQUOTA - if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN); -#endif - handler_init (sa, SIG_DFL); - handler_set (SIGALRM, sa); - handler_set (SIGQUIT, sa); - handler_set (SIGINT, sa); - handler_init (sa, SIG_IGN); - handler_set (SIGTSTP, sa); - - tbuf[0] = '-'; - (void) strncpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? - p + 1 : pwd->pw_shell, sizeof(tbuf) - 1); - tbuf[sizeof(tbuf) - 1] = '\0'; - execlp(pwd->pw_shell, tbuf, 0); - fprintf(stderr, "login: no shell: "); - perror(pwd->pw_shell); - exit(0); + if (! access( QUOTAWARN, X_OK)) + (void) system(QUOTAWARN); +#endif + + handler_init (sa, SIG_DFL); + handler_set (SIGALRM, sa); + handler_set (SIGQUIT, sa); + handler_set (SIGINT, sa); + handler_init (sa, SIG_IGN); + handler_set (SIGTSTP, sa); + + tbuf[0] = '-'; + p = strrchr(pwd->pw_shell, '/'); + (void) strncpy(tbuf+1, p?(p+1):pwd->pw_shell, sizeof(tbuf-1)); + tbuf[sizeof(tbuf) - 1] = '\0'; + + execlp(pwd->pw_shell, tbuf, 0); + fprintf(stderr, "login: no shell: "); + perror(pwd->pw_shell); + exit(0); } char *speeds[] = { @@ -1991,212 +1845,216 @@ speed_t b_speeds[] = { term_init (do_rlogin) { - int line_speed = -1; + int line_speed = -1; - if (do_rlogin) { - register char *cp = strchr(term, '/'), **cpp; - char *speed; + if (do_rlogin) { + register char *cp = strchr(term, '/'), **cpp; + char *speed; - if (cp) { + if (cp) { + *cp++ = '\0'; + speed = cp; + cp = strchr(speed, '/'); + if (cp) *cp++ = '\0'; - speed = cp; - cp = strchr(speed, '/'); - if (cp) - *cp++ = '\0'; - for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) - if (strcmp(*cpp, speed) == 0) { - line_speed = cpp-speeds; - break; - } - } + for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) + if (strcmp(*cpp, speed) == 0) { + line_speed = cpp-speeds; + break; + } } + } #ifdef POSIX_TERMIOS - { - struct termios tc; + { + struct termios tc; - (void)tcgetattr(0, &tc); - if (line_speed != -1) { - cfsetispeed(&tc, b_speeds[line_speed]); - cfsetospeed(&tc, b_speeds[line_speed]); - } - tc.c_cc[VMIN] = 1; - tc.c_cc[VTIME] = 0; + (void)tcgetattr(0, &tc); + if (line_speed != -1) { + cfsetispeed(&tc, b_speeds[line_speed]); + cfsetospeed(&tc, b_speeds[line_speed]); + } + tc.c_cc[VMIN] = 1; + tc.c_cc[VTIME] = 0; #ifndef NO_INIT_CC - tc.c_cc[VERASE] = CERASE; - tc.c_cc[VKILL] = CKILL; - tc.c_cc[VEOF] = CEOF; - tc.c_cc[VINTR] = CINTR; - tc.c_cc[VQUIT] = CQUIT; - tc.c_cc[VSTART] = CSTART; - tc.c_cc[VSTOP] = CSTOP; + tc.c_cc[VERASE] = CERASE; + tc.c_cc[VKILL] = CKILL; + tc.c_cc[VEOF] = CEOF; + tc.c_cc[VINTR] = CINTR; + tc.c_cc[VQUIT] = CQUIT; + tc.c_cc[VSTART] = CSTART; + tc.c_cc[VSTOP] = CSTOP; #ifndef CNUL #define CNUL CEOL #endif - tc.c_cc[VEOL] = CNUL; - /* The following are common extensions to POSIX */ + tc.c_cc[VEOL] = CNUL; + /* The following are common extensions to POSIX */ #ifdef VEOL2 - tc.c_cc[VEOL2] = CNUL; + tc.c_cc[VEOL2] = CNUL; #endif #ifdef VSUSP #if !defined(CSUSP) && defined(CSWTCH) #define CSUSP CSWTCH #endif - tc.c_cc[VSUSP] = CSUSP; + tc.c_cc[VSUSP] = CSUSP; #endif #ifdef VDSUSP - tc.c_cc[VDSUSP] = CDSUSP; + tc.c_cc[VDSUSP] = CDSUSP; #endif #ifdef VLNEXT - tc.c_cc[VLNEXT] = CLNEXT; + tc.c_cc[VLNEXT] = CLNEXT; #endif #ifdef VREPRINT - tc.c_cc[VREPRINT] = CRPRNT; + tc.c_cc[VREPRINT] = CRPRNT; #endif #ifdef VDISCRD - tc.c_cc[VDISCRD] = CFLUSH; + tc.c_cc[VDISCRD] = CFLUSH; #endif #ifdef VDISCARD #ifndef CDISCARD #define CDISCARD CFLUSH #endif - tc.c_cc[VDISCARD] = CDISCARD; + tc.c_cc[VDISCARD] = CDISCARD; #endif #ifdef VWERSE - tc.c_cc[VWERSE] = CWERASE; + tc.c_cc[VWERSE] = CWERASE; #endif #ifdef VWERASE - tc.c_cc[VWERASE] = CWERASE; + tc.c_cc[VWERASE] = CWERASE; #endif #if defined (VSTATUS) && defined (CSTATUS) - tc.c_cc[VSTATUS] = CSTATUS; + tc.c_cc[VSTATUS] = CSTATUS; #endif /* VSTATUS && CSTATUS */ #endif /* NO_INIT_CC */ - /* set all standard echo, edit, and job control options */ - /* but leave any extensions */ - tc.c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG|IEXTEN; - tc.c_lflag &= ~(NOFLSH|TOSTOP); + /* set all standard echo, edit, and job control options */ + /* but leave any extensions */ + tc.c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG|IEXTEN; + tc.c_lflag &= ~(NOFLSH|TOSTOP); #ifdef ECHOCTL - /* Not POSIX, but if we have it, we probably want it */ - tc.c_lflag |= ECHOCTL; + /* Not POSIX, but if we have it, we probably want it */ + tc.c_lflag |= ECHOCTL; #endif #ifdef ECHOKE - /* Not POSIX, but if we have it, we probably want it */ - tc.c_lflag |= ECHOKE; + /* Not POSIX, but if we have it, we probably want it */ + tc.c_lflag |= ECHOKE; #endif - tc.c_iflag |= ICRNL|BRKINT; - tc.c_oflag |= ONLCR|OPOST|TAB3; - tcsetattr(0, TCSANOW, &tc); - } + tc.c_iflag |= ICRNL|BRKINT; + tc.c_oflag |= ONLCR|OPOST|TAB3; + tcsetattr(0, TCSANOW, &tc); + } #else /* not POSIX_TERMIOS */ - { - struct sgttyb sgttyb; - static struct tchars tc = { - CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK - }; - static struct ltchars ltc = { - CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT - }; - - (void) ioctl(0, TIOCGETP, (char *)&sgttyb); - if (line_speed != -1) - sgttyb.sg_ispeed = sgttyb.sg_ospeed = line_speed; - sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; - sgttyb.sg_erase = CERASE; - sgttyb.sg_kill = CKILL; - (void)ioctl(0, TIOCSLTC, (char *)<c); - (void)ioctl(0, TIOCSETC, (char *)&tc); - (void)ioctl(0, TIOCSETP, (char *)&sgttyb); + { + struct sgttyb sgttyb; + static struct tchars tc = { + CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK + }; + static struct ltchars ltc = { + CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT + }; + + (void) ioctl(0, TIOCGETP, (char *)&sgttyb); + if (line_speed != -1) + sgttyb.sg_ispeed = sgttyb.sg_ospeed = line_speed; + sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; + sgttyb.sg_erase = CERASE; + sgttyb.sg_kill = CKILL; + (void)ioctl(0, TIOCSLTC, (char *)<c); + (void)ioctl(0, TIOCSETC, (char *)&tc); + (void)ioctl(0, TIOCSETP, (char *)&sgttyb); #if defined(TIOCSETD) - { - int ioctlval; - ioctlval = 0; - (void)ioctl(0, TIOCSETD, (char *)&ioctlval); - } -#endif + { + int ioctlval; + ioctlval = 0; + (void)ioctl(0, TIOCSETD, (char *)&ioctlval); } +#endif + } #endif } void getloginname() { - register int ch; - register char *p; - static char nbuf[UT_NAMESIZE + 1]; - - for (;;) { - printf("login: "); - for (p = nbuf; (ch = getchar()) != '\n'; ) { - if (ch == EOF) - exit(0); - if (p < nbuf + UT_NAMESIZE) - *p++ = ch; - } - if (p > nbuf) - if (nbuf[0] == '-') - fprintf(stderr, - "login names may not start with '-'.\n"); - else { - *p = '\0'; - username = nbuf; - break; - } + register int ch; + register char *p; + static char nbuf[UT_NAMESIZE + 1]; + + for (;;) { + printf("login: "); + for (p = nbuf; (ch = getchar()) != '\n'; ) { + if (ch == EOF) + exit(0); + if (p < nbuf + UT_NAMESIZE) + *p++ = ch; } + if (p > nbuf) + if (nbuf[0] == '-') + fprintf(stderr, + "login names may not start with '-'.\n"); + else { + *p = '\0'; + username = nbuf; + break; + } + } } sigtype timedout() { - fprintf(stderr, "Login timed out after %d seconds\n", timeout); - exit(0); + fprintf(stderr, "Login timed out after %d seconds\n", timeout); + exit(0); } #ifndef HAVE_TTYENT_H int root_tty_security = 1; #endif + int rootterm(tty) char *tty; { #ifndef HAVE_TTYENT_H - return(root_tty_security); + return(root_tty_security); #else - struct ttyent *t; + struct ttyent *t; - return((t = getttynam(tty)) && t->ty_status&TTY_SECURE); + return((t = getttynam(tty)) && t->ty_status&TTY_SECURE); #endif /* HAVE_TTYENT_H */ } #ifndef NO_MOTD sigjmp_buf motdinterrupt; + sigtype sigint() { - siglongjmp(motdinterrupt, 1); + siglongjmp(motdinterrupt, 1); } void motd() { - register int fd, nchars; - char tbuf[8192]; - handler sa, osa; - - if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0) - return; - handler_init (sa, sigint); - handler_swap (SIGINT, sa, osa); - if (sigsetjmp(motdinterrupt, 1) == 0) - while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) - (void)write(fileno(stdout), tbuf, nchars); - handler_set (SIGINT, osa); - (void)close(fd); + register int fd, nchars; + char tbuf[8192]; + handler sa, osa; + + if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0) + return; + handler_init (sa, sigint); + handler_swap (SIGINT, sa, osa); + if (sigsetjmp(motdinterrupt, 1) == 0) + while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) + (void)write(fileno(stdout), tbuf, nchars); + handler_set (SIGINT, osa); + (void)close(fd); } #else -void motd () { } +void motd() +{ +} #endif #ifndef NO_MAILCHECK -void check_mail () +void check_mail() { char tbuf[MAXPATHLEN+2]; struct stat st; @@ -2206,56 +2064,61 @@ void check_mail () (st.st_mtime > st.st_atime) ? "new " : ""); } #else -void check_mail () { } +void check_mail() +{ +} #endif void checknologin() { - register int fd, nchars; - char tbuf[8192]; + register int fd, nchars; + char tbuf[8192]; - if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) { - while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) - (void)write(fileno(stdout), tbuf, nchars); - sleepexit(0); - } + if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) { + while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) + (void)write(fileno(stdout), tbuf, nchars); + sleepexit(0); + } } void dolastlog(quiet, tty) - int quiet; - char *tty; + int quiet; + char *tty; { #if defined(HAVE_LASTLOG_H) || (defined(BSD) && (BSD >= 199103)) - struct lastlog ll; - int fd; + struct lastlog ll; + int fd; - if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) { - (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET); - if (!quiet) { - if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && - ll.ll_time != 0) { - printf("Last login: %.*s ", - 24-5, (char *)ctime(&ll.ll_time)); - if (*ll.ll_host != '\0') - printf("from %.*s\n", - sizeof(ll.ll_host), ll.ll_host); - else - printf("on %.*s\n", - sizeof(ll.ll_line), ll.ll_line); - } - (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET); - } - (void)time(&ll.ll_time); - (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); - ll.ll_line[sizeof(ll.ll_line) - 1] = '\0'; - if (hostname) { - (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); - ll.ll_host[sizeof(ll.ll_host) - 1] = '\0'; - } else - (void) memset(ll.ll_host, 0, sizeof(ll.ll_host)); - (void)write(fd, (char *)&ll, sizeof(ll)); - (void)close(fd); + if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) { + (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET); + if (!quiet) { + if ((read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll)) && + (ll.ll_time != 0)) { + + printf("Last login: %.*s ", 24-5, (char *)ctime(&ll.ll_time)); + + if (*ll.ll_host != '\0') + printf("from %.*s\n", sizeof(ll.ll_host), ll.ll_host); + else + printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line); + } + (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET); + } + (void) time(&ll.ll_time); + + (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + ll.ll_line[sizeof(ll.ll_line) - 1] = '\0'; + + if (hostname) { + (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); + ll.ll_host[sizeof(ll.ll_host) - 1] = '\0'; + } else { + (void) memset(ll.ll_host, 0, sizeof(ll.ll_host)); } + + (void)write(fd, (char *)&ll, sizeof(ll)); + (void)close(fd); + } #endif } @@ -2268,166 +2131,168 @@ void dolastlog(quiet, tty) char * stypeof(ttyid) - char *ttyid; + char *ttyid; { -char *cp = getenv("term"); + char *cp = getenv("term"); #ifndef HAVE_TTYENT_H -if (cp) - return cp; -else return(UNKNOWN); + if (cp) + return cp; + else + return(UNKNOWN); #else - struct ttyent *t; - if (cp) - return cp; - else return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); + struct ttyent *t; + if (cp) + return cp; + else + return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); #endif } int doremotelogin(host) - char *host; + char *host; { - static char lusername[UT_NAMESIZE+1]; - char rusername[UT_NAMESIZE+1]; - - lgetstr(rusername, sizeof(rusername), "Remote user"); - lgetstr(lusername, sizeof(lusername), "Local user"); - lgetstr(term, sizeof(term), "Terminal type"); - username = lusername; - pwd = getpwnam(username); - if (pwd == NULL) - return(-1); - return(ruserok(host, (pwd->pw_uid == 0), rusername, username)); + static char lusername[UT_NAMESIZE+1]; + char rusername[UT_NAMESIZE+1]; + + lgetstr(rusername, sizeof(rusername), "Remote user"); + lgetstr(lusername, sizeof(lusername), "Local user"); + lgetstr(term, sizeof(term), "Terminal type"); + username = lusername; + pwd = getpwnam(username); + if (pwd == NULL) + return(-1); + return(ruserok(host, (pwd->pw_uid == 0), rusername, username)); } #ifdef KRB4_KLOGIN int do_krb_login(host, strict) - char *host; - int strict; + char *host; + int strict; { - int rc; - struct sockaddr_in sin; - char instance[INST_SZ], version[9]; - long authoptions = 0L; - struct hostent *hp = gethostbyname(host); - static char lusername[UT_NAMESIZE+1]; + int rc; + struct sockaddr_in sin; + char instance[INST_SZ], version[9]; + long authoptions = 0L; + struct hostent *hp = gethostbyname(host); + static char lusername[UT_NAMESIZE+1]; + + /* + * Kerberos autologin protocol. + */ + (void) memset((char *) &sin, 0, (int) sizeof(sin)); + + if (hp) + (void) memcpy ((char *)&sin.sin_addr, hp->h_addr, + sizeof(sin.sin_addr)); + else + sin.sin_addr.s_addr = inet_addr(host); + + if ((hp == NULL) && (sin.sin_addr.s_addr == -1)) { + printf("Hostname did not resolve to an address, so Kerberos authentication failed\r\n"); /* - * Kerberos autologin protocol. + * No host addr prevents auth, so + * punt krb and require password */ - - (void) memset((char *) &sin, 0, (int) sizeof(sin)); - - if (hp) - (void) memcpy ((char *)&sin.sin_addr, hp->h_addr, - sizeof(sin.sin_addr)); - else - sin.sin_addr.s_addr = inet_addr(host); - - if ((hp == NULL) && (sin.sin_addr.s_addr == -1)) { - printf("Hostname did not resolve to an address, so Kerberos authentication failed\r\n"); - /* - * No host addr prevents auth, so - * punt krb and require password - */ - if (strict) { - goto paranoid; - } else { - pwd = NULL; - return(-1); - } + if (strict) { + goto paranoid; + } else { + pwd = NULL; + return(-1); } + } - kdata = (AUTH_DAT *)malloc( sizeof(AUTH_DAT) ); - ticket = (KTEXT) malloc(sizeof(KTEXT_ST)); + kdata = (AUTH_DAT *)malloc( sizeof(AUTH_DAT) ); + ticket = (KTEXT) malloc(sizeof(KTEXT_ST)); - (void) strcpy(instance, "*"); - if ((rc=krb_recvauth(authoptions, 0, ticket, "rcmd", - instance, &sin, - (struct sockaddr_in *)0, - kdata, "", (bit_64 *) 0, version))) { - printf("Kerberos rlogin failed: %s\r\n",krb_get_err_text(rc)); - if (strict) { + (void) strcpy(instance, "*"); + if ((rc=krb_recvauth(authoptions, 0, ticket, "rcmd", + instance, &sin, + (struct sockaddr_in *)0, + kdata, "", (bit_64 *) 0, version))) { + printf("Kerberos rlogin failed: %s\r\n",krb_get_err_text(rc)); + if (strict) { paranoid: - /* - * Paranoid hosts, such as a Kerberos server, - * specify the Klogind daemon to disallow - * even password access here. - */ - printf("Sorry, you must have Kerberos authentication to access this host.\r\n"); - exit(1); - } - } - (void) lgetstr(lusername, sizeof (lusername), "Local user"); - (void) lgetstr(term, sizeof(term), "Terminal type"); - username = lusername; - if (getuid()) { - pwd = NULL; - return(-1); - } - pwd = getpwnam(lusername); - if (pwd == NULL) { - pwd = NULL; - return(-1); + /* + * Paranoid hosts, such as a Kerberos server, + * specify the Klogind daemon to disallow + * even password access here. + */ + printf("Sorry, you must have Kerberos authentication to access this host.\r\n"); + exit(1); } + } + (void) lgetstr(lusername, sizeof (lusername), "Local user"); + (void) lgetstr(term, sizeof(term), "Terminal type"); + username = lusername; + if (getuid()) { + pwd = NULL; + return(-1); + } + pwd = getpwnam(lusername); + if (pwd == NULL) { + pwd = NULL; + return(-1); + } - /* - * if Kerberos login failed because of an error in krb_recvauth, - * return the indication of a bad attempt. User will be prompted - * for a password. We CAN'T check the .rhost file, because we need - * the remote username to do that, and the remote username is in the - * Kerberos ticket. This affects ONLY the case where there is - * Kerberos on both ends, but Kerberos fails on the server end. - */ - if (rc) { - return(-1); - } + /* + * if Kerberos login failed because of an error in krb_recvauth, + * return the indication of a bad attempt. User will be prompted + * for a password. We CAN'T check the .rhost file, because we need + * the remote username to do that, and the remote username is in the + * Kerberos ticket. This affects ONLY the case where there is + * Kerberos on both ends, but Kerberos fails on the server end. + */ + if (rc) { + return(-1); + } - if ((rc=kuserok(kdata,lusername))) { - printf("login: %s has not given you permission to login without a password.\r\n",lusername); - if (strict) { - exit(1); - } - return(-1); + if ((rc=kuserok(kdata,lusername))) { + printf("login: %s has not given you permission to login without a password.\r\n",lusername); + if (strict) { + exit(1); } - return(0); + return(-1); + } + return(0); } #endif /* KRB4_KLOGIN */ void lgetstr(buf, cnt, err) - char *buf, *err; - int cnt; + char *buf, *err; + int cnt; { - int ocnt = cnt; - char *obuf = buf; - char ch; - - do { - if (read(0, &ch, sizeof(ch)) != sizeof(ch)) - exit(1); - if (--cnt < 0) { - fprintf(stderr,"%s '%.*s' too long, %d characters maximum.\r\n", - err, ocnt, obuf, ocnt-1); - sleepexit(1); - } - *buf++ = ch; - } while (ch); + int ocnt = cnt; + char *obuf = buf; + char ch; + + do { + if (read(0, &ch, sizeof(ch)) != sizeof(ch)) + exit(1); + if (--cnt < 0) { + fprintf(stderr,"%s '%.*s' too long, %d characters maximum.\r\n", + err, ocnt, obuf, ocnt-1); + sleepexit(1); + } + *buf++ = ch; + } while (ch); } void sleepexit(eval) - int eval; + int eval; { #ifdef KRB4_GET_TICKETS - if (login_krb4_get_tickets && krbflag) - (void) destroy_tickets(); + if (login_krb4_get_tickets && krbflag) + (void) destroy_tickets(); #endif /* KRB4_GET_TICKETS */ - sleep((u_int)5); - exit(eval); + sleep((u_int)5); + exit(eval); } #if defined(KRB4_GET_TICKETS) || defined(KRB5_GET_TICKETS) - static int hungup = 0; + static sigtype sighup() { hungup = 1; @@ -2448,34 +2313,38 @@ dofork() #ifdef _IBMR2 update_ref_count(1); #endif - if(!(child=fork())) - return; /* Child process returns */ + if (!(child=fork())) + return; /* Child process returns */ /* The parent continues here */ - { /* Try and get rid of our controlling tty. On SunOS, this may or may - not work depending on if our parent did a setsid before exec-ing us. */ + /* Try and get rid of our controlling tty. On SunOS, this may or may + not work depending on if our parent did a setsid before exec-ing + us. */ #ifndef __linux__ - /* On linux, TIOCNOTTY causes us to die on a - SIGHUP, so don't even try it. */ + /* On linux, TIOCNOTTY causes us to die on a + SIGHUP, so don't even try it. */ #ifdef TIOCNOTTY - { int fd; - if ((fd = open("/dev/tty", O_RDWR)) >= 0) { - ioctl(fd, TIOCNOTTY, 0); - close(fd); - } - } + { + int fd; + + if ((fd = open("/dev/tty", O_RDWR)) >= 0) { + ioctl(fd, TIOCNOTTY, 0); + close(fd); + } + } #endif #endif /* __linux__ */ + #ifdef HAVE_SETSID - (void)setsid(); + (void)setsid(); #endif + #ifdef SETPGRP_TWOARG - (void)setpgrp(0, 0); + (void)setpgrp(0, 0); #else - (void)setpgrp(); + (void)setpgrp(); #endif - } /* Setup stuff? This would be things we could do in parallel with login */ (void) chdir("/"); /* Let's not keep the fs busy... */ @@ -2489,21 +2358,22 @@ dofork() while (1) { #ifdef HAVE_WAITPID pid = waitpid(child, 0, 0); -#else -#ifdef WAIT_USES_INT +#elif defined(WAIT_USES_INT) pid = wait((int *)0); #else pid = wait((union wait *)0); #endif -#endif - if (hungup) + + if (hungup) { #ifdef HAVE_KILLPG killpg(child, SIGHUP); #else kill(-child, SIGHUP); #endif + } + if (pid == child) - break; + break; } /* Cleanup stuff */ @@ -2525,20 +2395,18 @@ dofork() for compatablilty with version 5 krb library, since kcmd.o is linked into all programs. */ -char * - strsave(sp) -char *sp; +char *strsave(sp) + char *sp; { register char *ret; - if((ret = (char *) malloc((unsigned) strlen(sp)+1)) == NULL) { + if ((ret = (char *) malloc((unsigned) strlen(sp)+1)) == NULL) { fprintf(stderr, "no memory for saving args\n"); exit(1); } (void) strcpy(ret,sp); return(ret); } - #endif #ifdef _IBMR2 diff --git a/src/appl/gss-sample/ChangeLog b/src/appl/gss-sample/ChangeLog index 476fb5bce..bdf6e8d71 100644 --- a/src/appl/gss-sample/ChangeLog +++ b/src/appl/gss-sample/ChangeLog @@ -1,3 +1,15 @@ +1998-10-24 Marc Horowitz + + * gss-server.c (sign_server): fix the text heuristic to recognize + whitespace as text. + (main): clean up file descriptors properly after each + connection. + + * gss-client.c (read_file): properly handle empty files + + * gss-client.c: (call_server): NUL-terminate the contents + of non-empty files on the wire. + Wed Feb 18 15:27:32 1998 Tom Yu * Makefile.in: Remove trailing slash from BUILDTOP. Fix up diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c index e0bca99c4..33a7e963a 100644 --- a/src/appl/gss-sample/gss-client.c +++ b/src/appl/gss-sample/gss-client.c @@ -239,25 +239,29 @@ void read_file(file_name, in_buf) exit(1); } in_buf->length = stat_buf.st_size; - in_buf->value = malloc(in_buf->length); - if (in_buf->value == 0) { + + if (in_buf->length == 0) { + in_buf->value = NULL; + return; + } + + if ((in_buf->value = malloc(in_buf->length)) == 0) { fprintf(stderr, "Couldn't allocate %d byte buffer for reading file\n", in_buf->length); exit(1); } - memset(in_buf->value, 0, in_buf->length); - for (bytes_in = 0; bytes_in < in_buf->length; bytes_in += count) { - count = read(fd, in_buf->value, in_buf->length); - if (count < 0) { - perror("read"); - exit(1); - } - if (count == 0) - break; + + /* this code used to check for incomplete reads, but you can't get + an incomplete read on any file for which fstat() is meaningful */ + + count = read(fd, in_buf->value, in_buf->length); + if (count < 0) { + perror("read"); + exit(1); } - if (bytes_in != count) + if (count < in_buf->length) fprintf(stderr, "Warning, only read in %d bytes, expected %d\n", - bytes_in, count); + count, in_buf->length); } /* @@ -281,8 +285,7 @@ void read_file(file_name, in_buf) * seals msg in a GSS-API token with gss_seal, sends it to the server, * reads back a GSS-API signature block for msg from the server, and * verifies it with gss_verify. -1 is returned if any step fails, - * otherwise 0 is returned. - */ + * otherwise 0 is returned. */ int call_server(host, port, oid, service_name, deleg_flag, msg, use_file) char *host; u_short port; @@ -410,7 +413,7 @@ int call_server(host, port, oid, service_name, deleg_flag, msg, use_file) } else { /* Seal the message */ in_buf.value = msg; - in_buf.length = strlen(msg) + 1; + in_buf.length = strlen(msg); } maj_stat = gss_wrap(&min_stat, context, 1, GSS_C_QOP_DEFAULT, diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c index ef9d49582..3e9ff0959 100644 --- a/src/appl/gss-sample/gss-server.c +++ b/src/appl/gss-sample/gss-server.c @@ -393,9 +393,10 @@ int sign_server(s, server_creds) fprintf(log, "Received message: "); cp = msg_buf.value; - if (isprint(cp[0]) && isprint(cp[1])) - fprintf(log, "\"%s\"\n", cp); - else { + if ((isprint(cp[0]) || isspace(cp[0])) && + (isprint(cp[1]) || isspace(cp[1]))) { + fprintf(log, "\"%.*s\"\n", msg_buf.length, msg_buf.value); + } else { printf("\n"); print_token(&msg_buf); } @@ -488,20 +489,21 @@ main(argc, argv) } else { int stmp; - if ((stmp = create_socket(port))) { + if ((stmp = create_socket(port)) >= 0) { do { /* Accept a TCP connection */ if ((s = accept(stmp, NULL, 0)) < 0) { perror("accepting connection"); - } else { - /* this return value is not checked, because there's - not really anything to do if it fails */ - sign_server(s, server_creds); + continue; } + /* this return value is not checked, because there's + not really anything to do if it fails */ + sign_server(s, server_creds); + close(s); } while (!once); - } - close(stmp); + close(stmp); + } } (void) gss_release_cred(&min_stat, &server_creds); diff --git a/src/appl/gssftp/ftp/ChangeLog b/src/appl/gssftp/ftp/ChangeLog index ed4aecb1a..b021129b0 100644 --- a/src/appl/gssftp/ftp/ChangeLog +++ b/src/appl/gssftp/ftp/ChangeLog @@ -1,3 +1,10 @@ +1998-10-26 Marc Horowitz + + * ftp.c (login): *always* encrypt the password, regardless + of the default command mode. + (do_auth): Try the new krb5 mech, and if that fails, try the + old one. + 1998-10-26 Geoffrey King * ftp.M: Add documentation for new ccc and cprotect commands. diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c index f6fb15677..d19d62c20 100644 --- a/src/appl/gssftp/ftp/ftp.c +++ b/src/appl/gssftp/ftp/ftp.c @@ -31,6 +31,32 @@ * SUCH DAMAGE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef lint static char sccsid[] = "@(#)ftp.c 5.38 (Berkeley) 4/22/91"; #endif /* not lint */ @@ -95,11 +121,13 @@ MSG_DAT msg_data; #endif /* KRB5_KRB4_COMPAT */ #ifdef GSSAPI #include -#include +/* need to include the krb5 file, because we're doing manual fallback + from the v2 mech to the v2 mech. Once there's real negotiation, + we can be generic again. */ +#include gss_ctx_id_t gcontext; #endif /* GSSAPI */ - static int kerror; /* XXX needed for all auth types */ char *auth_type; /* Authentication succeeded? If so, what type? */ @@ -308,7 +336,8 @@ login(host) if (pass == NULL) pass = mygetpass("Password:"); #ifndef NOENCRYPTION - if ((oldclevel = clevel) == PROT_S) clevel = PROT_P; + oldclevel = clevel; + clevel = PROT_P; #endif n = command("PASS %s", pass); #ifndef NOENCRYPTION @@ -1843,8 +1872,16 @@ char realm[REALM_SZ + 1]; #endif /* KRB5_KRB4_COMPAT */ #ifdef GSSAPI -/* for testing, we don't have an ftp key yet */ -char* gss_services[] = { "ftp", "host", 0 }; +struct { + const gss_OID_desc * const * mech_type; + char *service_name; +} gss_trials[] = { + { &gss_mech_krb5_v2, "ftp" }, + { &gss_mech_krb5, "ftp" }, + { &gss_mech_krb5_v2, "host" }, + { &gss_mech_krb5, "host" }, +}; +int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]); #endif /* GSSAPI */ do_auth() @@ -1870,8 +1907,7 @@ do_auth() gss_name_t target_name; gss_buffer_desc send_tok, recv_tok, *token_ptr; char stbuf[FTP_BUFSIZ]; - char **service_name, **end_service_name; - int comcode; + int comcode, trial; struct gss_channel_bindings_struct chan; chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */ chan.initiator_address.length = 4; @@ -1882,21 +1918,15 @@ do_auth() chan.application_data.length = 0; chan.application_data.value = 0; - for (end_service_name = gss_services; *end_service_name; ) - end_service_name++; - end_service_name--; - if (verbose) - printf("%s accepted as authentication type\n", "GSSAPI"); + printf("GSSAPI accepted as authentication type\n"); /* blob from gss-client */ - - for (service_name = gss_services; *service_name; service_name++) { - + for (trial = 0; trial < n_gss_trials; trial++) { /* ftp@hostname first, the host@hostname */ /* the V5 GSSAPI binding canonicalizes this for us... */ - sprintf(stbuf, "%s@%s", *service_name, hostname); + sprintf(stbuf, "%s@%s", gss_trials[trial].service_name, hostname); if (debug) fprintf(stderr, "Trying to authenticate to <%s>\n", stbuf); @@ -1922,7 +1952,7 @@ do_auth() GSS_C_NO_CREDENTIAL, &gcontext, target_name, - GSS_C_NULL_OID, + *gss_trials[trial].mech_type, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | (forward ? GSS_C_DELEG_FLAG : 0), 0, @@ -1935,7 +1965,7 @@ do_auth() if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED){ - if (service_name == end_service_name) + if (trial == n_gss_trials-1) user_gss_error(maj_stat, min_stat, "initializing context"); (void) gss_release_name(&min_stat, &target_name); /* could just be that we missed on the service name */ @@ -1946,16 +1976,28 @@ do_auth() int len = send_tok.length; reply_parse = "ADAT="; /* for command() later */ oldverbose = verbose; - verbose = 0; + verbose = (trial == n_gss_trials-1)?0:-1; kerror = radix_encode(send_tok.value, out_buf, &len, 0); if (kerror) { fprintf(stderr, "Base 64 encoding failed: %s\n", radix_error(kerror)); } else if ((comcode = command("ADAT %s", out_buf))!=COMPLETE /* && comcode != 3 (335)*/) { - fprintf(stderr, "GSSAPI ADAT failed\n"); - /* force out of loop */ - maj_stat = GSS_S_FAILURE; + if (trial == n_gss_trials-1) { + fprintf(stderr, "GSSAPI ADAT failed\n"); + /* force out of loop */ + maj_stat = GSS_S_FAILURE; + } + /* backoff to the v1 gssapi is still possible. Send + a new AUTH command. If that fails, terminate the + loop */ + if (command("AUTH %s", "GSSAPI") != CONTINUE) { + fprintf(stderr, + "GSSAPI ADAT failed, AUTH restart failed\n"); + /* force out of loop */ + maj_stat = GSS_S_FAILURE; + } + goto outer_loop; } else if (!reply_parse) { fprintf(stderr, "No authentication data received from server\n"); @@ -1979,7 +2021,7 @@ do_auth() /* get out of loop clean */ gss_complete_loop: - service_name = end_service_name; + trial = n_gss_trials-1; gss_release_buffer(&min_stat, &send_tok); gss_release_name(&min_stat, &target_name); goto outer_loop; @@ -1991,8 +2033,7 @@ do_auth() } verbose = oldverbose; if (maj_stat == GSS_S_COMPLETE) { - if (verbose) - printf("GSSAPI authentication succeeded\n"); + printf("GSSAPI authentication succeeded\n"); reply_parse = NULL; auth_type = "GSSAPI"; return(1); diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog index 494050438..55168c36b 100644 --- a/src/appl/telnet/libtelnet/ChangeLog +++ b/src/appl/telnet/libtelnet/ChangeLog @@ -1,3 +1,10 @@ +1998-10-26 Marc Horowitz + + * enc_des.c, kerberos.c: the ECB des functions don't exist + anymore, but telnet always encrypted/decrypted one block. Convert + to calls to the new crypto api, with des-cbc-raw, using a single + block. + Tue Mar 3 14:43:30 1998 Theodore Ts'o * configure.in: Change test for cgetent to use HAVE_ instead diff --git a/src/appl/telnet/libtelnet/enc_des.c b/src/appl/telnet/libtelnet/enc_des.c index f44700a73..3912b35e9 100644 --- a/src/appl/telnet/libtelnet/enc_des.c +++ b/src/appl/telnet/libtelnet/enc_des.c @@ -31,11 +31,38 @@ * SUCH DAMAGE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */ #ifdef ENCRYPTION # ifdef AUTHENTICATION # ifdef DES_ENCRYPTION +#include #include #include #ifdef __STDC__ @@ -53,6 +80,8 @@ extern encrypt_debug_mode; +extern krb5_context telnet_context; + #define CFB 0 #define OFB 1 @@ -65,20 +94,19 @@ extern encrypt_debug_mode; struct fb { - Block krbdes_key; - Schedule krbdes_sched; Block temp_feed; unsigned char fb_feed[64]; int need_start; int state[2]; int keyid[2]; int once; + int validkey; struct stinfo { Block str_output; Block str_feed; Block str_iv; - Block str_ikey; - Schedule str_sched; + unsigned char str_keybytes[8]; /* yuck */ + krb5_keyblock str_key; int str_index; int str_flagshift; } streams[2]; @@ -122,6 +150,29 @@ static void fb64_session P((Session_Key *, int, struct fb *)); void fb64_stream_key P((Block, struct stinfo *)); int fb64_keyid P((int, unsigned char *, int *, struct fb *)); +static void ecb_encrypt(stp, in, out) + struct stinfo *stp; + Block in; + Block out; +{ + krb5_error_code code; + krb5_data din; + krb5_enc_data dout; + + din.length = 8; + din.data = in; + + dout.ciphertext.length = 8; + dout.ciphertext.data = out; + dout.enctype = ENCTYPE_UNKNOWN; + + code = krb5_c_encrypt(telnet_context, &stp->str_key, 0, 0, + &din, &dout); + /* XXX I'm not sure what to do if this fails */ + if (code) + com_err("libtelnet", code, "encrypting stream data"); +} + void cfb64_init(server) int server; @@ -207,7 +258,7 @@ fb64_start(fbp, dir, server) else if ((state & NO_SEND_IV) == 0) break; - if (!VALIDKEY(fbp->krbdes_key)) { + if (!fbp->validkey) { fbp->need_start = 1; break; } @@ -218,9 +269,18 @@ fb64_start(fbp, dir, server) /* * Create a random feed and send it over. */ - des_new_random_key(fbp->temp_feed); - des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, - fbp->krbdes_sched, 1); + { + krb5_data d; + krb5_error_code code; + + d.data = fbp->temp_feed; + d.length = sizeof(fbp->temp_feed); + + if (code = krb5_c_random_make_octets(telnet_context, + &d)) + return(FAILED); + } + p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; @@ -418,23 +478,18 @@ fb64_session(key, server, fbp) int server; struct fb *fbp; { - if (!key || key->type != SK_DES) { if (encrypt_debug_mode) printf("Can't set krbdes's session key (%d != %d)\r\n", key ? key->type : -1, SK_DES); return; } - memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); - fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); - fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); + fbp->validkey = 1; + + fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]); + fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]); - if (fbp->once == 0) { - des_set_random_generator_seed(fbp->krbdes_key); - fbp->once = 1; - } - des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); /* * Now look to see if krbdes_start() was was waiting for * the key to show up. If so, go ahead an call it now @@ -551,12 +606,9 @@ fb64_stream_iv(seed, stp) Block seed; register struct stinfo *stp; { - memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block)); memcpy((void *)stp->str_output, (void *)seed, sizeof(Block)); - des_key_sched(stp->str_ikey, stp->str_sched); - stp->str_index = sizeof(Block); } @@ -565,8 +617,13 @@ fb64_stream_key(key, stp) Block key; register struct stinfo *stp; { - memcpy((void *)stp->str_ikey, (void *)key, sizeof(Block)); - des_key_sched(key, stp->str_sched); + memcpy((void *)stp->str_keybytes, (void *)key, sizeof(Block)); + stp->str_key.length = 8; + stp->str_key.contents = stp->str_keybytes; + /* the original version of this code uses des ecb mode, but + it only ever does one block at a time. cbc with a zero iv + is identical */ + stp->str_key.enctype = ENCTYPE_DES_CBC_RAW; memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); @@ -607,7 +664,7 @@ cfb64_encrypt(s, c) while (c-- > 0) { if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_output, b); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } @@ -641,7 +698,7 @@ cfb64_decrypt(data) index = stp->str_index++; if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_output, b); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ @@ -683,7 +740,7 @@ ofb64_encrypt(s, c) while (c-- > 0) { if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_feed, b); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } @@ -714,7 +771,7 @@ ofb64_decrypt(data) index = stp->str_index++; if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_feed, b); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c index 63738b53b..ed32392c9 100644 --- a/src/appl/telnet/libtelnet/kerberos.c +++ b/src/appl/telnet/libtelnet/kerberos.c @@ -53,7 +53,38 @@ * or implied warranty. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifdef KRB4 +/* this code must be compiled in the krb5 tree. disgustingly, there + is code in here which declares structures which happen to mirror + the krb4 des structures. I didn't want to rototill this *completely* + so this is how it's going to work. --marc */ +#include #include #include #include @@ -73,6 +104,7 @@ #include "misc.h" extern auth_debug_mode; +extern krb5_context telnet_context; static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V4, }; @@ -93,6 +125,7 @@ static AUTH_DAT adat = { 0 }; #ifdef ENCRYPTION static Block session_key = { 0 }; static Schedule sched; +static krb5_keyblock krbkey; static Block challenge = { 0 }; #endif /* ENCRYPTION */ @@ -146,6 +179,9 @@ kerberos4_init(ap, server) } else { str_data[3] = TELQUAL_IS; } + + kerberos5_init(NULL, server); + return(1); } @@ -157,15 +193,18 @@ kerberos4_send(ap) Authenticator *ap; { KTEXT_ST auth; -#ifdef ENCRYPTION - Block enckey; -#endif /* ENCRYPTION */ char instance[INST_SZ]; char *realm; char *krb_realmofhost(); char *krb_get_phost(); CREDENTIALS cred; int r; +#ifdef ENCRYPTION + krb5_data data; + krb5_enc_data encdata; + krb5_error_code code; + krb5_keyblock random_key; +#endif printf("[ Trying KERBEROS4 ... ]\r\n"); if (!UserNameRequested) { @@ -216,11 +255,56 @@ kerberos4_send(ap) if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { register int i; - des_key_sched(cred.session, sched); - des_init_random_number_generator(cred.session); - des_new_random_key(session_key); - des_ecb_encrypt(session_key, session_key, sched, 0); - des_ecb_encrypt(session_key, challenge, sched, 0); + data.data = cred.session; + data.length = 8; /* sizeof(cred.session) */; + + if (code = krb5_c_random_seed(telnet_context, &data)) { + com_err("libtelnet", code, + "while seeding random number generator"); + return(0); + } + + if (code = krb5_c_make_random_key(telnet_context, + ENCTYPE_DES_CBC_RAW, + &random_key)) { + com_err("libtelnet", code, + "while creating random session key"); + return(0); + } + + /* the krb4 code uses ecb mode, but on a single block + with a zero ivec, ecb and cbc are the same */ + krbkey.enctype = ENCTYPE_DES_CBC_RAW; + krbkey.length = 8; + krbkey.contents = cred.session; + + encdata.ciphertext.data = random_key.contents; + encdata.ciphertext.length = random_key.length; + encdata.enctype = ENCTYPE_UNKNOWN; + + data.data = session_key; + data.length = 8; + + code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0, + &encdata, &data); + + krb5_free_keyblock_contents(telnet_context, &random_key); + + if (code) { + com_err("libtelnet", code, "while encrypting random key"); + return(0); + } + + encdata.ciphertext.data = session_key; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + data.data = challenge; + data.length = 8; + + code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0, + &encdata, &data); + /* * Increment the challenge by 1, and encrypt it for * later comparison. @@ -232,7 +316,19 @@ kerberos4_send(ap) if (x < 256) /* if no overflow, all done */ break; } - des_ecb_encrypt(challenge, challenge, sched, 1); + + data.data = challenge; + data.length = 8; + + encdata.ciphertext.data = challenge; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0, &data, + &encdata)) { + com_err("libtelnet", code, "while encrypting random key"); + return(0); + } } #endif /* ENCRYPTION */ @@ -253,7 +349,10 @@ kerberos4_is(ap, data, cnt) { #ifdef ENCRYPTION Session_Key skey; - Block datablock; + Block datablock, tmpkey; + krb5_data kdata; + krb5_enc_data encdata; + krb5_error_code code; #endif /* ENCRYPTION */ char realm[REALM_SZ]; char instance[INST_SZ]; @@ -317,24 +416,60 @@ kerberos4_is(ap, data, cnt) * Initialize the random number generator since it's * used later on by the encryption routine. */ - des_init_random_number_generator(session_key); - des_key_sched(session_key, sched); + + kdata.data = session_key; + kdata.length = 8; + + if (code = krb5_c_random_seed(telnet_context, &kdata)) { + com_err("libtelnet", code, + "while seeding random number generator"); + return; + } + memcpy((void *)datablock, (void *)data, sizeof(Block)); /* * Take the received encrypted challenge, and encrypt * it again to get a unique session_key for the * ENCRYPT option. */ - des_ecb_encrypt(datablock, session_key, sched, 1); + krbkey.enctype = ENCTYPE_DES_CBC_RAW; + krbkey.length = 8; + krbkey.contents = session_key; + + kdata.data = datablock; + kdata.length = 8; + + encdata.ciphertext.data = tmpkey; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0, + &kdata, &encdata)) { + com_err("libtelnet", code, "while encrypting random key"); + return; + } + skey.type = SK_DES; skey.length = 8; - skey.data = session_key; + skey.data = tmpkey; encrypt_session_key(&skey, 1); /* * Now decrypt the received encrypted challenge, * increment by one, re-encrypt it and send it back. */ - des_ecb_encrypt(datablock, challenge, sched, 0); + encdata.ciphertext.data = datablock; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + kdata.data = challenge; + kdata.length = 8; + + if (code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0, + &encdata, &kdata)) { + com_err("libtelnet", code, "while decrypting challenge"); + return; + } + for (r = 7; r >= 0; r--) { register int t; t = (unsigned int)challenge[r] + 1; @@ -342,7 +477,20 @@ kerberos4_is(ap, data, cnt) if (t < 256) /* if no overflow, all done */ break; } - des_ecb_encrypt(challenge, challenge, sched, 1); + + kdata.data = challenge; + kdata.length = 8; + + encdata.ciphertext.data = challenge; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0, + &kdata, &encdata)) { + com_err("libtelnet", code, "while decrypting challenge"); + return; + } + Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge)); #endif /* ENCRYPTION */ break; @@ -363,6 +511,10 @@ kerberos4_reply(ap, data, cnt) { #ifdef ENCRYPTION Session_Key skey; + krb5_data kdata; + krb5_enc_data encdata; + krb5_error_code code; + #endif /* ENCRYPTION */ if (cnt-- < 1) @@ -387,7 +539,21 @@ kerberos4_reply(ap, data, cnt) #else /* ENCRYPTION */ Data(ap, KRB_CHALLENGE, (void *)session_key, sizeof(session_key)); - des_ecb_encrypt(session_key, session_key, sched, 1); + + kdata.data = session_key; + kdata.length = 8; + + encdata.ciphertext.data = session_key; + encdata.ciphertext.length = 8; + encdata.enctype = ENCTYPE_UNKNOWN; + + if (code = krb5_c_encrypt(telnet_context, &krbkey, + 0, 0, &kdata, &encdata)) { + com_err("libtelnet", code, + "while encrypting session_key"); + return; + } + skey.type = SK_DES; skey.length = 8; skey.data = session_key; diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog index 6d13e63f2..7d94d0acf 100644 --- a/src/appl/telnet/telnet/ChangeLog +++ b/src/appl/telnet/telnet/ChangeLog @@ -1,3 +1,10 @@ +1998-10-26 Marc Horowitz + + * commands.c: remove calls to setuid(getuid()). This looks like + it was once an attempt to make it safe to run setuid, but it's not + safe for a number of other reasons, so there's no reason to + pretend. + Sat Oct 10 06:24:55 1998 Geoffrey King * telnet.c (telnet): Cosmetic change: Put a newline after "Waiting diff --git a/src/appl/telnet/telnet/commands.c b/src/appl/telnet/telnet/commands.c index 5c8ae3cb7..c23e199cc 100644 --- a/src/appl/telnet/telnet/commands.c +++ b/src/appl/telnet/telnet/commands.c @@ -2378,7 +2378,6 @@ tn(argc, argv) if (connected) { printf("?Already connected to %s\r\n", hostname); - setuid(getuid()); return 0; } if (argc < 2) { @@ -2419,7 +2418,6 @@ tn(argc, argv) } usage: printf("usage: %s [-l user] [-a] host-name [port]\r\n", cmd); - setuid(getuid()); return 0; } if (hostp == 0) @@ -2434,11 +2432,9 @@ tn(argc, argv) temp = sourceroute(hostp, &srp, &srlen); if (temp == 0) { herror(srp); - setuid(getuid()); return 0; } else if (temp == -1) { printf("Bad source route option: %s\r\n", hostp); - setuid(getuid()); return 0; } else { sin.sin_addr.s_addr = temp; @@ -2468,7 +2464,6 @@ tn(argc, argv) hostname = _hostname; } else { herror(hostp); - setuid(getuid()); return 0; } } @@ -2489,7 +2484,6 @@ tn(argc, argv) sin.sin_port = sp->s_port; else { printf("%s: bad port number\r\n", portp); - setuid(getuid()); return 0; } } else { @@ -2500,7 +2494,6 @@ tn(argc, argv) sp = getservbyname("telnet", "tcp"); if (sp == 0) { fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); - setuid(getuid()); return 0; } sin.sin_port = sp->s_port; @@ -2510,7 +2503,6 @@ tn(argc, argv) printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr)); do { net = socket(AF_INET, SOCK_STREAM, 0); - setuid(getuid()); if (net < 0) { perror("telnet: socket"); return 0; diff --git a/src/clients/ChangeLog b/src/clients/ChangeLog index 75b04852d..e8390d6b2 100644 --- a/src/clients/ChangeLog +++ b/src/clients/ChangeLog @@ -1,3 +1,11 @@ +1998-10-26 Marc Horowitz + + * configure.in: add kvno + +Sat Jul 25 15:00:26 1998 Sam Hartman + + * Makefile.in (LOCAL_SUBDIRS): add kvno + Wed Feb 18 15:40:02 1998 Tom Yu * Makefile.in: Remove trailing slash from thisconfigdir. diff --git a/src/clients/Makefile.in b/src/clients/Makefile.in index b793c0430..e772cf6b8 100644 --- a/src/clients/Makefile.in +++ b/src/clients/Makefile.in @@ -1,7 +1,7 @@ thisconfigdir=. BUILDTOP=$(REL)$(U) -LOCAL_SUBDIRS= klist kinit kdestroy kpasswd ksu +LOCAL_SUBDIRS= klist kinit kdestroy kpasswd ksu kvno ##WIN32##all-windows:: ##WIN32## @echo Making all in clients\klist diff --git a/src/clients/configure.in b/src/clients/configure.in index 4959bdebf..db30b09c3 100644 --- a/src/clients/configure.in +++ b/src/clients/configure.in @@ -8,6 +8,7 @@ AC_CHECK_HEADERS(unistd.h pwd.h) K5_GEN_MAKEFILE(.) K5_GEN_MAKEFILE(klist) K5_GEN_MAKEFILE(kinit) +K5_GEN_MAKEFILE(kvno) K5_GEN_MAKEFILE(kdestroy) K5_GEN_MAKEFILE(kpasswd) K5_GEN_MAKEFILE(ksu) diff --git a/src/clients/kinit/ChangeLog b/src/clients/kinit/ChangeLog index 65bcc031e..5bdf45257 100644 --- a/src/clients/kinit/ChangeLog +++ b/src/clients/kinit/ChangeLog @@ -1,3 +1,7 @@ +1998-10-26 Marc Horowitz + + * kinit.c: convert to new init_creds api + 1998-05-06 Theodore Ts'o * kinit.c (main): POSIX states that getopt returns -1 when it diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c index 6f7b840c9..f02db2e18 100644 --- a/src/clients/kinit/kinit.c +++ b/src/clients/kinit/kinit.c @@ -24,43 +24,64 @@ * Initialize a credentials cache. */ -#include "k5-int.h" +#include +#include +#include + +#ifdef GETOPT_LONG +#include "getopt.h" +#else +#include +#endif #include "com_err.h" -#include "adm_proto.h" -#include #ifdef HAVE_PWD_H #include -#endif -#define KRB5_DEFAULT_OPTIONS 0 -#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ - -extern int optind; -extern char *optarg; +void get_name_from_passwd_file(program_name, kcontext, me) + char * program_name; + krb5_context kcontext; + krb5_principal * me; +{ + struct passwd *pw; + krb5_error_code code; + if (pw = getpwuid((int) getuid())) { + if ((code = krb5_parse_name(kcontext, pw->pw_name, me))) { + com_err (program_name, code, "when parsing name %s", pw->pw_name); + exit(1); + } + } else { + fprintf(stderr, "Unable to identify user from password file\n"); + exit(1); + } +} +#else /* HAVE_PWD_H */ +void get_name_from_passwd_file(kcontext, me) + krb5_context kcontext; + krb5_principal * me; +{ + fprintf(stderr, "Unable to identify user\n"); + exit(1); +} +#endif /* HAVE_PWD_H */ -krb5_data tgtname = { - 0, - KRB5_TGS_NAME_SIZE, - KRB5_TGS_NAME +#ifdef GETOPT_LONG +/* if struct[2] == NULL, then long_getopt acts as if the short flag + struct[3] was specified. If struct[2] != NULL, then struct[3] is + stored in *(struct[2]), the array index which was specified is + stored in *index, and long_getopt() returns 0. */ + +struct option long_options[] = { + { "noforwardable", 0, NULL, 'f'+0200 }, + { "noproxiable", 0, NULL, 'p'+0200 }, + { "addresses", 0, NULL, 'A'+0200}, + { "forwardable", 0, NULL, 'f' }, + { "proxiable", 0, NULL, 'p' }, + { "noaddresses", 0, NULL, 'A'}, + { "version", 0, NULL, 0x01 }, + { NULL, 0, NULL, 0 } }; - -/* Internal prototypes */ -static krb5_error_code krb5_validate_tgt - KRB5_PROTOTYPE((krb5_context, krb5_ccache, - krb5_principal, krb5_data *)); -static krb5_error_code krb5_renew_tgt - KRB5_PROTOTYPE((krb5_context, krb5_ccache, - krb5_principal, krb5_data *)); -static krb5_error_code krb5_tgt_gen - KRB5_PROTOTYPE((krb5_context, krb5_ccache, - krb5_principal, krb5_data *, int opt)); - -/* - * Try no preauthentication first; then try the encrypted timestamp - */ -krb5_preauthtype * preauth = NULL; -krb5_preauthtype preauth_list[2] = { 0, -1 }; +#endif int main(argc, argv) @@ -68,114 +89,147 @@ main(argc, argv) char **argv; { krb5_context kcontext; + krb5_principal me = NULL; + krb5_deltat start_time = 0; + krb5_address **addresses = NULL; + krb5_get_init_creds_opt opts; + char *service_name = NULL; + krb5_keytab keytab = NULL; + char *cache_name; krb5_ccache ccache = NULL; - char *cache_name = NULL; /* -f option */ - char *keytab_name = NULL; /* -t option */ - char *service_name = NULL; /* -s option */ - krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */ - krb5_timestamp starttime = 0; - krb5_deltat rlife = 0; - int options = KRB5_DEFAULT_OPTIONS; - int option; - int errflg = 0; - krb5_error_code code; - krb5_principal me; - krb5_principal server; + enum { INIT_PW, INIT_KT, RENEW, VALIDATE} action; + int errflg = 0, idx, i; krb5_creds my_creds; - krb5_timestamp now; - krb5_address *null_addr = (krb5_address *)0; - krb5_address **addrs = (krb5_address **)0; - int use_keytab = 0; /* -k option */ - krb5_keytab keytab = NULL; - struct passwd *pw = 0; - int pwsize; - char password[255], *client_name, prompt[1024]; + krb5_error_code code; - code = krb5_init_context(&kcontext); - if (code) { - com_err(argv[0], code, "while initializing krb5"); - exit(1); - } + /* Ensure we can be driven from a pipe */ + if(!isatty(fileno(stdin))) + setvbuf(stdin, 0, _IONBF, 0); + if(!isatty(fileno(stdout))) + setvbuf(stdout, 0, _IONBF, 0); + if(!isatty(fileno(stderr))) + setvbuf(stderr, 0, _IONBF, 0); - if ((code = krb5_timeofday(kcontext, &now))) { - com_err(argv[0], code, "while getting time of day"); + if (code = krb5_init_context(&kcontext)) { + com_err(argv[0], code, "while initializing kerberos library"); exit(1); } + krb5_get_init_creds_opt_init(&opts); + + action = INIT_PW; + if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; - while ((option = getopt(argc, argv, "r:Rfpl:s:c:kt:vS:")) != -1) { - switch (option) { - case 'r': - options |= KDC_OPT_RENEWABLE; - code = krb5_string_to_deltat(optarg, &rlife); - if (code != 0 || rlife == 0) { - fprintf(stderr, "Bad lifetime value %s\n", optarg); - errflg++; + while ( +#ifdef GETOPT_LONG + (i = getopt_long(argc, argv, "r:fpAl:s:c:kt:RS:v", + long_options, &idx)) != -1 +#else + (i = getopt(argc, argv, "r:fpAl:s:c:kt:RS:v")) != -1 +#endif + ) { + switch (i) { +#ifdef GETOPT_LONG + case 1: /* Print the version */ + printf("%s\n", krb5_version); + exit(0); +#endif + case 'l': + { + krb5_deltat lifetime; + code = krb5_string_to_deltat(optarg, &lifetime); + if (code != 0 || lifetime == 0) { + fprintf(stderr, "Bad lifetime value %s\n", optarg); + errflg++; + } + krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime); } break; - case 'R': - /* renew the ticket */ - options |= KDC_OPT_RENEW; + case 'r': + { + krb5_deltat rlife; + + code = krb5_string_to_deltat(optarg, &rlife); + if (code != 0 || rlife == 0) { + fprintf(stderr, "Bad lifetime value %s\n", optarg); + errflg++; + } + krb5_get_init_creds_opt_set_renew_life(&opts, rlife); + } break; - case 'v': - /* validate the ticket */ - options |= KDC_OPT_VALIDATE; + case 'f': + krb5_get_init_creds_opt_set_forwardable(&opts, 1); break; - case 'S': - service_name = optarg; +#ifdef GETOPT_LONG + case 'f'+0200: + krb5_get_init_creds_opt_set_forwardable(&opts, 0); break; +#endif case 'p': - options |= KDC_OPT_PROXIABLE; + krb5_get_init_creds_opt_set_proxiable(&opts, 1); break; - case 'f': - options |= KDC_OPT_FORWARDABLE; +#ifdef GETOPT_LONG + case 'p'+0200: + krb5_get_init_creds_opt_set_proxiable(&opts, 0); break; -#ifndef NO_KEYTAB - case 'k': - use_keytab = 1; +#endif + case 'A': + krb5_get_init_creds_opt_set_address_list(&opts, NULL); break; - case 't': - if (keytab == NULL) { - keytab_name = optarg; +#ifdef GETOPT_LONG + case 'A'+0200: + krb5_os_localaddr(kcontext, &addresses); + krb5_get_init_creds_opt_set_address_list(&opts, addresses); + break; +#endif + case 's': + code = krb5_string_to_deltat(optarg, &start_time); + if (code != 0 || start_time == 0) { + krb5_timestamp abs_starttime; + krb5_timestamp now; + + code = krb5_string_to_timestamp(optarg, &abs_starttime); + if (code != 0 || abs_starttime == 0) { + fprintf(stderr, "Bad start time value %s\n", optarg); + errflg++; + } else { + if ((code = krb5_timeofday(kcontext, &now))) { + com_err(argv[0], code, + "while getting time of day"); + exit(1); + } - code = krb5_kt_resolve(kcontext, keytab_name, &keytab); + start_time = abs_starttime - now; + } + } + break; + case 'S': + service_name = optarg; + break; + case 'k': + action = INIT_KT; + break; + case 't': + if (keytab == NULL) { + code = krb5_kt_resolve(kcontext, optarg, &keytab); if (code != 0) { - com_err(argv[0], code, "resolving keytab %s", - keytab_name); - errflg++; + com_err(argv[0], code, "resolving keytab %s", optarg); + errflg++; } } else { fprintf(stderr, "Only one -t option allowed.\n"); errflg++; } break; -#endif - case 'l': - code = krb5_string_to_deltat(optarg, &lifetime); - if (code != 0 || lifetime == 0) { - fprintf(stderr, "Bad lifetime value %s\n", optarg); - errflg++; - } + case 'R': + action = RENEW; break; - case 's': - code = krb5_string_to_timestamp(optarg, &starttime); - if (code != 0 || starttime == 0) { - krb5_deltat ktmp; - code = krb5_string_to_deltat(optarg, &ktmp); - if (code == 0 && ktmp != 0) { - starttime = now + ktmp; - options |= KDC_OPT_POSTDATED; - } else { - fprintf(stderr, "Bad postdate start time value %s\n", optarg); - errflg++; - } - } else { - options |= KDC_OPT_POSTDATED; - } + case 'v': + action = VALIDATE; break; - case 'c': + case 'c': if (ccache == NULL) { cache_name = optarg; @@ -190,7 +244,6 @@ main(argc, argv) errflg++; } break; - case '?': default: errflg++; break; @@ -204,7 +257,11 @@ main(argc, argv) } if (errflg) { - fprintf(stderr, "Usage: %s [-r time] [-R] [-s time] [-v] [-puf] [-l lifetime] [-c cachename] [-k] [-t keytab] [-S target_service] [principal]\n", argv[0]); +#ifdef GETOPT_LONG + fprintf(stderr, "Usage: %s [--version] [-l lifetime] [-r renewable_life] [-f | --forwardable | --noforwardable] [-p | --proxiable | --noproxiable] [-A | --noaddresses | --addresses] [-s start_time] [-S target_service] [-k [-t keytab_file]] [-R] [-v] [-c cachename] [principal]\n", argv[0]); +#else + fprintf(stderr, "Usage: %s [-l lifetime] [-r renewable_life] [-f] [-p] [-A] [-s start_time] [-S target_service] [-k [-t keytab_file]] [-R] [-v] [-c cachename] [principal]\n", argv[0]); +#endif exit(2); } @@ -215,147 +272,51 @@ main(argc, argv) } } - if (optind != argc-1) { /* No principal name specified */ -#ifndef NO_KEYTAB - if (use_keytab) { - /* Use the default host/service name */ - code = krb5_sname_to_principal(kcontext, NULL, NULL, - KRB5_NT_SRV_HST, &me); - if (code) { - com_err(argv[0], code, - "when creating default server principal name"); - exit(1); - } - } else -#endif - { - /* Get default principal from cache if one exists */ - code = krb5_cc_get_principal(kcontext, ccache, &me); - if (code) { -#ifdef HAVE_PWD_H - /* Else search passwd file for client */ - pw = getpwuid((int) getuid()); - if (pw) { - if ((code = krb5_parse_name(kcontext,pw->pw_name, - &me))) { - com_err (argv[0], code, "when parsing name %s", - pw->pw_name); - exit(1); - } - } else { - fprintf(stderr, - "Unable to identify user from password file\n"); - exit(1); - } -#else /* HAVE_PWD_H */ - fprintf(stderr, "Unable to identify user\n"); - exit(1); -#endif /* HAVE_PWD_H */ - } - } - } /* Use specified name */ - else if ((code = krb5_parse_name (kcontext, argv[optind], &me))) { - com_err (argv[0], code, "when parsing name %s",argv[optind]); - exit(1); - } - - if ((code = krb5_unparse_name(kcontext, me, &client_name))) { - com_err (argv[0], code, "when unparsing name"); - exit(1); - } - - memset((char *)&my_creds, 0, sizeof(my_creds)); - - my_creds.client = me; - - if (service_name == NULL) { - if((code = krb5_build_principal_ext(kcontext, &server, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - tgtname.length, tgtname.data, - krb5_princ_realm(kcontext, me)->length, - krb5_princ_realm(kcontext, me)->data, - 0))) { - com_err(argv[0], code, "while building server name"); - exit(1); - } - } else { - if ((code = krb5_parse_name(kcontext, service_name, &server))) { - com_err(argv[0], code, "while parsing service name %s", - service_name); - exit(1); - } - } - - my_creds.server = server; - - if (options & KDC_OPT_POSTDATED) { - my_creds.times.starttime = starttime; - my_creds.times.endtime = starttime + lifetime; + if (optind == argc-1) { + /* Use specified name */ + if ((code = krb5_parse_name (kcontext, argv[optind], &me))) { + com_err (argv[0], code, "when parsing name %s",argv[optind]); + exit(1); + } } else { - my_creds.times.starttime = 0; /* start timer when request - gets to KDC */ - my_creds.times.endtime = now + lifetime; - } - if (options & KDC_OPT_RENEWABLE) { - my_creds.times.renew_till = now + rlife; - } else - my_creds.times.renew_till = 0; - - if (options & KDC_OPT_VALIDATE) { - /* don't use get_in_tkt, just use mk_req... */ - krb5_data outbuf; - - code = krb5_validate_tgt(kcontext, ccache, server, &outbuf); - if (code) { - com_err (argv[0], code, "validating tgt"); - exit(1); + /* No principal name specified */ + if (action == INIT_KT) { + /* Use the default host/service name */ + if (code = krb5_sname_to_principal(kcontext, NULL, NULL, + KRB5_NT_SRV_HST, &me)) { + com_err(argv[0], code, + "when creating default server principal name"); + exit(1); + } + } else { + /* Get default principal from cache if one exists */ + if (code = krb5_cc_get_principal(kcontext, ccache, &me)) + get_name_from_passwd_file(argv[0], kcontext, &me); } - /* should be done... */ - exit(0); } - - if (options & KDC_OPT_RENEW) { - /* don't use get_in_tkt, just use mk_req... */ - krb5_data outbuf; - - code = krb5_renew_tgt(kcontext, ccache, server, &outbuf); - if (code) { - com_err (argv[0], code, "renewing tgt"); - exit(1); - } - /* should be done... */ - exit(0); + + switch (action) { + case INIT_PW: + code = krb5_get_init_creds_password(kcontext, &my_creds, me, NULL, + krb5_prompter_posix, NULL, + start_time, service_name, + &opts); + break; + case INIT_KT: + code = krb5_get_init_creds_keytab(kcontext, &my_creds, me, keytab, + start_time, service_name, + &opts); + break; + case VALIDATE: + code = krb5_get_validated_creds(kcontext, &my_creds, me, ccache, + service_name); + break; + case RENEW: + code = krb5_get_renewed_creds(kcontext, &my_creds, me, ccache, + service_name); + break; } -#ifndef NO_KEYTAB - if (!use_keytab) -#endif - { - (void) sprintf(prompt, "Password for %.*s: ", - sizeof(prompt)-32, (char *) client_name); - - pwsize = sizeof(password); - code = krb5_read_password(kcontext, prompt, 0, password, &pwsize); - if (code || pwsize == 0) { - fprintf(stderr, "Error while reading password for '%s'\n", - client_name); - memset(password, 0, sizeof(password)); - exit(1); - } - - code = krb5_get_in_tkt_with_password(kcontext, options, addrs, - NULL, preauth, password, 0, - &my_creds, 0); - memset(password, 0, sizeof(password)); -#ifndef NO_KEYTAB - } else { - code = krb5_get_in_tkt_with_keytab(kcontext, options, addrs, - NULL, preauth, keytab, 0, - &my_creds, 0); -#endif - } - if (code) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) fprintf (stderr, "%s: Password incorrect\n", argv[0]); @@ -364,86 +325,27 @@ main(argc, argv) exit(1); } - code = krb5_cc_initialize (kcontext, ccache, me); - if (code != 0) { + if (code = krb5_cc_initialize(kcontext, ccache, me)) { com_err (argv[0], code, "when initializing cache %s", cache_name?cache_name:""); exit(1); } - code = krb5_cc_store_cred(kcontext, ccache, &my_creds); - if (code) { + if (code = krb5_cc_store_cred(kcontext, ccache, &my_creds)) { com_err (argv[0], code, "while storing credentials"); exit(1); } - /* my_creds is pointing at server */ - krb5_free_principal(kcontext, server); + if (me) + krb5_free_principal(kcontext, me); + if (keytab) + krb5_kt_close(kcontext, keytab); + if (ccache) + krb5_cc_close(kcontext, ccache); + if (addresses) + krb5_free_addresses(kcontext, addresses); krb5_free_context(kcontext); - + exit(0); } - -#define VALIDATE 0 -#define RENEW 1 - -/* stripped down version of krb5_mk_req */ -static krb5_error_code krb5_validate_tgt(context, ccache, server, outbuf) - krb5_context context; - krb5_ccache ccache; - krb5_principal server; /* tgtname */ - krb5_data *outbuf; -{ - return krb5_tgt_gen(context, ccache, server, outbuf, VALIDATE); -} - -/* stripped down version of krb5_mk_req */ -static krb5_error_code krb5_renew_tgt(context, ccache, server, outbuf) - krb5_context context; - krb5_ccache ccache; - krb5_principal server; /* tgtname */ - krb5_data *outbuf; -{ - return krb5_tgt_gen(context, ccache, server, outbuf, RENEW); -} - - -/* stripped down version of krb5_mk_req */ -static krb5_error_code krb5_tgt_gen(context, ccache, server, outbuf, opt) - krb5_context context; - krb5_ccache ccache; - krb5_principal server; /* tgtname */ - krb5_data *outbuf; - int opt; -{ - krb5_error_code retval; - krb5_creds * credsp; - krb5_creds creds; - - /* obtain ticket & session key */ - memset((char *)&creds, 0, sizeof(creds)); - if ((retval = krb5_copy_principal(context, server, &creds.server))) - goto cleanup; - - if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) - goto cleanup_creds; - - if(opt == VALIDATE) { - if ((retval = krb5_get_credentials_validate(context, 0, - ccache, &creds, &credsp))) - goto cleanup_creds; - } else { - if ((retval = krb5_get_credentials_renew(context, 0, - ccache, &creds, &credsp))) - goto cleanup_creds; - } - - /* we don't actually need to do the mk_req, just get the creds. */ -cleanup_creds: - krb5_free_cred_contents(context, &creds); - -cleanup: - - return retval; -} diff --git a/src/clients/klist/ChangeLog b/src/clients/klist/ChangeLog index 3150210e4..20feffb35 100644 --- a/src/clients/klist/ChangeLog +++ b/src/clients/klist/ChangeLog @@ -1,3 +1,9 @@ +1998-10-26 Marc Horowitz + + * klist.c: add -a flag to print the ticket address, and -n flag to + do so without attempting resolution. Make klist use the new api + for stringifying enctypes. + Tue Aug 11 23:38:53 1998 Matthew D Hancher * klist.c (do_ccache): Properly check the return value of diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c index 6d05f822d..deb5f44bc 100644 --- a/src/clients/klist/klist.c +++ b/src/clients/klist/klist.c @@ -30,11 +30,13 @@ #include #include #include +#include +#include extern int optind; extern char *optarg; int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0; -int show_etype = 0; +int show_etype = 0, show_addresses = 0, no_resolve = 0; char *defname; char *progname; krb5_int32 now; @@ -50,6 +52,7 @@ void show_credential KRB5_PROTOTYPE((char *, void do_ccache KRB5_PROTOTYPE((char *)); void do_keytab KRB5_PROTOTYPE((char *)); void printtime KRB5_PROTOTYPE((time_t)); +void one_addr KRB5_PROTOTYPE((krb5_address *)); void fillit KRB5_PROTOTYPE((FILE *, int, int)); #define DEFAULT 0 @@ -58,7 +61,7 @@ void fillit KRB5_PROTOTYPE((FILE *, int, int)); void usage() { - fprintf(stderr, "Usage: %s [[-c] [-f] [-e] [-s]] [-k [-t] [-K]] [name]\n", + fprintf(stderr, "Usage: %s [[-c] [-f] [-e] [-s] [-a] [-n]] [-k [-t] [-K]] [name]\n", progname); fprintf(stderr, "\t-c specifies credentials cache, -k specifies keytab"); fprintf(stderr, ", -c is default\n"); @@ -66,6 +69,8 @@ void usage() fprintf(stderr, "\t\t-f shows credentials flags\n"); fprintf(stderr, "\t\t-e shows the encryption type\n"); fprintf(stderr, "\t\t-s sets exit status based on valid tgt existence\n"); + fprintf(stderr, "\t\t-a displays the address list\n"); + fprintf(stderr, "\t\t\t-n do not reverse-resolve\n"); fprintf(stderr, "\toptions for keytabs:\n"); fprintf(stderr, "\t\t-t shows keytab entry timestamps\n"); fprintf(stderr, "\t\t-K shows keytab entry DES keys\n"); @@ -114,6 +119,12 @@ main(argc, argv) case 's': status_only = 1; break; + case 'n': + no_resolve = 1; + break; + case 'a': + show_addresses = 1; + break; case 'c': if (mode != DEFAULT) usage(); mode = CCACHE; @@ -220,8 +231,8 @@ void do_keytab(name) printf(" "); } printf("%s", pname); -if (show_etype) - printf(" (%s) " , etype_string(entry.key.enctype)); + if (show_etype) + printf(" (%s) " , etype_string(entry.key.enctype)); if (show_keys) { printf(" (0x"); { @@ -352,26 +363,15 @@ char * etype_string(enctype) krb5_enctype enctype; { - static char buf[12]; + static char buf[100]; + krb5_error_code retval; - switch (enctype) { - case ENCTYPE_DES_CBC_CRC: - return "DES-CBC-CRC"; - break; - case ENCTYPE_DES_CBC_MD4: - return "DES-CBC-MD4"; - break; - case ENCTYPE_DES_CBC_MD5: - return "DES-CBC-MD5"; - break; - case ENCTYPE_DES3_CBC_SHA: - return "DES3-CBC-SHA"; - break; - default: + if ((retval = krb5_enctype_to_string(enctype, buf, sizeof(buf)))) { + /* XXX if there's an error != EINVAL, I should probably report it */ sprintf(buf, "etype %d", enctype); - return buf; - break; } + + return buf; } char * @@ -498,8 +498,9 @@ show_credential(progname, kcontext, cred) fputs("\t",stdout); else fputs(", ",stdout); - printf("Etype (skey, tkt): %s, %s ", - etype_string(cred->keyblock.enctype), + printf("Etype (skey, tkt): %s, ", + etype_string(cred->keyblock.enctype)); + printf("%s ", etype_string(tkt->enc_part.enctype)); krb5_free_ticket(kcontext, tkt); extra_field++; @@ -508,10 +509,52 @@ show_credential(progname, kcontext, cred) /* if any additional info was printed, extra_field is non-zero */ if (extra_field) putchar('\n'); + + + if (show_addresses) { + if (!cred->addresses || !cred->addresses[0]) { + printf("\tAddresses: (none)\n"); + } else { + int i; + + printf("\tAddresses: "); + one_addr(cred->addresses[0]); + + for (i=1; cred->addresses[i]; i++) { + printf(", "); + one_addr(cred->addresses[1]); + } + + printf("\n"); + } + } + free(name); free(sname); } +void one_addr(a) + krb5_address *a; +{ + struct hostent *h; + + if ((a->addrtype == ADDRTYPE_INET) && + (a->length == 4)) { + if (!no_resolve) { + h = gethostbyaddr(a->contents, 4, AF_INET); + if (h) { + printf("%s", h->h_name); + } + } + if (no_resolve || !h) { + printf("%d.%d.%d.%d", a->contents[0], a->contents[1], + a->contents[2], a->contents[3]); + } + } else { + printf("unknown addr type %d", a->addrtype); + } +} + void fillit(f, num, c) FILE *f; diff --git a/src/include/ChangeLog b/src/include/ChangeLog index b3c8848e0..d66def009 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,21 @@ +1998-10-26 Marc Horowitz + + * krb5.hin: add new interfaces for new crypto API and key + derivation/key usage. Add new (krb5_get_permitted_enctypes, + krb5_is_permitted_enctype) api for querying permitted etypes from + krb5.conf, and new auth_context flag + (KRB5_AUTH_CONTEXT_PERMIT_ALL) to override this. Fix bug in + krb5_kt_get_type. + + * k5-int.h: make changes related to new crypto API and key + derivation/key usage + +Tue Sep 1 19:32:33 1998 Tom Yu + + * krb5.hin: Add ENCTYPE_LOCAL_DES3_HMAC_SHA1, in order to deal + with marc's current des3 cryptosystem until we figure out what + we're actually going to use for a standardized cryptosystem. + Wed Jul 1 19:14:25 1998 Theodore Y. Ts'o * win-mac.h: Make size_t to be an unsigned long instead of diff --git a/src/include/k5-int.h b/src/include/k5-int.h index db82e0266..fa8824c49 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -34,6 +34,33 @@ * documentation shall at all times remain with M.I.T., and USER agrees to * preserve same. */ + +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* * This prototype for k5-int.h (Krb5 internals include file) * includes the user-visible definitions from krb5.h and then @@ -152,6 +179,8 @@ typedef unsigned char u_char; #define labs(x) abs(x) #endif +/* #define KRB5_OLD_CRYPTO is done in krb5.h */ + #endif /* KRB5_CONFIG__ */ /* @@ -500,11 +529,125 @@ void krb5_os_free_context krb5_error_code krb5_find_config_files KRB5_PROTOTYPE(()); +#endif /* KRB5_LIBOS_PROTO__ */ + +/* new encryption provider api */ + +struct krb5_enc_provider { + void (*block_size) KRB5_NPROTOTYPE + ((size_t *output)); + + /* keybytes is the input size to make_key; + keylength is the output size */ + void (*keysize) KRB5_NPROTOTYPE + ((size_t *keybytes, size_t *keylength)); + + /* ivec == 0 is an all-zeros ivec */ + krb5_error_code (*encrypt) KRB5_NPROTOTYPE + ((krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output)); + + krb5_error_code (*decrypt) KRB5_NPROTOTYPE + ((krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output)); + + krb5_error_code (*make_key) KRB5_NPROTOTYPE + ((krb5_const krb5_data *randombits, krb5_keyblock *key)); +}; + +struct krb5_hash_provider { + void (*hash_size) KRB5_NPROTOTYPE + ((size_t *output)); + + void (*block_size) KRB5_NPROTOTYPE + ((size_t *output)); + + /* this takes multiple inputs to avoid lots of copying. */ + krb5_error_code (*hash) KRB5_NPROTOTYPE + ((unsigned int icount, krb5_const krb5_data *input, krb5_data *output)); +}; + +struct krb5_keyhash_provider { + void (*hash_size) KRB5_NPROTOTYPE + ((size_t *output)); + + krb5_error_code (*hash) KRB5_NPROTOTYPE + ((krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output)); + + krb5_error_code (*verify) KRB5_NPROTOTYPE + ((krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_const krb5_data *hash, + krb5_boolean *valid)); +}; + +typedef void (*krb5_encrypt_length_func) KRB5_NPROTOTYPE +((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length)); + +typedef krb5_error_code (*krb5_crypt_func) KRB5_NPROTOTYPE +((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output)); + +typedef krb5_error_code (*krb5_str2key_func) KRB5_NPROTOTYPE +((krb5_const struct krb5_enc_provider *enc, krb5_const krb5_data *string, + krb5_const krb5_data *salt, krb5_keyblock *key)); + +struct krb5_keytypes { + krb5_enctype etype; + char *in_string; + char *out_string; + struct krb5_enc_provider *enc; + struct krb5_hash_provider *hash; + krb5_encrypt_length_func encrypt_len; + krb5_crypt_func encrypt; + krb5_crypt_func decrypt; + krb5_str2key_func str2key; +}; + +struct krb5_cksumtypes { + krb5_cksumtype ctype; + unsigned int flags; + char *in_string; + char *out_string; + /* if the hash is keyed, this is the etype it is keyed with. + Actually, it can be keyed by any etype which has the same + enc_provider as the specified etype. DERIVE checksums can + be keyed with any valid etype. */ + krb5_enctype keyed_etype; + /* I can't statically initialize a union, so I'm just going to use + two pointers here. The keyhash is used if non-NULL. If NULL, + then HMAC/hash with derived keys is used if the relevant flag + is set. Otherwise, a non-keyed hash is computed. This is all + kind of messy, but so is the krb5 api. */ + struct krb5_keyhash_provider *keyhash; + struct krb5_hash_provider *hash; +}; + +#define KRB5_CKSUMFLAG_DERIVE 0x0001 +#define KRB5_CKSUMFLAG_NOT_COLL_PROOF 0x0002 /* - * in here to deal with stuff from lib/crypto/os + * in here to deal with stuff from lib/crypto */ +void krb5_nfold +KRB5_PROTOTYPE((int inbits, krb5_const unsigned char *in, + int outbits, unsigned char *out)); + +krb5_error_code krb5_hmac +KRB5_PROTOTYPE((krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, unsigned int icount, + krb5_const krb5_data *input, krb5_data *output)); + + +#ifdef KRB5_OLD_CRYPTO +/* old provider api */ + typedef struct _krb5_cryptosystem_entry { krb5_magic magic; krb5_error_code (*encrypt_func) KRB5_NPROTOTYPE(( krb5_const_pointer /* in */, @@ -573,23 +716,6 @@ typedef struct _krb5_checksum_entry { unsigned int uses_key:1; } krb5_checksum_entry; - -/* This array is indexed by encryption type */ -extern krb5_cs_table_entry * NEAR krb5_csarray[]; -extern int krb5_max_cryptosystem; - -/* This array is indexed by key type */ -extern krb5_cs_table_entry * NEAR krb5_enctype_array[]; -extern krb5_enctype krb5_max_enctype; - -/* This array is indexed by checksum type */ -extern krb5_checksum_entry * NEAR krb5_cksumarray[]; -extern krb5_cksumtype krb5_max_cksum; - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_random_confounder - KRB5_PROTOTYPE((size_t, - krb5_pointer )); - krb5_error_code krb5_crypto_os_localaddr KRB5_PROTOTYPE((krb5_address ***)); @@ -599,7 +725,15 @@ krb5_error_code krb5_crypto_us_timeofday time_t gmt_mktime KRB5_PROTOTYPE((struct tm *)); -#endif /* KRB5_LIBOS_PROTO__ */ +#endif /* KRB5_OLD_CRYPTO */ + +/* this helper fct is in libkrb5, but it makes sense declared here. */ + +krb5_error_code krb5_encrypt_helper +KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key, + krb5_keyusage usage, krb5_const krb5_data *plain, + krb5_enc_data *cipher)); + /* * End "los-proto.h" */ @@ -1201,6 +1335,7 @@ krb5_error_code krb5_encode_kdc_rep KRB5_PROTOTYPE((krb5_context, krb5_const krb5_msgtype, krb5_const krb5_enc_kdc_rep_part *, + int using_subkey, krb5_const krb5_keyblock *, krb5_kdc_rep *, krb5_data ** )); diff --git a/src/include/kerberosIV/ChangeLog b/src/include/kerberosIV/ChangeLog index 85f624b06..0ecf2b09e 100644 --- a/src/include/kerberosIV/ChangeLog +++ b/src/include/kerberosIV/ChangeLog @@ -1,3 +1,9 @@ +Thu Sep 17 18:23:26 1998 Tom Yu + + * krb_db.h: ifdef out the declarations for kerb_get_* and + kerb_db_* to avoid problems with krb4 compat code in the kdc, + which declares some of these static. + Wed Feb 18 15:51:41 1998 Tom Yu * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/include/kerberosIV/krb_db.h b/src/include/kerberosIV/krb_db.h index 4925137c4..dc2265d96 100644 --- a/src/include/kerberosIV/krb_db.h +++ b/src/include/kerberosIV/krb_db.h @@ -104,11 +104,13 @@ typedef struct { } Dba; +#if 0 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 #endif /* KRB_DB_DEFS */ diff --git a/src/include/krb5.hin b/src/include/krb5.hin index 994952404..8b1d42f0d 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -24,6 +24,32 @@ * General definitions for Kerberos version 5. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef KRB5_GENERAL__ #define KRB5_GENERAL__ @@ -54,6 +80,7 @@ #define THREEPARAMOPEN(x,y,z) open(x,y,z) #endif +#define KRB5_OLD_CRYPTO #ifdef HAVE_SYS_TYPES_H #include @@ -131,10 +158,11 @@ typedef unsigned int krb5_boolean; typedef unsigned int krb5_msgtype; typedef unsigned int krb5_kvno; -typedef unsigned int krb5_addrtype; -typedef unsigned int krb5_enctype; -typedef unsigned int krb5_cksumtype; -typedef unsigned int krb5_authdatatype; +typedef krb5_int32 krb5_addrtype; +typedef krb5_int32 krb5_enctype; +typedef krb5_int32 krb5_cksumtype; +typedef krb5_int32 krb5_authdatatype; +typedef krb5_int32 krb5_keyusage; typedef krb5_int32 krb5_preauthtype; /* This may change, later on */ typedef krb5_int32 krb5_flags; @@ -286,6 +314,17 @@ typedef struct _krb5_keyblock { krb5_octet FAR *contents; } krb5_keyblock; +#ifdef KRB5_OLD_CRYPTO +typedef struct _krb5_encrypt_block { + krb5_magic magic; + krb5_enctype crypto_entry; /* to call krb5_encrypt_size, you need + this. it was a pointer, but it + doesn't have to be. gross. */ + krb5_keyblock FAR *key; + krb5_int32 priv_size; /* Size of private data */ +} krb5_encrypt_block; +#endif + typedef struct _krb5_checksum { krb5_magic magic; krb5_cksumtype checksum_type; /* checksum type */ @@ -293,15 +332,6 @@ typedef struct _krb5_checksum { krb5_octet FAR *contents; } krb5_checksum; -typedef struct _krb5_encrypt_block { - krb5_magic magic; - struct _krb5_cryptosystem_entry FAR * crypto_entry; - krb5_keyblock FAR *key; - krb5_pointer priv; /* for private use, e.g. DES - key schedules */ - krb5_int32 priv_size; /* Size of private data */ -} krb5_encrypt_block; - typedef struct _krb5_enc_data { krb5_magic magic; krb5_enctype enctype; @@ -315,9 +345,15 @@ typedef struct _krb5_enc_data { #define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */ #define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */ #define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */ +/* XXX deprecated? */ #define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */ #define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */ +#define ENCTYPE_DES3_HMAC_SHA1 0x0007 +#define ENCTYPE_DES_HMAC_SHA1 0x0008 #define ENCTYPE_UNKNOWN 0x01ff +/* local crud */ +/* marc's DES-3 with 32-bit length */ +#define ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007 #define CKSUMTYPE_CRC32 0x0001 #define CKSUMTYPE_RSA_MD4 0x0002 @@ -328,7 +364,7 @@ typedef struct _krb5_enc_data { #define CKSUMTYPE_RSA_MD5 0x0007 #define CKSUMTYPE_RSA_MD5_DES 0x0008 #define CKSUMTYPE_NIST_SHA 0x0009 -#define CKSUMTYPE_HMAC_SHA 0x000a +#define CKSUMTYPE_HMAC_SHA1 0x000a #ifndef krb5_roundup /* round x up to nearest multiple of y */ @@ -349,8 +385,118 @@ typedef struct _krb5_enc_data { extern "C" { #endif +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_encrypt + KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key, + krb5_keyusage usage, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_enc_data *output)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_decrypt + KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key, + krb5_keyusage usage, krb5_const krb5_data *ivec, + krb5_const krb5_enc_data *input, krb5_data *output)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_encrypt_length + KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, + size_t inputlen, size_t *length)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_block_size + KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, + size_t *blocksize)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_make_random_key + KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, + krb5_keyblock *random_key)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_random_make_octets + KRB5_PROTOTYPE((krb5_context context, krb5_data *data)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_random_seed + KRB5_PROTOTYPE((krb5_context context, krb5_data *data)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_string_to_key + KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, + krb5_const krb5_data *string, krb5_const krb5_data *salt, + krb5_keyblock *key)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_enctype_compare + KRB5_PROTOTYPE((krb5_context context, krb5_enctype e1, krb5_enctype e2, + krb5_boolean *similar)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_make_checksum + KRB5_PROTOTYPE((krb5_context context, krb5_cksumtype cksumtype, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *input, krb5_checksum *cksum)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_verify_checksum + KRB5_PROTOTYPE((krb5_context context, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *data, + krb5_const krb5_checksum *cksum, + krb5_boolean *valid)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_checksum_length + KRB5_PROTOTYPE((krb5_context context, krb5_cksumtype cksumtype, + size_t *length)); + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV + krb5_c_keyed_checksum_types + KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, + unsigned int *count, krb5_cksumtype **cksumtypes)); + +#define KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS 1 +#define KRB5_KEYUSAGE_KDC_REP_TICKET 2 +#define KRB5_KEYUSAGE_AS_REP_ENCPART 3 +#define KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY 4 +#define KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY 5 +#define KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM 6 +#define KRB5_KEYUSAGE_TGS_REQ_AUTH 7 +#define KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY 8 +#define KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY 9 +#define KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM 10 +#define KRB5_KEYUSAGE_AP_REQ_AUTH 11 +#define KRB5_KEYUSAGE_AP_REP_ENCPART 12 +#define KRB5_KEYUSAGE_KRB_PRIV_ENCPART 13 +#define KRB5_KEYUSAGE_KRB_CRED_ENCPART 14 +#define KRB5_KEYUSAGE_KRB_SAFE_CKSUM 15 +#define KRB5_KEYUSAGE_APP_DATA_ENCRYPT 16 +#define KRB5_KEYUSAGE_APP_DATA_CKSUM 17 +#define KRB5_KEYUSAGE_KRB_ERROR_CKSUM 18 +#define KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM 19 +#define KRB5_KEYUSAGE_AD_MTE 20 +#define KRB5_KEYUSAGE_AD_ITE 21 + +/* XXX need to register these */ + +#define KRB5_KEYUSAGE_GSS_TOK_MIC 22 +#define KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG 23 +#define KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV 24 + + +krb5_boolean KRB5_CALLCONV valid_enctype + KRB5_PROTOTYPE((krb5_const krb5_enctype ktype)); +krb5_boolean KRB5_CALLCONV valid_cksumtype + KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); +krb5_boolean KRB5_CALLCONV is_coll_proof_cksum + KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); +krb5_boolean KRB5_CALLCONV is_keyed_cksum + KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); + +#ifdef KRB5_OLD_CRYPTO /* - * cryptosystem routine prototypes + * old cryptosystem routine prototypes. These are now layered + * on top of the functions above. */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_encrypt KRB5_PROTOTYPE((krb5_context context, @@ -402,7 +548,7 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_use_enctype krb5_const krb5_enctype enctype)); KRB5_DLLIMP size_t KRB5_CALLCONV krb5_encrypt_size KRB5_PROTOTYPE((krb5_const size_t length, - krb5_const struct _krb5_cryptosystem_entry FAR * crypto)); + krb5_enctype crypto)); KRB5_DLLIMP size_t KRB5_CALLCONV krb5_checksum_size KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_cksumtype ctype)); @@ -422,15 +568,6 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_verify_checksum KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_random_confounder KRB5_PROTOTYPE((size_t, krb5_pointer)); -krb5_boolean KRB5_CALLCONV valid_enctype - KRB5_PROTOTYPE((krb5_const krb5_enctype ktype)); -krb5_boolean KRB5_CALLCONV valid_cksumtype - KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); -krb5_boolean KRB5_CALLCONV is_coll_proof_cksum - KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); -krb5_boolean KRB5_CALLCONV is_keyed_cksum - KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype)); - krb5_error_code krb5_encrypt_data KRB5_PROTOTYPE((krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_data *data, @@ -440,6 +577,9 @@ krb5_error_code krb5_decrypt_data KRB5_PROTOTYPE((krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_enc_data *data, krb5_data *enc_data)); + +#endif /* KRB5_OLD_CRYPTO */ + #ifdef __cplusplus } #endif @@ -961,6 +1101,7 @@ typedef struct _krb5_pwd_data { #define KRB5_AUTH_CONTEXT_RET_TIME 0x00000002 #define KRB5_AUTH_CONTEXT_DO_SEQUENCE 0x00000004 #define KRB5_AUTH_CONTEXT_RET_SEQUENCE 0x00000008 +#define KRB5_AUTH_CONTEXT_PERMIT_ALL 0x00000010 typedef struct krb5_replay_data { krb5_timestamp timestamp; @@ -1222,7 +1363,7 @@ typedef struct _krb5_kt_ops { void * serializer; } krb5_kt_ops; -#define krb5_kt_get_type(context, keytab) (*(keytab)->ops->prefix) +#define krb5_kt_get_type(context, keytab) ((keytab)->ops->prefix) #define krb5_kt_get_name(context, keytab, name, namelen) krb5_x((keytab)->ops->get_name,(context, keytab,name,namelen)) #define krb5_kt_close(context, keytab) krb5_x((keytab)->ops->close,(context, keytab)) #define krb5_kt_get_entry(context, keytab, principal, vno, enctype, entry) krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype, entry)) @@ -1267,6 +1408,12 @@ krb5_error_code krb5_get_tgs_ktypes krb5_const_principal, krb5_enctype **)); +krb5_error_code krb5_get_permitted_enctypes + KRB5_PROTOTYPE((krb5_context, krb5_enctype **)); + +krb5_boolean krb5_is_permitted_enctype + KRB5_PROTOTYPE((krb5_context, krb5_enctype)); + /* libkrb.spec */ krb5_error_code krb5_kdc_rep_decrypt_proc KRB5_PROTOTYPE((krb5_context, @@ -1616,6 +1763,8 @@ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred_enc_part KRB5_PROTOTYPE((krb5_context, krb5_cred_enc_part FAR *)); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_checksum KRB5_PROTOTYPE((krb5_context, krb5_checksum FAR *)); +KRB5_DLLIMP void KRB5_CALLCONV krb5_free_checksum_contents + KRB5_PROTOTYPE((krb5_context, krb5_checksum FAR *)); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_keyblock KRB5_PROTOTYPE((krb5_context, krb5_keyblock FAR *)); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_keyblock_contents @@ -1636,6 +1785,8 @@ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_data_contents KRB5_PROTOTYPE((krb5_context, krb5_data FAR *)); KRB5_DLLIMP void KRB5_CALLCONV krb5_free_unparsed_name KRB5_PROTOTYPE((krb5_context, char FAR *)); +KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cksumtypes + KRB5_PROTOTYPE((krb5_context, krb5_cksumtype FAR *)); /* From krb5/os but needed but by the outside world */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_us_timeofday diff --git a/src/include/krb5/ChangeLog b/src/include/krb5/ChangeLog index 202608002..af894dad1 100644 --- a/src/include/krb5/ChangeLog +++ b/src/include/krb5/ChangeLog @@ -1,3 +1,8 @@ +1998-10-26 Marc Horowitz + + * kdb_dbc.h, kdb.h: update kdb api to be compatible with the new + crypto api. + Wed Jul 8 04:30:22 1998 Geoffrey King * adm_proto.h: Added prototype for new function krb5_klog_reopen() diff --git a/src/include/krb5/kdb.h b/src/include/krb5/kdb.h index 6a75372d1..65731279f 100644 --- a/src/include/krb5/kdb.h +++ b/src/include/krb5/kdb.h @@ -24,6 +24,31 @@ * KDC Database interface definitions. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ #ifndef KRB5_KDB5__ #define KRB5_KDB5__ @@ -208,8 +233,7 @@ krb5_error_code krb5_db_iterate krb5_error_code krb5_db_verify_master_key KRB5_PROTOTYPE((krb5_context, krb5_principal, - krb5_keyblock *, - krb5_encrypt_block *)); + krb5_keyblock *)); krb5_error_code krb5_db_store_mkey KRB5_PROTOTYPE((krb5_context, char *, @@ -224,10 +248,10 @@ krb5_error_code krb5_db_setup_mkey_name krb5_principal *)); krb5_error_code krb5_db_set_mkey - KRB5_PROTOTYPE((krb5_context, krb5_encrypt_block *)); + KRB5_PROTOTYPE((krb5_context, krb5_keyblock *)); krb5_error_code krb5_db_get_mkey - KRB5_PROTOTYPE((krb5_context, krb5_encrypt_block **)); + KRB5_PROTOTYPE((krb5_context, krb5_keyblock **)); krb5_error_code krb5_db_destroy KRB5_PROTOTYPE((krb5_context, char * )); @@ -246,7 +270,7 @@ krb5_boolean krb5_db_set_lockmode krb5_error_code krb5_db_fetch_mkey KRB5_PROTOTYPE((krb5_context, krb5_principal, - krb5_encrypt_block *, + krb5_enctype, krb5_boolean, krb5_boolean, char *, @@ -260,14 +284,14 @@ krb5_error_code krb5_db_close_database krb5_error_code krb5_dbekd_encrypt_key_data KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + const krb5_keyblock *, const krb5_keyblock *, const krb5_keysalt *, int, krb5_key_data *)); krb5_error_code krb5_dbekd_decrypt_key_data KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + const krb5_keyblock *, const krb5_key_data *, krb5_keyblock *, krb5_keysalt *)); @@ -343,7 +367,7 @@ struct __krb5_key_salt_tuple; krb5_error_code krb5_dbe_cpw KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + krb5_keyblock *, struct __krb5_key_salt_tuple *, int, char *, @@ -351,20 +375,20 @@ krb5_error_code krb5_dbe_cpw krb5_db_entry *)); krb5_error_code krb5_dbe_apw KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + krb5_keyblock *, struct __krb5_key_salt_tuple *, int, char *, krb5_db_entry *)); krb5_error_code krb5_dbe_crk KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + krb5_keyblock *, struct __krb5_key_salt_tuple *, int, krb5_db_entry *)); krb5_error_code krb5_dbe_ark KRB5_PROTOTYPE((krb5_context, - krb5_encrypt_block *, + krb5_keyblock *, struct __krb5_key_salt_tuple *, int, krb5_db_entry *)); diff --git a/src/include/krb5/kdb_dbc.h b/src/include/krb5/kdb_dbc.h index 3dfd0d841..e0bbd1b47 100644 --- a/src/include/krb5/kdb_dbc.h +++ b/src/include/krb5/kdb_dbc.h @@ -24,6 +24,32 @@ * KDC Database context definitions. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef KRB5_KDB5_DBC__ #define KRB5_KDB5_DBC__ @@ -43,7 +69,7 @@ typedef struct __krb5_db_context { int db_locks_held; /* Number of times locked */ int db_lock_mode; /* Last lock mode, e.g. greatest*/ krb5_boolean db_nb_locks; /* [Non]Blocking lock modes */ - krb5_encrypt_block *db_master_key; /* Master key of database */ + krb5_keyblock *db_master_key; /* Master key of database */ kdb5_dispatch_table *db_dispatch; /* Dispatch table */ } krb5_db_context; diff --git a/src/kadmin/cli/ChangeLog b/src/kadmin/cli/ChangeLog index 9bf1d76f0..455733b5f 100644 --- a/src/kadmin/cli/ChangeLog +++ b/src/kadmin/cli/ChangeLog @@ -1,3 +1,8 @@ +1998-10-26 Marc Horowitz + + * keytab.c (etype_string): replace the hardwired table with a call + to krb5_enctype_to_string() + Fri Feb 27 23:32:38 1998 Theodore Ts'o * Makefile.in: Changed thisconfigdir to point at the kadmin diff --git a/src/kadmin/cli/keytab.c b/src/kadmin/cli/keytab.c index df4f6ce25..8a474b92c 100644 --- a/src/kadmin/cli/keytab.c +++ b/src/kadmin/cli/keytab.c @@ -5,6 +5,32 @@ * $Source$ */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #if !defined(lint) && !defined(__CODECENTER__) static char *rcsid = "$Header$"; #endif @@ -399,26 +425,11 @@ int remove_principal(char *keytab_str, krb5_keytab keytab, char static char *etype_string(enctype) krb5_enctype enctype; { - static char buf[12]; - - switch (enctype) { - case ENCTYPE_DES_CBC_CRC: - return "DES-CBC-CRC"; - break; - case ENCTYPE_DES_CBC_MD4: - return "DES-CBC-MD4"; - break; - case ENCTYPE_DES_CBC_MD5: - return "DES-CBC-MD5"; - break; -#if 0 - case ENCTYPE_DES3_CBC_MD5: - return "DES3-CBC-MD5"; - break; -#endif - default: + static char buf[100]; + krb5_error_code ret; + + if (ret = krb5_enctype_to_string(enctype, buf, sizeof(buf))) sprintf(buf, "etype %d", enctype); - return buf; - break; - } + + return buf; } diff --git a/src/kadmin/dbutil/ChangeLog b/src/kadmin/dbutil/ChangeLog index e6ab156f9..2f0c84e73 100644 --- a/src/kadmin/dbutil/ChangeLog +++ b/src/kadmin/dbutil/ChangeLog @@ -1,8 +1,25 @@ +1998-10-27 Marc Horowitz + + * dumpv4, loadv4.c, kdb5_create.c, kdb5_stash.c, kdb5_util.c, + kadm5_create.c: convert to new crypto api + Wed Sep 30 00:02:01 1998 Theodore Y. Ts'o * dump.c: Add support for changing the master key for a database as part of creating a dump of the database. +Thu Aug 20 16:50:00 1998 Tom Yu + + * kdb5_util.c (add_random_key): Fixes to deal with absence of "-e" + flag. + +Wed Aug 19 14:52:40 1998 Tom Yu + + * kdb5_util.c (add_random_key): New function to create a new + random key for a principal while retaining the previous kvno's + keys. This is only temporary until a reasonable kadm5 interface + is made. + 1998-05-06 Theodore Ts'o * kdb5_stash.c (argv): diff --git a/src/kadmin/dbutil/dumpv4.c b/src/kadmin/dbutil/dumpv4.c index fd5d0b2f4..9eb203c3a 100644 --- a/src/kadmin/dbutil/dumpv4.c +++ b/src/kadmin/dbutil/dumpv4.c @@ -24,6 +24,32 @@ * Dump a KDC database into a V4 slave dump. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifdef KRB5_KRB4_COMPAT #include "k5-int.h" @@ -45,14 +71,13 @@ struct dump_record { char *comerr_name; FILE *f; - krb5_encrypt_block *v5master; + krb5_keyblock *v5mkey; C_Block v4_master_key; Key_schedule v4_master_key_schedule; long master_key_version; char *realm; }; -extern krb5_encrypt_block master_encblock; extern krb5_keyblock master_keyblock; extern krb5_principal master_princ; extern krb5_boolean dbactive; @@ -226,7 +251,7 @@ found_one:; principal->key_version, principal->attributes); - handle_one_key(arg, arg->v5master, &entry->key_data[ok_key], v4key); + handle_one_key(arg, arg->v5mkey, &entry->key_data[ok_key], v4key); for (i = 0; i < 8; i++) { fprintf(arg->f, "%02x", ((unsigned char*)v4key)[i]); @@ -363,26 +388,20 @@ int handle_keys(arg) exit(1); } - krb5_use_enctype(util_context, &master_encblock, DEFAULT_KDC_ENCTYPE); if (retval = krb5_db_fetch_mkey(util_context, master_princ, - &master_encblock, 0, + master_keyblock.enctype, 0, 0, global_params.stash_file, 0, &master_keyblock)) { com_err(arg->comerr_name, retval, "while reading master key"); exit(1); } - if (retval = krb5_process_key(util_context, &master_encblock, - &master_keyblock)) { - com_err(arg->comerr_name, retval, "while processing master key"); - exit(1); - } - arg->v5master = &master_encblock; + arg->v5mkey = &master_keyblock; return(0); } -handle_one_key(arg, v5master, v5key, v4key) +handle_one_key(arg, v5mkey, v5key, v4key) struct dump_record *arg; - krb5_encrypt_block *v5master; + krb5_keyblock *v5mkey; krb5_key_data *v5key; des_cblock v4key; { @@ -392,7 +411,7 @@ handle_one_key(arg, v5master, v5key, v4key) krb5_keyblock v5plainkey; /* v4key is the actual v4 key from the file. */ - if (retval = krb5_dbekd_decrypt_key_data(util_context, v5master, v5key, + if (retval = krb5_dbekd_decrypt_key_data(util_context, v5mkey, v5key, &v5plainkey, NULL)) return retval; diff --git a/src/kadmin/dbutil/kadm5_create.c b/src/kadmin/dbutil/kadm5_create.c index b60ec9759..9cedf30c4 100644 --- a/src/kadmin/dbutil/kadm5_create.c +++ b/src/kadmin/dbutil/kadm5_create.c @@ -5,6 +5,32 @@ * $Source$ */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #if !defined(lint) && !defined(__CODECENTER__) static char *rcsid = "$Header$"; #endif @@ -31,7 +57,6 @@ int add_admin_princ(void *handle, krb5_context context, extern char *progname; -extern krb5_encrypt_block master_encblock; extern krb5_keyblock master_keyblock; extern krb5_db_entry master_db; diff --git a/src/kadmin/dbutil/kdb5_create.c b/src/kadmin/dbutil/kdb5_create.c index 2e2c5f912..5aa7ae11e 100644 --- a/src/kadmin/dbutil/kdb5_create.c +++ b/src/kadmin/dbutil/kdb5_create.c @@ -24,6 +24,32 @@ * Generate (from scratch) a Kerberos KDC database. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include #include #include @@ -42,8 +68,7 @@ struct realm_info { krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; - krb5_encrypt_block *eblock; - krb5_pointer rseed; + krb5_keyblock *key; krb5_int32 nkslist; krb5_key_salt_tuple *kslist; } rblock = { /* XXX */ @@ -51,8 +76,7 @@ struct realm_info { KRB5_KDB_MAX_RLIFE, KRB5_KDB_EXPIRATION, KRB5_KDB_DEF_FLAGS, - (krb5_encrypt_block *) NULL, - (krb5_pointer) NULL, + (krb5_keyblock *) NULL, 1, &def_kslist }; @@ -85,7 +109,6 @@ static krb5_error_code add_principal extern krb5_keyblock master_keyblock; extern krb5_principal master_princ; -extern krb5_encrypt_block master_encblock; krb5_data master_salt; krb5_data tgt_princ_entries[] = { @@ -133,7 +156,7 @@ void kdb5_create(argc, argv) int pw_size = 0; int do_stash = 0; krb5_int32 crflags = KRB5_KDB_CREATE_BTREE; - krb5_data pwd; + krb5_data pwd, seed; if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; @@ -159,8 +182,6 @@ void kdb5_create(argc, argv) rblock.nkslist = global_params.num_keysalts; rblock.kslist = global_params.keysalts; - krb5_use_enctype(util_context, &master_encblock, master_keyblock.enctype); - retval = krb5_db_set_name(util_context, global_params.dbname); if (!retval) retval = EEXIST; @@ -216,50 +237,37 @@ master key name '%s'\n", com_err(argv[0], retval, "while calculated master key salt"); exit_status++; return; } - if (retval = krb5_string_to_key(util_context, &master_encblock, - &master_keyblock, &pwd, &master_salt)) { + if (retval = krb5_c_string_to_key(util_context, master_keyblock.enctype, + &pwd, &master_salt, &master_keyblock)) { com_err(argv[0], retval, "while transforming master key from password"); exit_status++; return; } - if ((retval = krb5_process_key(util_context, &master_encblock, - &master_keyblock))) { - com_err(argv[0], retval, "while processing master key"); - exit_status++; return; - } + rblock.key = &master_keyblock; + + seed.length = master_keyblock.length; + seed.data = master_keyblock.contents; - rblock.eblock = &master_encblock; - if ((retval = krb5_init_random_key(util_context, &master_encblock, - &master_keyblock, &rblock.rseed))) { + if ((retval = krb5_c_random_seed(util_context, &seed))) { com_err(argv[0], retval, "while initializing random key generator"); - (void) krb5_finish_key(util_context, &master_encblock); exit_status++; return; } if ((retval = krb5_db_create(util_context, global_params.dbname, crflags))) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, &rblock.rseed); com_err(argv[0], retval, "while creating database '%s'", global_params.dbname); exit_status++; return; } if (retval = krb5_db_fini(util_context)) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, - &rblock.rseed); com_err(argv[0], retval, "while closing current database"); exit_status++; return; } if ((retval = krb5_db_set_name(util_context, global_params.dbname))) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, &rblock.rseed); com_err(argv[0], retval, "while setting active database to '%s'", global_params.dbname); exit_status++; return; } if ((retval = krb5_db_init(util_context))) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, &rblock.rseed); com_err(argv[0], retval, "while initializing the database '%s'", global_params.dbname); exit_status++; return; @@ -268,8 +276,6 @@ master key name '%s'\n", if ((retval = add_principal(util_context, master_princ, MASTER_KEY, &rblock)) || (retval = add_principal(util_context, &tgt_princ, TGT_KEY, &rblock))) { (void) krb5_db_fini(util_context); - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, &rblock.rseed); com_err(argv[0], retval, "while adding entries to the database"); exit_status++; return; } @@ -287,8 +293,6 @@ master key name '%s'\n", } /* clean up */ (void) krb5_db_fini(util_context); - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, &rblock.rseed); memset((char *)master_keyblock.contents, 0, master_keyblock.length); free(master_keyblock.contents); if (pw_str) { @@ -315,9 +319,8 @@ tgt_keysalt_iterate(ksent, ptr) krb5_context context; krb5_error_code kret; struct iterate_args *iargs; - krb5_keyblock random_keyblock, *key; + krb5_keyblock key; krb5_int32 ind; - krb5_encrypt_block random_encblock; krb5_pointer rseed; krb5_data pwd; @@ -330,33 +333,25 @@ tgt_keysalt_iterate(ksent, ptr) * Convert the master key password into a key for this particular * encryption system. */ - krb5_use_enctype(context, &random_encblock, ksent->ks_enctype); pwd.data = mkey_password; pwd.length = strlen(mkey_password); - if (kret = krb5_string_to_key(context, &random_encblock, &random_keyblock, - &pwd, &master_salt)) - return kret; - if ((kret = krb5_init_random_key(context, &random_encblock, - &random_keyblock, &rseed))) + if (kret = krb5_c_random_seed(context, &pwd)) return kret; - + if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) { ind = iargs->dbentp->n_key_data-1; - if (!(kret = krb5_random_key(context, - &random_encblock, rseed, - &key))) { + if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype, + &key))) { kret = krb5_dbekd_encrypt_key_data(context, - iargs->rblock->eblock, - key, + iargs->rblock->key, + &key, NULL, 1, &iargs->dbentp->key_data[ind]); - krb5_free_keyblock(context, key); + krb5_free_keyblock_contents(context, &key); } } - memset((char *)random_keyblock.contents, 0, random_keyblock.length); - free(random_keyblock.contents); - (void) krb5_finish_random_key(context, &random_encblock, &rseed); + return(kret); } @@ -402,7 +397,7 @@ add_principal(context, princ, op, pblock) entry.n_key_data = 1; entry.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; - if ((retval = krb5_dbekd_encrypt_key_data(context, pblock->eblock, + if ((retval = krb5_dbekd_encrypt_key_data(context, pblock->key, &master_keyblock, NULL, 1, entry.key_data))) return retval; diff --git a/src/kadmin/dbutil/kdb5_stash.c b/src/kadmin/dbutil/kdb5_stash.c index 40084e2bb..c682f3a56 100644 --- a/src/kadmin/dbutil/kdb5_stash.c +++ b/src/kadmin/dbutil/kdb5_stash.c @@ -24,6 +24,32 @@ * Store the master database key in a file. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "com_err.h" #include @@ -33,7 +59,6 @@ extern int errno; extern krb5_keyblock master_keyblock; extern krb5_principal master_princ; -extern krb5_encrypt_block master_encblock; extern kadm5_config_params global_params; extern int exit_status; @@ -93,8 +118,6 @@ char *argv[]; exit_status++; return; } - krb5_use_enctype(context, &master_encblock, master_keyblock.enctype); - if (retval = krb5_db_set_name(context, dbname)) { com_err(argv[0], retval, "while setting active database to '%s'", dbname); @@ -116,7 +139,8 @@ char *argv[]; } /* TRUE here means read the keyboard, but only once */ - if (retval = krb5_db_fetch_mkey(context, master_princ, &master_encblock, + if (retval = krb5_db_fetch_mkey(context, master_princ, + master_keyblock.enctype, TRUE, FALSE, (char *) NULL, 0, &master_keyblock)) { com_err(argv[0], retval, "while reading master key"); @@ -124,7 +148,7 @@ char *argv[]; exit_status++; return; } if (retval = krb5_db_verify_master_key(context, master_princ, - &master_keyblock,&master_encblock)) { + &master_keyblock)) { com_err(argv[0], retval, "while verifying master key"); (void) krb5_db_fini(context); exit_status++; return; diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c index ead82aa63..0a053c8c8 100644 --- a/src/kadmin/dbutil/kdb5_util.c +++ b/src/kadmin/dbutil/kdb5_util.c @@ -24,6 +24,32 @@ * Edit a KDC database. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include #include #include @@ -60,15 +86,14 @@ usage() "\tdump [-old] [-ov] [-b6] [-verbose] [filename [princs...]]\n" "\tload [-old] [-ov] [-b6] [-verbose] [-update] filename\n" "\tdump_v4 [filename]\n" - "\tload_v4 [-t] [-n] [-v] [-K] [-s stashfile] inputfile\n"); + "\tload_v4 [-t] [-n] [-v] [-K] [-s stashfile] inputfile\n" + "\tark [-e etype_list] principal\n"); exit(1); } extern krb5_keyblock master_keyblock; extern krb5_principal master_princ; -extern krb5_encrypt_block master_encblock; krb5_db_entry master_entry; -krb5_pointer master_random; int valid_master_key = 0; int close_policy_db = 0; @@ -84,6 +109,7 @@ int load_db(int, char **); int dump_v4db(int, char **); int load_v4db(int, char **); int open_db_and_mkey(); +int add_random_key(int, char **); typedef int (*cmd_func)(int, char **); @@ -99,6 +125,7 @@ struct _cmd_table { "load", load_db, 0, "dump_v4", dump_v4db, 1, "load_v4", load_v4db, 0, + "ark", add_random_key, 1, NULL, NULL, 0, }; @@ -204,19 +231,10 @@ int main(argc, argv) (void) umask(077); master_keyblock.enctype = global_params.enctype; - if (master_keyblock.enctype != ENCTYPE_UNKNOWN) { - if (!valid_enctype(master_keyblock.enctype)) { - char tmp[32]; - if (krb5_enctype_to_string(master_keyblock.enctype, - tmp, sizeof(tmp))) - com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP, - "while setting up enctype %d", master_keyblock.enctype); - else - com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP, tmp); - exit(1); - } - krb5_use_enctype(util_context, &master_encblock, - master_keyblock.enctype); + if ((master_keyblock.enctype != ENCTYPE_UNKNOWN) && + (!valid_enctype(master_keyblock.enctype))) { + com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP, + "while setting up enctype %d", master_keyblock.enctype); } cmd = cmd_lookup(cmd_argv[0]); @@ -257,12 +275,9 @@ void set_dbname(argc, argv) return; } if (valid_master_key) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, - &master_random); - krb5_free_keyblock_contents(util_context, &master_keyblock); - master_keyblock.contents = NULL; - valid_master_key = 0; + krb5_free_keyblock_contents(util_context, &master_keyblock); + master_keyblock.contents = NULL; + valid_master_key = 0; } krb5_free_principal(util_context, master_princ); dbactive = FALSE; @@ -287,7 +302,7 @@ int open_db_and_mkey() krb5_error_code retval; int nentries; krb5_boolean more; - krb5_data scratch, pwd; + krb5_data scratch, pwd, seed; dbactive = FALSE; valid_master_key = 0; @@ -355,23 +370,15 @@ int open_db_and_mkey() /* If no encryption type is set, use the default */ if (master_keyblock.enctype == ENCTYPE_UNKNOWN) { - master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; - if (!valid_enctype(master_keyblock.enctype)) { - char tmp[32]; - if (krb5_enctype_to_string(master_keyblock.enctype, - tmp, sizeof(tmp))) - com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, - "while setting up enctype %d", master_keyblock.enctype); - else - com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, tmp); - exit(1); - } - krb5_use_enctype(util_context, &master_encblock, - master_keyblock.enctype); + master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; + if (!valid_enctype(master_keyblock.enctype)) + com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, + "while setting up enctype %d", + master_keyblock.enctype); } - retval = krb5_string_to_key(util_context, &master_encblock, - &master_keyblock, &pwd, &scratch); + retval = krb5_c_string_to_key(util_context, master_keyblock.enctype, + &pwd, &scratch, &master_keyblock); if (retval) { com_err(progname, retval, "while transforming master key from password"); @@ -380,8 +387,9 @@ int open_db_and_mkey() free(scratch.data); mkey_password = 0; } else if ((retval = krb5_db_fetch_mkey(util_context, master_princ, - &master_encblock, manual_mkey, - FALSE, global_params.stash_file, + master_keyblock.enctype, + manual_mkey, FALSE, + global_params.stash_file, 0, &master_keyblock))) { com_err(progname, retval, "while reading master key"); com_err(progname, 0, "Warning: proceeding without master key"); @@ -389,27 +397,19 @@ int open_db_and_mkey() return(0); } if ((retval = krb5_db_verify_master_key(util_context, master_princ, - &master_keyblock,&master_encblock)) - ) { + &master_keyblock))) { com_err(progname, retval, "while verifying master key"); exit_status++; krb5_free_keyblock_contents(util_context, &master_keyblock); return(1); } - if ((retval = krb5_process_key(util_context, &master_encblock, - &master_keyblock))) { - com_err(progname, retval, "while processing master key"); - exit_status++; - memset((char *)master_keyblock.contents, 0, master_keyblock.length); - krb5_free_keyblock_contents(util_context, &master_keyblock); - return(1); - } - if ((retval = krb5_init_random_key(util_context, &master_encblock, - &master_keyblock, - &master_random))) { - com_err(progname, retval, "while initializing random key generator"); + + seed.length = master_keyblock.length; + seed.data = master_keyblock.contents; + + if ((retval = krb5_c_random_seed(util_context, &seed))) { + com_err(progname, retval, "while seeding random number generator"); exit_status++; - (void) krb5_finish_key(util_context, &master_encblock); memset((char *)master_keyblock.contents, 0, master_keyblock.length); krb5_free_keyblock_contents(util_context, &master_keyblock); return(1); @@ -432,11 +432,6 @@ quit() if (finished) return 0; - if (valid_master_key) { - (void) krb5_finish_key(util_context, &master_encblock); - (void) krb5_finish_random_key(util_context, &master_encblock, - &master_random); - } retval = krb5_db_fini(util_context); memset((char *)master_keyblock.contents, 0, master_keyblock.length); finished = TRUE; @@ -447,3 +442,104 @@ quit() } return 0; } + +int +add_random_key(argc, argv) + int argc; + char **argv; +{ + krb5_error_code ret; + krb5_principal princ; + krb5_db_entry dbent; + int n, i; + krb5_boolean more; + krb5_timestamp now; + + krb5_key_salt_tuple *keysalts = NULL; + krb5_int32 num_keysalts = 0; + + int free_keysalts; + char *me = argv[0]; + char *ks_str = NULL; + char *pr_str; + + if (argc < 2) + usage(); + for (argv++, argc--; *argv; argv++, argc--) { + if (!strcmp(*argv, "-e")) { + argv++; argc--; + ks_str = *argv; + continue; + } else + break; + } + if (argc < 1) + usage(); + pr_str = *argv; + ret = krb5_parse_name(util_context, pr_str, &princ); + if (ret) { + com_err(me, ret, "while parsing principal name %s", pr_str); + return 1; + } + n = 1; + ret = krb5_db_get_principal(util_context, princ, &dbent, + &n, &more); + if (ret) { + com_err(me, ret, "while fetching principal %s", pr_str); + return 1; + } + if (n != 1) { + fprintf(stderr, "principal %s not found\n", pr_str); + return 1; + } + if (more) { + fprintf(stderr, "principal %s not unique\n", pr_str); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_string_to_keysalts(ks_str, + ", \t", ":.-", 0, + &keysalts, + &num_keysalts); + if (ret) { + com_err(me, ret, "while parsing keysalts %s", ks_str); + return 1; + } + if (!num_keysalts || keysalts == NULL) { + num_keysalts = global_params.num_keysalts; + keysalts = global_params.keysalts; + free_keysalts = 0; + } else + free_keysalts = 1; + ret = krb5_dbe_ark(util_context, &master_keyblock, + keysalts, num_keysalts, + &dbent); + if (free_keysalts) + free(keysalts); + if (ret) { + com_err(me, ret, "while randomizing principal %s", pr_str); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + dbent.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; + ret = krb5_timeofday(util_context, &now); + if (ret) { + com_err(me, ret, "while getting time"); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_dbe_update_last_pwd_change(util_context, &dbent, now); + if (ret) { + com_err(me, ret, "while setting changetime"); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_db_put_principal(util_context, &dbent, &n); + krb5_dbe_free_contents(util_context, &dbent); + if (ret) { + com_err(me, ret, "while saving principal %s", pr_str); + return 1; + } + printf("%s changed\n", pr_str); + return 0; +} diff --git a/src/kadmin/dbutil/loadv4.c b/src/kadmin/dbutil/loadv4.c index 01a4bf2a6..b7df142bd 100644 --- a/src/kadmin/dbutil/loadv4.c +++ b/src/kadmin/dbutil/loadv4.c @@ -25,6 +25,32 @@ * entries from a V4 database. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifdef KRB5_KRB4_COMPAT #include @@ -59,8 +85,7 @@ struct realm_info { krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; - krb5_encrypt_block *eblock; - krb5_pointer rseed; + krb5_keyblock *key; }; static struct realm_info rblock = { /* XXX */ @@ -92,7 +117,6 @@ static int create_local_tgt = 0; static krb5_keyblock master_keyblock; static krb5_principal master_princ; -static krb5_encrypt_block master_encblock; static krb5_data tgt_princ_entries[] = { {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME}, @@ -146,6 +170,7 @@ char *argv[]; extern kadm5_config_params global_params; long exp_time = 0; krb5_int32 crflags = KRB5_KDB_CREATE_BTREE; + krb5_data seed; retval = krb5_init_context(&context); if (retval) { @@ -218,8 +243,6 @@ char *argv[]; return; } - krb5_use_enctype(context, &master_encblock, master_keyblock.enctype); - /* If the user has not requested locking, don't modify an existing database. */ if (! tempdb) { retval = krb5_db_set_name(context, dbname); @@ -281,39 +304,32 @@ master key name '%s'\n", fflush(stdout); } - if (retval = krb5_db_fetch_mkey(context, master_princ, &master_encblock, + if (retval = krb5_db_fetch_mkey(context, master_princ, + master_keyblock.enctype, read_mkey, read_mkey, stash_file, 0, &master_keyblock)) { com_err(PROGNAME, retval, "while reading master key"); krb5_free_context(context); return; } - if (retval = krb5_process_key(context, &master_encblock, &master_keyblock)) { - com_err(PROGNAME, retval, "while processing master key"); - krb5_free_context(context); - return; - } - rblock.eblock = &master_encblock; - if (retval = krb5_init_random_key(context, &master_encblock, - &master_keyblock, &rblock.rseed)) { + rblock.key = &master_keyblock; + + seed.length = master_keyblock.length; + seed.data = master_keyblock.contents; + + if (retval = krb5_c_random_seed(context, &seed)) { com_err(PROGNAME, retval, "while initializing random key generator"); - (void) krb5_finish_key(context, &master_encblock); krb5_free_context(context); return; } if (retval = krb5_db_create(context, tempdbname, crflags)) { - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); - (void) krb5_db_destroy(context, tempdbname); com_err(PROGNAME, retval, "while creating %sdatabase '%s'", tempdb ? "temporary " : "", tempdbname); krb5_free_context(context); return; } if (retval = krb5_db_set_name(context, tempdbname)) { - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); (void) krb5_db_destroy(context, tempdbname); com_err(PROGNAME, retval, "while setting active database to '%s'", tempdbname); @@ -321,16 +337,12 @@ master key name '%s'\n", return; } if (v4init(PROGNAME, v4manual, v4dumpfile)) { - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); (void) krb5_db_destroy(context, tempdbname); krb5_free_context(context); return; } if ((retval = krb5_db_init(context)) || (retval = krb5_db_open_database(context))) { - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); (void) krb5_db_destroy(context, tempdbname); com_err(PROGNAME, retval, "while initializing the database '%s'", tempdbname); @@ -340,8 +352,6 @@ master key name '%s'\n", if (retval = add_principal(context, master_princ, MASTER_KEY, &rblock)) { (void) krb5_db_fini(context); - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); (void) krb5_db_destroy(context, tempdbname); com_err(PROGNAME, retval, "while adding K/M to the database"); krb5_free_context(context); @@ -351,8 +361,6 @@ master key name '%s'\n", if (create_local_tgt && (retval = add_principal(context, &tgt_princ, RANDOM_KEY, &rblock))) { (void) krb5_db_fini(context); - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); (void) krb5_db_destroy(context, tempdbname); com_err(PROGNAME, retval, "while adding TGT service to the database"); krb5_free_context(context); @@ -384,8 +392,6 @@ master key name '%s'\n", if (tempdb) (void) krb5_db_destroy (context, tempdbname); } - (void) krb5_finish_key(context, &master_encblock); - (void) krb5_finish_random_key(context, &master_encblock, &rblock.rseed); memset((char *)master_keyblock.contents, 0, master_keyblock.length); /* @@ -547,7 +553,7 @@ Principal *princ; keysalt.type = KRB5_KDB_SALTTYPE_V4; keysalt.data.length = 0; keysalt.data.data = (char *) NULL; - retval = krb5_dbekd_encrypt_key_data(context, rblock.eblock, + retval = krb5_dbekd_encrypt_key_data(context, rblock.key, &v4v5key, &keysalt, princ->key_version, &entry.key_data[0]); @@ -592,7 +598,7 @@ struct realm_info *pblock; { krb5_db_entry entry; krb5_error_code retval; - krb5_keyblock *rkey; + krb5_keyblock rkey; int nentries = 1; krb5_timestamp mod_time; krb5_principal mod_princ; @@ -619,7 +625,7 @@ struct realm_info *pblock; switch (op) { case MASTER_KEY: entry.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; - if (retval = krb5_dbekd_encrypt_key_data(context, pblock->eblock, + if (retval = krb5_dbekd_encrypt_key_data(context, pblock->key, &master_keyblock, (krb5_keysalt *) NULL, 1, &entry.key_data[0])) { @@ -628,19 +634,19 @@ struct realm_info *pblock; } break; case RANDOM_KEY: - if (retval = krb5_random_key(context, pblock->eblock, pblock->rseed, - &rkey)) { + if (retval = krb5_c_make_random_key(context, pblock->key->enctype, + &rkey)) { krb5_db_free_principal(context, &entry, 1); return retval; } - if (retval = krb5_dbekd_encrypt_key_data(context, pblock->eblock, - rkey, + if (retval = krb5_dbekd_encrypt_key_data(context, pblock->key, + &rkey, (krb5_keysalt *) NULL, 1, &entry.key_data[0])) { krb5_db_free_principal(context, &entry, 1); return(retval); } - krb5_free_keyblock(context, rkey); + krb5_free_keyblock_contents(context, &rkey); break; case NULL_KEY: return EOPNOTSUPP; diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog index 22f8214bd..8131a8695 100644 --- a/src/kadmin/server/ChangeLog +++ b/src/kadmin/server/ChangeLog @@ -1,3 +1,10 @@ +1998-10-27 Marc Horowitz + + * ovsec_kadmd.c: add calls to a new function + _svcauth_gssapi_unset_names() to clean up memory when shutting + down. Use krb5_overridekeyname instead of krb5_defkeyname, so the + command line takes precedence over the environment. + Wed Jul 22 00:28:57 1998 Geoffrey King * ovsec_kadmd.c (main): Cast gss_nt_krb5_name to diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c index 6ac8709c7..b8a5088d8 100644 --- a/src/kadmin/server/ovsec_kadmd.c +++ b/src/kadmin/server/ovsec_kadmd.c @@ -3,6 +3,32 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include #include #include @@ -64,7 +90,7 @@ void *global_server_handle; * it also restricts us to linking against the Kv5 GSS-API library. * Since this is *k*admind, that shouldn't be a problem. */ -extern char *krb5_defkeyname; +extern char *krb5_overridekeyname; char *build_princ_name(char *name, char *realm); void log_badauth(OM_uint32 major, OM_uint32 minor, @@ -315,7 +341,7 @@ int main(int argc, char *argv[]) htons(addr.sin_port)); } kadm5_destroy(global_server_handle); - krb5_klog_close(); + krb5_klog_close(); exit(1); } memset(&addr, 0, sizeof(addr)); @@ -386,9 +412,10 @@ int main(int argc, char *argv[]) exit(1); } - /* XXX krb5_defkeyname is an internal library global and should - go away */ - krb5_defkeyname = params.admin_keytab; + /* XXX krb5_overridekeyname is an internal library global and should + go away. This is an awful hack. */ + + krb5_overridekeyname = params.admin_keytab; /* * Try to acquire creds for the old OV services as well as the @@ -402,6 +429,7 @@ int main(int argc, char *argv[]) "failing."); fprintf(stderr, "%s: Cannot set GSS-API authentication names.\n", whoami); + _svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); krb5_klog_close(); exit(1); @@ -428,6 +456,7 @@ int main(int argc, char *argv[]) error_message(ret)); fprintf(stderr, "%s: Cannot initialize acl file: %s\n", whoami, error_message(ret)); + _svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); krb5_klog_close(); exit(1); @@ -438,6 +467,7 @@ int main(int argc, char *argv[]) krb5_klog_syslog(LOG_ERR, "Cannot detach from tty: %s", error_message(ret)); fprintf(stderr, "%s: Cannot detach from tty: %s\n", whoami, error_message(ret)); + _svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); krb5_klog_close(); exit(1); @@ -449,6 +479,7 @@ int main(int argc, char *argv[]) krb5_klog_syslog(LOG_INFO, "finished, exiting"); /* Clean up memory, etc */ + _svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); close(s); acl_finish(context, 0); @@ -934,6 +965,7 @@ void do_schpw(int s1, kadm5_config_params *params) error_message(errno)); fprintf(stderr, "Cannot create connecting socket: %s", error_message(errno)); + _svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); krb5_klog_close(); exit(1); diff --git a/src/kadmin/v4server/ChangeLog b/src/kadmin/v4server/ChangeLog index e64ee0e38..b00913cde 100644 --- a/src/kadmin/v4server/ChangeLog +++ b/src/kadmin/v4server/ChangeLog @@ -1,3 +1,18 @@ +1998-10-27 Marc Horowitz + + * admin_server.c, kadm_funcs.c, kadm_ser_wrap.c, kadm_server.h: + convert to new crypto api + +Fri Jul 31 18:17:16 1998 Tom Yu + + * kadm_ser_wrap.c (kadm_ser_init): Remove references to + master_encblock, as it's no longer needed in the new crypto API, + adjusting kdb calls accordingly. Also punt calls to use_enctype, + process_key, etc. + + * admin_server.c (clear_secrets): Remove references to + master_encblock, due to new crypto API. + Mon Jul 20 11:20:32 1998 Ezra Peisach * acl_files.c: Include stdlib.h if present. diff --git a/src/kadmin/v4server/acl_files.c b/src/kadmin/v4server/acl_files.c index 35dd6608f..22a0007de 100644 --- a/src/kadmin/v4server/acl_files.c +++ b/src/kadmin/v4server/acl_files.c @@ -332,7 +332,7 @@ char *el; 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); + s = (char *) malloc(strlen(el)+1); strcpy(s, el); h->tbl[hv] = s; h->entries++; diff --git a/src/kadmin/v4server/admin_server.c b/src/kadmin/v4server/admin_server.c index 9cd2f8fb5..90bf087c9 100644 --- a/src/kadmin/v4server/admin_server.c +++ b/src/kadmin/v4server/admin_server.c @@ -239,9 +239,6 @@ char *argv[]; static void clear_secrets() { - krb5_finish_key(kadm_context, &server_parm.master_encblock); - memset((char *)&server_parm.master_encblock, 0, - sizeof (server_parm.master_encblock)); memset((char *)server_parm.master_keyblock.contents, 0, server_parm.master_keyblock.length); server_parm.mkvno = 0L; @@ -479,7 +476,7 @@ void process_client(fd, who) } status = krb5_dbekd_decrypt_key_data(kadm_context, - &server_parm.master_encblock, + &server_parm.master_keyblock, kdatap, &cpw_skey, (krb5_keysalt *) NULL); diff --git a/src/kadmin/v4server/kadm_funcs.c b/src/kadmin/v4server/kadm_funcs.c index 1d3207300..658d4b721 100644 --- a/src/kadmin/v4server/kadm_funcs.c +++ b/src/kadmin/v4server/kadm_funcs.c @@ -591,6 +591,8 @@ des_cblock newpw; sblock.data.length = 0; sblock.data.data = (char *) NULL; retval = krb5_dbekd_encrypt_key_data(kadm_context, + /* XXX but I'm ifdef'd out here, + so I can't really test this. */ &server_parm.master_encblock, &localpw, &sblock, diff --git a/src/kadmin/v4server/kadm_ser_wrap.c b/src/kadmin/v4server/kadm_ser_wrap.c index 2c5c8076c..bca814d07 100644 --- a/src/kadmin/v4server/kadm_ser_wrap.c +++ b/src/kadmin/v4server/kadm_ser_wrap.c @@ -83,18 +83,7 @@ kadm_ser_init(inter, realm) /* setting up the database */ mkey_name = KRB5_KDB_M_NAME; -#ifdef KADM5 server_parm.master_keyblock.enctype = params->enctype; - krb5_use_enctype(kadm_context, &server_parm.master_encblock, - server_parm.master_keyblock.enctype); -#else - if (inter == 1) { - server_parm.master_keyblock.enctype = ENCTYPE_DES_CBC_MD5; - krb5_use_enctype(kadm_context, &server_parm.master_encblock, - server_parm.master_keyblock.enctype); - } else - server_parm.master_keyblock.enctype = ENCTYPE_UNKNOWN; -#endif retval = krb5_db_setup_mkey_name(kadm_context, mkey_name, realm, (char **) 0, @@ -102,24 +91,15 @@ kadm_ser_init(inter, realm) if (retval) return KADM_NO_MAST; krb5_db_fetch_mkey(kadm_context, server_parm.master_princ, - &server_parm.master_encblock, + server_parm.master_keyblock.enctype, (inter == 1), FALSE, -#ifdef KADM5 params->stash_file, -#else - (char *) NULL, -#endif NULL, &server_parm.master_keyblock); if (retval) return KADM_NO_MAST; retval = krb5_db_verify_master_key(kadm_context, server_parm.master_princ, - &server_parm.master_keyblock, - &server_parm.master_encblock); - if (retval) - return KADM_NO_VERI; - retval = krb5_process_key(kadm_context, &server_parm.master_encblock, - &server_parm.master_keyblock); + &server_parm.master_keyblock); if (retval) return KADM_NO_VERI; retval = krb5_db_get_principal(kadm_context, server_parm.master_princ, diff --git a/src/kadmin/v4server/kadm_server.h b/src/kadmin/v4server/kadm_server.h index e7a7fed27..f29327326 100644 --- a/src/kadmin/v4server/kadm_server.h +++ b/src/kadmin/v4server/kadm_server.h @@ -35,7 +35,6 @@ typedef struct { char sinst[INST_SZ]; char krbrlm[REALM_SZ]; krb5_principal sprinc; - krb5_encrypt_block master_encblock; krb5_principal master_princ; krb5_keyblock master_keyblock; krb5_deltat max_life; diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index 30cf89bdd..757ac7dc5 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,56 @@ +1998-10-27 Marc Horowitz + + * do_as_req.c, do_tgs_req.c, extern.h, kdc_preauth.c, kdc_util.c, + kerberos_v4.c, main.c: conver to new crypto api. + +Fri Sep 25 19:47:26 1998 Tom Yu + + * kerberos_v4.c (check_princ): Re-order if statements that check + for null keys to make Purify shut up. + +Thu Sep 17 18:21:51 1998 Tom Yu + + * kdc_util.c (kdc_get_server_key): Fix to not use cached tgs key + to prevent lossage when it might be out of date by always fetching + the correct kvno for the ticket out of the database. + +Tue Sep 1 19:34:30 1998 Tom Yu + + * kerberos_v4.c (compat_decrypt_key): Add + ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list of keytypes to bash. + (kerb_get_principal): Add ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list + of searched enctypes. + +Wed Aug 19 13:37:00 1998 Tom Yu + + * kerberos_v4.c (set_tgtkey): Add kvno arg to fetch an explicit + kvno. Also compare kvno as well as realm when caching the TGT + key. Declare as static. + (kerb_get_principal): Add kvno argument to permit searching for + an explicit kvno. + (kerberos_v4): Extract the kvno directly out of the krb_req, since + we know what the format is. + +Wed Aug 12 18:40:08 1998 Tom Yu + + * kerberos_v4.c: Add macro K4KDC_ENCTYPE_OK to determine whether a + given enctype is compatible with single-DES krb4. + (compat_decrypt_key): Declare as static. Change call signature to + include an output krb5_keyblock as well as an input to determine + whether the principal should be treated as a service principal. + Bash the enctype of the keyblock to raw des3 if it's full-blown + des3. + (kerb_get_principal): Add k5key and issrv arguments as in + compat_decrypt_key, mostly to pass them on there. Hardcode a + search order that includes des3 for looking up service keys. + (kerberos_v4): Call krb_create_ticket or krb_cr_tkt_krb5 as + appropriate to the key type. While we're at it, s/ktbtgt/krbtgt/ + just to avoid confusing people. + (check_princ): Add k5key and issrv args for as in + compat_decrypt_key. Fix up null key detection to only operate if + it's a single-des key. + (set_tgtkey): Call krb_set_key_krb5 if appropriate. + Tue Jul 21 20:29:38 1998 Tom Yu * replay.c (kdc_check_lookaside): diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 22d5b1b56..b6fa39d3d 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -65,10 +65,9 @@ krb5_data **response; /* filled in with a response packet */ int c_nprincs = 0, s_nprincs = 0; krb5_boolean more; krb5_timestamp kdc_time, authtime; - krb5_keyblock *session_key = 0; + krb5_keyblock session_key; krb5_keyblock encrypting_key; const char *status; - krb5_encrypt_block eblock; krb5_key_data *server_key, *client_key; krb5_enctype useenctype; #ifdef KRBCONF_KDC_MODIFIES_KDB @@ -82,6 +81,7 @@ krb5_data **response; /* filled in with a response packet */ ticket_reply.enc_part.ciphertext.data = 0; e_data.data = 0; encrypting_key.contents = 0; + session_key.contents = 0; #ifdef HAVE_NETINET_IN_H if (from->address->addrtype == ADDRTYPE_INET) @@ -172,12 +172,9 @@ krb5_data **response; /* filled in with a response packet */ errcode = KRB5KDC_ERR_ETYPE_NOSUPP; goto errout; } - krb5_use_enctype(kdc_context, &eblock, useenctype); - - if ((errcode = krb5_random_key(kdc_context, &eblock, - krb5_enctype_array[useenctype]->random_sequence, - &session_key))) { - /* random key failed */ + + if ((errcode = krb5_c_make_random_key(kdc_context, useenctype, + &session_key))) { status = "RANDOM_KEY_FAILED"; goto errout; } @@ -200,7 +197,7 @@ krb5_data **response; /* filled in with a response packet */ if (isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE)) setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE); - enc_tkt_reply.session = session_key; + enc_tkt_reply.session = &session_key; enc_tkt_reply.client = request->client; enc_tkt_reply.transited.tr_type = KRB5_DOMAIN_X500_COMPRESS; enc_tkt_reply.transited.tr_contents = empty_string; /* equivalent of "" */ @@ -312,7 +309,7 @@ krb5_data **response; /* filled in with a response packet */ /* convert server.key into a real key (it may be encrypted in the database) */ - if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, + if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, server_key, &encrypting_key, NULL))) { status = "DECRYPT_SERVER_KEY"; @@ -353,7 +350,7 @@ krb5_data **response; /* filled in with a response packet */ } /* convert client.key_data into a real key */ - if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, + if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, client_key, &encrypting_key, NULL))) { status = "DECRYPT_CLIENT_KEY"; @@ -366,7 +363,7 @@ krb5_data **response; /* filled in with a response packet */ reply.padata = 0; reply.client = request->client; reply.ticket = &ticket_reply; - reply_encpart.session = session_key; + reply_encpart.session = &session_key; if ((errcode = fetch_last_req_info(&client, &reply_encpart.last_req))) { status = "FETCH_LAST_REQ"; goto errout; @@ -397,7 +394,7 @@ krb5_data **response; /* filled in with a response packet */ reply.enc_part.enctype = encrypting_key.enctype; errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart, - &encrypting_key, &reply, response); + 0, &encrypting_key, &reply, response); krb5_free_keyblock_contents(kdc_context, &encrypting_key); encrypting_key.contents = 0; @@ -465,8 +462,8 @@ errout: } if (s_nprincs) krb5_db_free_principal(kdc_context, &server, s_nprincs); - if (session_key) - krb5_free_keyblock(kdc_context, session_key); + if (session_key.contents) + krb5_free_keyblock_contents(kdc_context, &session_key); if (ticket_reply.enc_part.ciphertext.data) { memset(ticket_reply.enc_part.ciphertext.data , 0, ticket_reply.enc_part.ciphertext.length); diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index ff6f214d3..7faf748da 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -62,7 +62,6 @@ int portnum; krb5_data **response; /* filled in with a response packet */ { krb5_keyblock * subkey; - krb5_encrypt_block eblock; krb5_kdc_req *request = 0; krb5_db_entry server; krb5_kdc_rep reply; @@ -76,7 +75,7 @@ krb5_data **response; /* filled in with a response packet */ int nprincs = 0; krb5_boolean more; krb5_timestamp kdc_time, authtime=0; - krb5_keyblock *session_key = 0; + krb5_keyblock session_key; krb5_timestamp until, rtime; krb5_keyblock encrypting_key; krb5_key_data *server_key; @@ -88,6 +87,8 @@ krb5_data **response; /* filled in with a response packet */ register int i; int firstpass = 1; const char *status = 0; + + session_key.contents = 0; retval = decode_krb5_tgs_req(pkt, &request); if (retval) @@ -258,10 +259,8 @@ tgt_again: goto cleanup; } - krb5_use_enctype(kdc_context, &eblock, useenctype); - errcode = krb5_random_key(kdc_context, &eblock, - krb5_enctype_array[useenctype]->random_sequence, - &session_key); + errcode = krb5_c_make_random_key(kdc_context, useenctype, &session_key); + if (errcode) { /* random key failed */ status = "RANDOM_KEY_FAILED"; @@ -404,20 +403,8 @@ tgt_again: /* assemble any authorization data */ if (request->authorization_data.ciphertext.data) { - krb5_encrypt_block eblock; krb5_data scratch; - /* decrypt the authdata in the request */ - if (!valid_enctype(request->authorization_data.enctype)) { - status = "BAD_AUTH_ETYPE"; - errcode = KRB5KDC_ERR_ETYPE_NOSUPP; - goto cleanup; - } - /* put together an eblock for this encryption */ - - krb5_use_enctype(kdc_context, &eblock, - request->authorization_data.enctype); - scratch.length = request->authorization_data.ciphertext.length; if (!(scratch.data = malloc(request->authorization_data.ciphertext.length))) { @@ -425,28 +412,17 @@ tgt_again: errcode = ENOMEM; goto cleanup; } - /* do any necessary key pre-processing */ - if ((errcode = krb5_process_key(kdc_context, &eblock, - header_ticket->enc_part2->session))) { - status = "AUTH_PROCESS_KEY"; - free(scratch.data); - goto cleanup; - } - /* call the encryption routine */ - if ((errcode = krb5_decrypt(kdc_context, (krb5_pointer) request->authorization_data.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { + if ((errcode = krb5_c_decrypt(kdc_context, + header_ticket->enc_part2->session, + KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY, + 0, &request->authorization_data, + &scratch))) { status = "AUTH_ENCRYPT_FAIL"; - (void) krb5_finish_key(kdc_context, &eblock); - free(scratch.data); - goto cleanup; - } - if ((errcode = krb5_finish_key(kdc_context, &eblock))) { - status = "AUTH_FINISH_KEY"; free(scratch.data); goto cleanup; } + /* scratch now has the authorization data, so we decode it */ errcode = decode_krb5_authdata(&scratch, &(request->unenc_authdata)); free(scratch.data); @@ -466,7 +442,7 @@ tgt_again: enc_tkt_reply.authorization_data = header_ticket->enc_part2->authorization_data; - enc_tkt_reply.session = session_key; + enc_tkt_reply.session = &session_key; enc_tkt_reply.client = header_ticket->enc_part2->client; enc_tkt_reply.transited.tr_type = KRB5_DOMAIN_X500_COMPRESS; enc_tkt_reply.transited.tr_contents = empty_string; /* equivalent of "" */ @@ -562,7 +538,7 @@ tgt_again: /* convert server.key into a real key (it may be encrypted * in the database) */ if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, - &master_encblock, + &master_keyblock, server_key, &encrypting_key, NULL))) { status = "DECRYPT_SERVER_KEY"; @@ -571,7 +547,6 @@ tgt_again: if ((encrypting_key.enctype == ENCTYPE_DES_CBC_CRC) && (isflagset(server.attributes, KRB5_KDB_SUPPORT_DESMD5))) encrypting_key.enctype = ENCTYPE_DES_CBC_MD5; - ticket_reply.enc_part.kvno = server_key->key_data_kvno; errcode = krb5_encrypt_tkt_part(kdc_context, &encrypting_key, &ticket_reply); krb5_free_keyblock_contents(kdc_context, &encrypting_key); @@ -579,6 +554,7 @@ tgt_again: status = "TKT_ENCRYPT"; goto cleanup; } + ticket_reply.enc_part.kvno = server_key->key_data_kvno; } /* Start assembling the response */ @@ -588,7 +564,7 @@ tgt_again: reply.enc_part.kvno = 0; /* We are using the session key */ reply.ticket = &ticket_reply; - reply_encpart.session = session_key; + reply_encpart.session = &session_key; reply_encpart.nonce = request->nonce; /* copy the time fields EXCEPT for authtime; its location @@ -616,6 +592,7 @@ tgt_again: reply.enc_part.enctype = subkey ? subkey->enctype : header_ticket->enc_part2->session->enctype; errcode = krb5_encode_kdc_rep(kdc_context, KRB5_TGS_REP, &reply_encpart, + subkey ? 1 : 0, subkey ? subkey : header_ticket->enc_part2->session, &reply, response); @@ -661,8 +638,8 @@ cleanup: free(sname); if (nprincs) krb5_db_free_principal(kdc_context, &server, 1); - if (session_key) - krb5_free_keyblock(kdc_context, session_key); + if (session_key.contents) + krb5_free_keyblock_contents(kdc_context, &session_key); if (newtransited) free(enc_tkt_reply.transited.tr_contents.data); diff --git a/src/kdc/extern.h b/src/kdc/extern.h index e8de8a7e3..c31e5c70e 100644 --- a/src/kdc/extern.h +++ b/src/kdc/extern.h @@ -56,7 +56,6 @@ typedef struct __kdc_realm_data { /* * Other per-realm data. */ - krb5_encrypt_block realm_encblock; /* Per-realm master encryption block*/ char *realm_ports; /* Per-realm KDC port */ /* * Per-realm parameters. @@ -79,7 +78,6 @@ extern kdc_realm_t *kdc_active_realm; #define kdc_context kdc_active_realm->realm_context #define max_life_for_realm kdc_active_realm->realm_maxlife #define max_renewable_life_for_realm kdc_active_realm->realm_maxrlife -#define master_encblock kdc_active_realm->realm_encblock #define master_keyblock kdc_active_realm->realm_mkey #define master_princ kdc_active_realm->realm_mprinc #define tgs_key kdc_active_realm->realm_tgskey diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index b88c77283..0324694a2 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -23,6 +23,32 @@ * Preauthentication routines for the KDC. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "kdc_util.h" #include "extern.h" @@ -365,13 +391,18 @@ verify_enc_timestamp(context, client, request, enc_tkt_reply, pa) krb5_int32 start; krb5_timestamp timenow; - enc_ts_data.data = 0; scratch.data = pa->contents; scratch.length = pa->length; + + enc_ts_data.data = 0; if ((retval = decode_krb5_enc_data(&scratch, &enc_data)) != 0) goto cleanup; + enc_ts_data.length = enc_data->ciphertext.length; + if ((enc_ts_data.data = (char *) malloc(enc_ts_data.length)) == NULL) + goto cleanup; + start = 0; while (1) { if ((retval = krb5_dbe_search_enctype(context, client, @@ -379,12 +410,14 @@ verify_enc_timestamp(context, client, request, enc_tkt_reply, pa) -1, 0, &client_key))) goto cleanup; - if ((retval = krb5_dbekd_decrypt_key_data(context, &master_encblock, + if ((retval = krb5_dbekd_decrypt_key_data(context, &master_keyblock, client_key, &key, NULL))) goto cleanup; + key.enctype = enc_data->enctype; - retval = krb5_decrypt_data(context, &key, 0, enc_data, &enc_ts_data); + retval = krb5_c_decrypt(context, &key, KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS, + 0, enc_data, &enc_ts_data); krb5_free_keyblock_contents(context, &key); if (retval == 0) break; @@ -492,6 +525,7 @@ get_etype_info(context, request, client, server, pa_data) goto cleanup; pa_data->contents = scratch->data; pa_data->length = scratch->length; + free(scratch); retval = 0; @@ -615,7 +649,6 @@ get_sam_edata(context, request, client, server, pa_data) krb5_predicted_sam_response psr; krb5_data * scratch; int i = 0; - krb5_encrypt_block eblock; krb5_keyblock encrypting_key; char response[9]; char inputblock[8]; @@ -666,6 +699,13 @@ get_sam_edata(context, request, client, server, pa_data) break; } } + + krb5_princ_component(kdc_context,newp,probeslot)->data = 0; + krb5_princ_component(kdc_context,newp,probeslot)->length = 0; + krb5_princ_size(context, newp)--; + + krb5_free_principal(kdc_context, newp); + /* if sc.sam_type is set, it worked */ if (sc.sam_type) { /* so use assoc to get the key out! */ @@ -678,14 +718,15 @@ get_sam_edata(context, request, client, server, pa_data) &assoc_key); if (retval) { char *sname; - krb5_unparse_name(kdc_context, newp, &sname); + krb5_unparse_name(kdc_context, request->client, &sname); com_err("krb5kdc", retval, "snk4 finding the enctype and key <%s>", sname); + free(sname); return retval; } /* convert server.key into a real key */ retval = krb5_dbekd_decrypt_key_data(kdc_context, - &master_encblock, + &master_keyblock, assoc_key, &encrypting_key, NULL); if (retval) { @@ -695,14 +736,10 @@ get_sam_edata(context, request, client, server, pa_data) } /* now we can use encrypting_key... */ } - } else + } else { /* SAM is not an option - so don't return as hint */ return KRB5_PREAUTH_BAD_TYPE; - - krb5_princ_component(kdc_context,newp,probeslot)->data = 0; - krb5_princ_component(kdc_context,newp,probeslot)->length = 0; - krb5_princ_size(context, newp)--; - krb5_free_principal(kdc_context, newp); + } } sc.magic = KV5M_SAM_CHALLENGE; sc.sam_flags = KRB5_SAM_USE_SAD_AS_KEY; @@ -721,21 +758,35 @@ get_sam_edata(context, request, client, server, pa_data) /* eblock is just to set the enctype */ { const krb5_enctype type = ENCTYPE_DES_CBC_MD5; - if (!valid_enctype(type)) return KRB5_PROG_ETYPE_NOSUPP; - krb5_use_enctype(context, &eblock, type); - retval = krb5_string_to_key(context, &eblock, - &psr.sam_key, &sc.sam_challenge, - 0 /* salt */); - retval = encode_krb5_predicted_sam_response(&psr, &scratch); - if (retval) goto cleanup; + + if ((retval = krb5_c_string_to_key(context, type, &sc.sam_challenge, + 0 /* salt */, &psr.sam_key))) + goto cleanup; + + if ((retval = encode_krb5_predicted_sam_response(&psr, &scratch))) + goto cleanup; { - krb5_enc_data tmpdata; - retval = krb5_encrypt_data(context, master_encblock.key, 0, - scratch, &tmpdata); - sc.sam_track_id = tmpdata.ciphertext; + size_t enclen; + krb5_enc_data tmpdata; + + if ((retval = krb5_c_encrypt_length(context, + master_keyblock.enctype, + scratch->length, &enclen))) + goto cleanup; + + if ((tmpdata.ciphertext.data = (char *) malloc(enclen)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + tmpdata.ciphertext.length = enclen; + + if ((retval = krb5_c_encrypt(context, &master_keyblock, + /* XXX */ 0, 0, scratch, &tmpdata))) + goto cleanup; + + sc.sam_track_id = tmpdata.ciphertext; } - if (retval) goto cleanup; } sc.sam_response_prompt.data = "response prompt"; @@ -779,15 +830,17 @@ get_sam_edata(context, request, client, server, pa_data) /* generate digit string, take it mod 1000000 (six digits.) */ { int j; - krb5_encrypt_block eblock; - krb5_keyblock *session_key = 0; + krb5_keyblock session_key; char outputblock[8]; int i; + + session_key.contents = 0; + memset(inputblock, 0, 8); - krb5_use_enctype(kdc_context, &eblock, ENCTYPE_DES_CBC_CRC); - retval = krb5_random_key(kdc_context, &eblock, - krb5_enctype_array[ENCTYPE_DES_CBC_CRC]->random_sequence, - &session_key); + + retval = krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_CRC, + &session_key); + if (retval) { /* random key failed */ com_err("krb5kdc", retval,"generating random challenge for preauth"); @@ -795,41 +848,48 @@ get_sam_edata(context, request, client, server, pa_data) } /* now session_key has a key which we can pick bits out of */ /* we need six decimal digits. Grab 6 bytes, div 2, mod 10 each. */ - if (session_key->length != 8) { + if (session_key.length != 8) { com_err("krb5kdc", retval = KRB5KDC_ERR_ETYPE_NOSUPP, "keytype didn't match code expectations"); return retval; } for(i = 0; i<6; i++) { - inputblock[i] = '0' + ((session_key->contents[i]/2) % 10); + inputblock[i] = '0' + ((session_key.contents[i]/2) % 10); } - if (session_key) - krb5_free_keyblock(kdc_context, session_key); + if (session_key.contents) + krb5_free_keyblock_contents(kdc_context, &session_key); /* retval = krb5_finish_key(kdc_context, &eblock); */ /* now we have inputblock containing the 8 byte input to DES... */ sc.sam_challenge.data = inputblock; sc.sam_challenge.length = 6; - krb5_use_enctype(kdc_context, &eblock, ENCTYPE_DES_CBC_RAW); encrypting_key.enctype = ENCTYPE_DES_CBC_RAW; - /* do any necessary key pre-processing */ - retval= krb5_process_key(kdc_context, &eblock, &encrypting_key); if (retval) { com_err("krb5kdc", retval, "snk4 processing key"); } { - char ivec[8]; - memset(ivec,0,8); - retval = krb5_encrypt(kdc_context, inputblock, outputblock, 8, - &eblock, ivec); - } - if (retval) { - com_err("krb5kdc", retval, "snk4 response generation failed"); - return retval; + krb5_data plain; + krb5_enc_data cipher; + + plain.length = 8; + plain.data = inputblock; + + /* XXX I know this is enough because of the fixed raw enctype. + if it's not, the underlying code will return a reasonable + error, which should never happen */ + cipher.ciphertext.length = 8; + cipher.ciphertext.data = outputblock; + + if ((retval = krb5_c_encrypt(kdc_context, &encrypting_key, + /* XXX */ 0, 0, &plain, &cipher))) { + com_err("krb5kdc", retval, "snk4 response generation failed"); + return retval; + } } + /* now output block is the raw bits of the response; convert it to display form */ for (j=0; j<4; j++) { @@ -863,20 +923,34 @@ sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data); /* string2key on sc.sam_challenge goes in here */ /* eblock is just to set the enctype */ { - const krb5_enctype type = ENCTYPE_DES_CBC_MD5; - if (!valid_enctype(type)) return KRB5_PROG_ETYPE_NOSUPP; - krb5_use_enctype(context, &eblock, type); - retval = krb5_string_to_key(context, &eblock, - &psr.sam_key, &predict_response, - 0 /* salt */); + retval = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5, + &predict_response, 0 /* salt */, + &psr.sam_key); + if (retval) goto cleanup; + retval = encode_krb5_predicted_sam_response(&psr, &scratch); if (retval) goto cleanup; { - krb5_enc_data tmpdata; - retval = krb5_encrypt_data(context, master_encblock.key, 0, - scratch, &tmpdata); - sc.sam_track_id = tmpdata.ciphertext; + size_t enclen; + krb5_enc_data tmpdata; + + if ((retval = krb5_c_encrypt_length(context, + master_keyblock.enctype, + scratch->length, &enclen))) + goto cleanup; + + if ((tmpdata.ciphertext.data = (char *) malloc(enclen)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + tmpdata.ciphertext.length = enclen; + + if ((retval = krb5_c_encrypt(context, &master_keyblock, + /* XXX */ 0, 0, scratch, &tmpdata))) + goto cleanup; + + sc.sam_track_id = tmpdata.ciphertext; } if (retval) goto cleanup; } @@ -937,37 +1011,64 @@ verify_sam_response(context, client, request, enc_tkt_reply, pa) scratch.data = pa->contents; scratch.length = pa->length; - retval = decode_krb5_sam_response(&scratch, &sr); - if (retval) com_err("krb5kdc", retval, "decode_krb5_sam_response failed"); - if (retval) goto cleanup; + if ((retval = decode_krb5_sam_response(&scratch, &sr))) { + scratch.data = 0; + com_err("krb5kdc", retval, "decode_krb5_sam_response failed"); + goto cleanup; + } { krb5_enc_data tmpdata; + + tmpdata.enctype = ENCTYPE_UNKNOWN; tmpdata.ciphertext = sr->sam_track_id; - retval = krb5_decrypt_data(context, master_encblock.key, 0, - &tmpdata, &scratch); - if (retval) com_err("krb5kdc", retval, "decrypt track_id failed"); + + scratch.length = tmpdata.ciphertext.length; + if ((scratch.data = (char *) malloc(scratch.length)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + + if ((retval = krb5_c_decrypt(context, &master_keyblock, /* XXX */ 0, 0, + &tmpdata, &scratch))) { + com_err("krb5kdc", retval, "decrypt track_id failed"); + goto cleanup; + } } - if (retval) goto cleanup; - retval = decode_krb5_predicted_sam_response(&scratch, &psr); - if (retval) com_err("krb5kdc", retval, "decode_krb5_predicted_sam_response failed"); - if (retval) goto cleanup; + + if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) { + com_err("krb5kdc", retval, + "decode_krb5_predicted_sam_response failed"); + goto cleanup; + } + { - /* now psr.sam_key is what we said to use... */ - retval = krb5_decrypt_data(context, &psr->sam_key, 0, - &sr->sam_enc_nonce_or_ts, &scratch); - if (retval) com_err("krb5kdc", retval, "decrypt nonce_or_ts failed"); + free(scratch.data); + scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length; + if ((scratch.data = (char *) malloc(scratch.length)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + + if ((retval = krb5_c_decrypt(context, &psr->sam_key, /* XXX */ 0, + 0, &sr->sam_enc_nonce_or_ts, &scratch))) { + com_err("krb5kdc", retval, "decrypt nonce_or_ts failed"); + goto cleanup; + } + } + + if ((retval = decode_krb5_enc_sam_response_enc(&scratch, &esre))) { + com_err("krb5kdc", retval, "decode_krb5_enc_sam_response_enc failed"); + goto cleanup; } - if (retval) goto cleanup; - retval = decode_krb5_enc_sam_response_enc(&scratch, &esre); - if (retval) com_err("krb5kdc", retval, "decode_krb5_enc_sam_response_enc failed"); - if (retval) goto cleanup; + if (esre->sam_timestamp != sr->sam_patimestamp) { retval = KRB5KDC_ERR_PREAUTH_FAILED; goto cleanup; } - retval = krb5_timeofday(context, &timenow); - if (retval) goto cleanup; + + if ((retval = krb5_timeofday(context, &timenow))) + goto cleanup; if (labs(timenow - sr->sam_patimestamp) > context->clockskew) { retval = KRB5KRB_AP_ERR_SKEW; @@ -975,8 +1076,11 @@ verify_sam_response(context, client, request, enc_tkt_reply, pa) } setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH); + cleanup: - if (retval) com_err("krb5kdc", retval, "sam verify failure"); + if (retval) + com_err("krb5kdc", retval, "sam verify failure"); + if (scratch.data) free(scratch.data); if (sr) free(sr); if (psr) free(psr); if (esre) free(esre); diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 863ffd19c..51d4d7807 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -124,6 +124,7 @@ comp_cksum(kcontext, source, ticket, his_cksum) krb5_checksum * his_cksum; { krb5_error_code retval; + krb5_boolean valid; if (!valid_cksumtype(his_cksum->checksum_type)) return KRB5KDC_ERR_SUMTYPE_NOSUPP; @@ -133,14 +134,15 @@ comp_cksum(kcontext, source, ticket, his_cksum) return KRB5KRB_AP_ERR_INAPP_CKSUM; /* verify checksum */ - if ((retval = krb5_verify_checksum(kcontext, his_cksum->checksum_type, - his_cksum, - source->data, source->length, - ticket->enc_part2->session->contents, - ticket->enc_part2->session->length))) { - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - return retval; + if ((retval = krb5_c_verify_checksum(kcontext, ticket->enc_part2->session, + KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, + source, his_cksum, &valid))) + return(retval); + + if (!valid) + return(KRB5KRB_AP_ERR_BAD_INTEGRITY); + + return(0); } krb5_error_code @@ -333,12 +335,15 @@ cleanup: /* XXX This function should no longer be necessary. * The KDC should take the keytab associated with the realm and pass that to * the krb5_rd_req_decode(). --proven + * + * It's actually still used by do_tgs_req() for u2u auth, and not too + * much else. -- tlyu */ krb5_error_code kdc_get_server_key(ticket, key, kvno) krb5_ticket * ticket; krb5_keyblock ** key; - krb5_kvno * kvno; + krb5_kvno * kvno; /* XXX nothing uses this */ { krb5_error_code retval; krb5_db_entry server; @@ -347,64 +352,46 @@ kdc_get_server_key(ticket, key, kvno) krb5_key_data * server_key; int i; - if (krb5_principal_compare(kdc_context, tgs_server, ticket->server)) { - retval = krb5_copy_keyblock(kdc_context, &tgs_key, key); - *kvno = tgs_kvno; - return retval; - } else { - nprincs = 1; + nprincs = 1; - if ((retval = krb5_db_get_principal(kdc_context, ticket->server, - &server, &nprincs, - &more))) { - return(retval); - } - if (more) { - krb5_db_free_principal(kdc_context, &server, nprincs); - return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); - } else if (nprincs != 1) { - char *sname; - - krb5_db_free_principal(kdc_context, &server, nprincs); - if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) { - krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'", - sname); - free(sname); - } - return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); - } - /* - * Get the latest version of the server key_data and - * convert the key into a real key (it may be encrypted in the database) - * - * Search the key list in the order specified by the key/salt list. - */ - server_key = (krb5_key_data *) NULL; - for (i=0; irealm_nkstypes; i++) { - krb5_key_salt_tuple *kslist; - - kslist = (krb5_key_salt_tuple *) kdc_active_realm->realm_kstypes; - if (!krb5_dbe_find_enctype(kdc_context, - &server, - kslist[i].ks_enctype, - -1, - -1, - &server_key)) - break; - } - if (!server_key) - return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); - - *kvno = server_key->key_data_kvno; - if ((*key = (krb5_keyblock *)malloc(sizeof **key))) { - retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, - server_key, - *key, NULL); - } else - retval = ENOMEM; + if ((retval = krb5_db_get_principal(kdc_context, ticket->server, + &server, &nprincs, + &more))) { + return(retval); + } + if (more) { krb5_db_free_principal(kdc_context, &server, nprincs); - return retval; + return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + } else if (nprincs != 1) { + char *sname; + + krb5_db_free_principal(kdc_context, &server, nprincs); + if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) { + krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'", + sname); + free(sname); + } + return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); } + retval = krb5_dbe_find_enctype(kdc_context, &server, + ticket->enc_part.enctype, -1, + ticket->enc_part.kvno, &server_key); + if (retval) + goto errout; + if (!server_key) { + retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; + goto errout; + } + *kvno = server_key->key_data_kvno; + if ((*key = (krb5_keyblock *)malloc(sizeof **key))) { + retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, + server_key, + *key, NULL); + } else + retval = ENOMEM; +errout: + krb5_db_free_principal(kdc_context, &server, nprincs); + return retval; } /* This probably wants to be updated if you support last_req stuff */ diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c index f5a3a7789..a1efd8b37 100644 --- a/src/kdc/kerberos_v4.c +++ b/src/kdc/kerberos_v4.c @@ -65,10 +65,12 @@ extern int errno; -int compat_decrypt_key PROTOTYPE((krb5_key_data *, C_Block)); -int kerb_get_principal PROTOTYPE((char *, char *, Principal *, int, - int *)); -int check_princ PROTOTYPE((char *, char *, unsigned, Principal *)); +static int compat_decrypt_key PROTOTYPE((krb5_key_data *, C_Block, + krb5_keyblock *, int)); +static int kerb_get_principal PROTOTYPE((char *, char *, Principal *, int, + int *, krb5_keyblock *, krb5_kvno, int)); +static int check_princ PROTOTYPE((char *, char *, unsigned, Principal *, + krb5_keyblock *, int)); #ifdef HAVE_STDARG_H char * v4_klog KRB5_PROTOTYPE((int, const char *, ...)); @@ -144,8 +146,8 @@ static krb5_data *response; void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); -int set_tgtkey PROTOTYPE((char *)); - +static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); + /* Attributes converted from V5 to V4 - internal representation */ #define V4_KDB_REQUIRES_PREAUTH 0x1 #define V4_KDB_DISALLOW_ALL_TIX 0x2 @@ -334,36 +336,59 @@ hang() } #define kdb_encrypt_key( in, out, mk, mks, e_d_flag) #define LONGLEN 4 +#define K4KDC_ENCTYPE_OK(e) \ +((e) == ENCTYPE_DES_CBC_CRC \ + || (e) == ENCTYPE_DES_CBC_MD4 \ + || (e) == ENCTYPE_DES_CBC_MD5 \ + || (e) == ENCTYPE_DES_CBC_RAW) /* take a v5 keyblock, masquerading as a v4 key, * decrypt it, and convert the resulting v5 keyblock * to a real v4 key. * this is ugly, but it saves changing more v4 code. + * + * Also, keep old krb5_keyblock around in case we want to use it later. */ -int compat_decrypt_key (in5, out4) - krb5_key_data *in5; - C_Block out4; +static int +compat_decrypt_key (in5, out4, out5, issrv) + krb5_key_data *in5; + C_Block out4; + krb5_keyblock *out5; + int issrv; /* whether it's a server key */ { - krb5_keyblock out5; - int retval = -1; + krb5_error_code retval; - out5.contents = NULL; - if (krb5_dbekd_decrypt_key_data(kdc_context,&master_encblock,in5,&out5,NULL)){ + out5->contents = NULL; + memset(out4, 0, sizeof(out4)); + retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, + in5, out5, NULL); + if (retval) { lt = klog(L_DEATH_REQ, "KDC can't decrypt principal's key."); + out5->contents = NULL; return(retval); } - if (out5.length != KRB5_MIT_DES_KEYSIZE) - lt = klog(L_DEATH_REQ, "internal keysize error in kdc"); - else if ((out5.enctype != ENCTYPE_DES_CBC_CRC) && - (out5.enctype != ENCTYPE_DES_CBC_MD4) && - (out5.enctype != ENCTYPE_DES_CBC_MD5) && - (out5.enctype != ENCTYPE_DES_CBC_RAW)) - lt = klog(L_DEATH_REQ, "incompatible principal key type."); - else { - memcpy(out4, out5.contents, out5.length); - retval = 0; + if (K4KDC_ENCTYPE_OK(out5->enctype)) { + if (out5->length == KRB5_MIT_DES_KEYSIZE) + memcpy(out4, out5->contents, out5->length); + else { + lt = klog(L_DEATH_REQ, "internal keysize error in kdc"); + krb5_free_keyblock_contents(kdc_context, out5); + out5->contents = NULL; + retval = -1; + } + } else { + if (!issrv) { + lt = klog(L_DEATH_REQ, "incompatible principal key type."); + krb5_free_keyblock_contents(kdc_context, out5); + out5->contents = NULL; + retval = -1; + } else { + /* KLUDGE! If it's a non-raw des3 key, bash its enctype */ + if (out5->enctype == ENCTYPE_DES3_HMAC_SHA1 || + out5->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) + out5->enctype = ENCTYPE_DES3_CBC_RAW; + } } - krb5_free_keyblock_contents(kdc_context, &out5); return(retval); } @@ -372,13 +397,16 @@ int compat_decrypt_key (in5, out4) #define MIN5 300 #define HR21 255 -int -kerb_get_principal(name, inst, principal, maxn, more) +static int +kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) char *name; /* could have wild card */ char *inst; /* could have wild card */ Principal *principal; int maxn; /* max number of name structs to return */ int *more; /* more tuples than room for */ + krb5_keyblock *k5key; + krb5_kvno kvno; + int issrv; /* true if retrieving a service key */ { /* Note that this structure should not be passed to the krb5_free* functions, because the pointers within it point @@ -430,27 +458,52 @@ kerb_get_principal(name, inst, principal, maxn, more) return(nprinc); } - if (krb5_dbe_find_enctype(kdc_context, - &entries, - ENCTYPE_DES_CBC_CRC, - KRB5_KDB_SALTTYPE_V4, - -1, - &pkey) && - krb5_dbe_find_enctype(kdc_context, - &entries, - ENCTYPE_DES_CBC_CRC, - -1, - -1, - &pkey)) - { - lt = klog(L_KRB_PERR, "KDC V4: principal %s.%s isn't V4 compatible", - name, inst); - krb5_db_free_principal(kdc_context, &entries, nprinc); - return(0); + if (!issrv) { + if (krb5_dbe_find_enctype(kdc_context, + &entries, + ENCTYPE_DES_CBC_CRC, + KRB5_KDB_SALTTYPE_V4, + kvno, + &pkey) && + krb5_dbe_find_enctype(kdc_context, + &entries, + ENCTYPE_DES_CBC_CRC, + -1, + kvno, + &pkey)) { + lt = klog(L_KRB_PERR, + "KDC V4: principal %s.%s isn't V4 compatible", + name, inst); + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } + } else { + /* XXX yes I know this is a hardcoded search order */ + if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_LOCAL_DES3_HMAC_SHA1, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_HMAC_SHA1, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES_CBC_CRC, + KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES_CBC_CRC, + -1, kvno, &pkey)) { + lt = klog(L_KRB_PERR, + "KDC V4: failed to find key for %s.%s", + name, inst); + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } } - if (! compat_decrypt_key( pkey, k)) { - memcpy( &principal->key_low, k, LONGLEN); + if (!compat_decrypt_key(pkey, k, k5key, issrv)) { + memcpy( &principal->key_low, k, LONGLEN); memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); } /* convert v5's entries struct to v4's Principal struct: @@ -550,7 +603,11 @@ kerberos_v4(client, pkt) Key_schedule key_s; char *ptr; + krb5_keyblock k5key; + krb5_kvno kvno; + + k5key.contents = NULL; /* in case we have to free it */ ciph->length = 0; @@ -639,11 +696,14 @@ kerberos_v4(client, pkt) 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))) { + &a_name_data, &k5key, 0))) { kerb_err_reply(client, pkt, i, lt); a_name_data.key_low = a_name_data.key_high = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } + /* don't use k5key for client */ + krb5_free_keyblock_contents(kdc_context, &k5key); tk->length = 0; /* init */ if (strcmp(service, "krbtgt")) klog(L_NTGT_INTK, @@ -651,10 +711,11 @@ kerberos_v4(client, pkt) req_inst_ptr, service, instance, 0); /* this does all the checking */ if ((i = check_princ(service, instance, lifetime, - &s_name_data))) { + &s_name_data, &k5key, 1))) { kerb_err_reply(client, pkt, i, lt); a_name_data.key_high = a_name_data.key_low = 0; s_name_data.key_high = s_name_data.key_low = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } /* Bound requested lifetime with service and user */ @@ -675,10 +736,22 @@ kerberos_v4(client, pkt) 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, (char *) session_key, lifetime, kerb_time.tv_sec, - s_name_data.name, s_name_data.instance, key); + if (K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_create_ticket(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, (char *) session_key, + lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + key); + } else { + krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, (char *) session_key, + lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + &k5key); + } + krb5_free_keyblock_contents(kdc_context, &k5key); memset(key, 0, sizeof(key)); memset(key_s, 0, sizeof(key_s)); @@ -737,14 +810,15 @@ kerberos_v4(client, pkt) memcpy(auth->dat, pkt->dat, auth->length); strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ); - if (set_tgtkey(tktrlm)) { + kvno = (krb5_kvno)auth->dat[2]; + if (set_tgtkey(tktrlm, kvno)) { lt = klog(L_ERR_UNK, - "FAILED realm %s unknown. Host: %s ", - tktrlm, inet_ntoa(client_host)); + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); kerb_err_reply(client, pkt, kerno, lt); return; } - kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, ad, 0); if (kerno) { @@ -784,9 +858,11 @@ kerberos_v4(client, pkt) return; } kerno = check_princ(service, instance, req_life, - &s_name_data); + &s_name_data, &k5key, 1); if (kerno) { kerb_err_reply(client, pkt, kerno, lt); + s_name_data.key_high = s_name_data.key_low = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } /* Bound requested lifetime with service and user */ @@ -910,18 +986,21 @@ static char *krb4_stime(t) return st; } -int check_princ(p_name, instance, lifetime, p) +static int +check_princ(p_name, instance, lifetime, p, k5key, issrv) char *p_name; char *instance; unsigned lifetime; Principal *p; + krb5_keyblock *k5key; + int issrv; /* whether this is a server key */ { static int n; static int more; /* long trans; */ - n = kerb_get_principal(p_name, instance, p, 1, &more); + n = kerb_get_principal(p_name, instance, p, 1, &more, k5key, 0, issrv); klog(L_ALL_REQ, "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", p_name, instance, lifetime, n, 0); @@ -986,11 +1065,13 @@ int check_princ(p_name, instance, lifetime, p) } /* 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 (k5key->contents != NULL && K4KDC_ENCTYPE_OK(k5key->enctype)) { + 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; + } } /* make sure the service hasn't expired */ if (((u_long) p->exp_date != 0)&& @@ -1007,31 +1088,44 @@ int check_princ(p_name, instance, lifetime, p) /* Set the key for krb_rd_req so we can check tgt */ -int set_tgtkey(r) +static int +set_tgtkey(r, kvno) char *r; /* Realm for desired key */ + krb5_kvno kvno; { int n; static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; Principal p_st; Principal *p = &p_st; C_Block key; + krb5_keyblock k5key; - if (!strcmp(lastrealm, r)) + k5key.contents = NULL; + if (!strcmp(lastrealm, r) && last_kvno == kvno) return (KSUCCESS); /* log("Getting key for %s", r); */ - n = kerb_get_principal("krbtgt", r, p, 1, &more); + n = kerb_get_principal("krbtgt", r, p, 1, &more, &k5key, kvno, 1); if (n == 0) return (KFAILURE); - /* unseal tgt key from master key */ - memcpy(key, &p->key_low, 4); - memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4); - kdb_encrypt_key(key, key, master_key, - master_key_schedule, DECRYPT); - krb_set_key((char *) key, 0); - strcpy(lastrealm, r); + if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strcpy(lastrealm, r); + last_kvno = kvno; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); + memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + krb_set_key((char *) key, 0); + strcpy(lastrealm, r); + last_kvno = kvno; + } + krb5_free_keyblock_contents(kdc_context, &k5key); return (KSUCCESS); } diff --git a/src/kdc/main.c b/src/kdc/main.c index 4524c00f4..a8f4233be 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -166,8 +166,6 @@ finish_realm(rdp) memset(rdp->realm_tgskey.contents, 0, rdp->realm_tgskey.length); free(rdp->realm_tgskey.contents); } - if (rdp->realm_encblock.crypto_entry) - krb5_finish_key(rdp->realm_context, &rdp->realm_encblock); krb5_db_fini(rdp->realm_context); if (rdp->realm_tgsprinc) krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc); @@ -326,17 +324,11 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname, goto whoops; } - /* Select the specified encryption type */ - /* krb5_db_fetch_mkey will setup the encblock for stashed keys */ - if (manual) - krb5_use_enctype(rdp->realm_context, &rdp->realm_encblock, - rdp->realm_mkey.enctype); - /* * Get the master key. */ if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, - &rdp->realm_encblock, manual, + rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, 0, &rdp->realm_mkey))) { com_err(progname, kret, @@ -363,8 +355,7 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname, /* Verify the master key */ if ((kret = krb5_db_verify_master_key(rdp->realm_context, rdp->realm_mprinc, - &rdp->realm_mkey, - &rdp->realm_encblock))) { + &rdp->realm_mkey))) { com_err(progname, kret, "while verifying master key for realm %s", realm); goto whoops; @@ -415,17 +406,7 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname, rdp->realm_mkvno = kdata->key_data_kvno; krb5_db_free_principal(rdp->realm_context, &db_entry, num2get); - /* Now preprocess the master key */ - if ((kret = krb5_process_key(rdp->realm_context, - &rdp->realm_encblock, - &rdp->realm_mkey))) { - com_err(progname, kret, - "while processing master key for realm %s", realm); - goto whoops; - } - - if ((kret = krb5_db_set_mkey(rdp->realm_context, - &rdp->realm_encblock))) { + if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) { com_err(progname, kret, "while setting master key for realm %s", realm); goto whoops; @@ -491,7 +472,7 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname, goto whoops; } if (!(kret = krb5_dbekd_decrypt_key_data(rdp->realm_context, - &rdp->realm_encblock, + &rdp->realm_mkey, kdata, &rdp->realm_tgskey, NULL))){ rdp->realm_tgskvno = kdata->key_data_kvno; @@ -506,45 +487,40 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname, } if (!rkey_init_done) { - krb5_enctype enctype; - krb5_encrypt_block temp_eblock; + krb5_timestamp now; + krb5_data seed; #ifdef KRB5_KRB4_COMPAT - krb5_keyblock *temp_key; + krb5_keyblock temp_key; #endif /* * If all that worked, then initialize the random key * generators. */ - for (enctype = 0; enctype <= krb5_max_enctype; enctype++) { - if (krb5_enctype_array[enctype] && - !krb5_enctype_array[enctype]->random_sequence) { - krb5_use_enctype(rdp->realm_context, &temp_eblock, enctype); - if ((kret = krb5_init_random_key( - rdp->realm_context, &temp_eblock, - &rdp->realm_mkey, - &krb5_enctype_array[enctype]->random_sequence))) { - com_err(progname, kret, - "while setting up random key generator for enctype %d--enctype disabled", - enctype); - krb5_enctype_array[enctype] = 0; - } else { + + if ((kret = krb5_timeofday(rdp->realm_context, &now))) + goto whoops; + seed.length = sizeof(now); + seed.data = (char *) &now; + if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) + goto whoops; + + seed.length = rdp->realm_mkey.length; + seed.data = rdp->realm_mkey.contents; + + if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) + goto whoops; + #ifdef KRB5_KRB4_COMPAT - if (enctype == ENCTYPE_DES_CBC_CRC) { - if ((kret = krb5_random_key( - rdp->realm_context, &temp_eblock, - krb5_enctype_array[enctype]->random_sequence, - &temp_key))) - com_err(progname, kret, - "while initializing V4 random key generator"); - else { - (void) des_init_random_number_generator(temp_key->contents); - krb5_free_keyblock(rdp->realm_context, temp_key); - } - } -#endif - } - } + if ((kret = krb5_c_make_random_key(rdp->realm_context, + ENCTYPE_DES_CBC_CRC, &temp_key))) { + com_err(progname, kret, + "while initializing V4 random key generator"); + goto whoops; } + + (void) des_init_random_number_generator(temp_key.contents); + krb5_free_keyblock_contents(rdp->realm_context, &temp_key); +#endif rkey_init_done = 1; } whoops: diff --git a/src/krb524/ChangeLog b/src/krb524/ChangeLog index e68edba1f..40ef10cd1 100644 --- a/src/krb524/ChangeLog +++ b/src/krb524/ChangeLog @@ -1,3 +1,26 @@ +Tue Sep 1 19:35:44 1998 Tom Yu + + * cnv_tkt_skey.c (krb524_convert_tkt_skey): Add + ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list of enctypes to bash. + + * krb524d.c (do_connection): Add ENCTYPE_LOCAL_DES3_HMAC_SHA1 to + the list of enctypes to search. + +Wed Aug 19 13:40:28 1998 Tom Yu + + * cnv_tkt_skey.c (krb524_convert_tkt_skey): Call krb_cr_tkt_krb5 + if necessary, depending on th enctype. Force enctype to be raw + DES3 if it's another DES3 type. + + * krb524d.c (kdc_get_server_key): Add integer kvno argument, + rename previous kvno arg as kvnop, to distinguish returned (found) + kvno from the input kvno. + (lookup_service_key): Add kvnop argument to allow for returned + kvno. + (do_connection): Search for DES3 keys as well as DES. Get the + found kvno as well, and use that instead of the kvno of the + incoming ticket. + Fri Jul 24 19:38:58 1998 Geoffrey King * krb524d.c (main): Fork into the background by default, also diff --git a/src/krb524/cnv_tkt_skey.c b/src/krb524/cnv_tkt_skey.c index df270776a..4c51b6777 100644 --- a/src/krb524/cnv_tkt_skey.c +++ b/src/krb524/cnv_tkt_skey.c @@ -154,19 +154,39 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey, (long) lifetime); /* XXX are there V5 flags we should map to V4 equivalents? */ - ret = krb_create_ticket(v4tkt, - 0, /* flags */ - pname, - pinst, - prealm, - *((unsigned long *)kaddr.contents), - (char *) v5etkt->session->contents, - lifetime, - /* issue_data */ - server_time, - sname, - sinst, - v4_skey->contents); + if (v4_skey->enctype == ENCTYPE_DES_CBC_CRC) { + ret = krb_create_ticket(v4tkt, + 0, /* flags */ + pname, + pinst, + prealm, + *((unsigned long *)kaddr.contents), + (char *) v5etkt->session->contents, + lifetime, + /* issue_data */ + server_time, + sname, + sinst, + v4_skey->contents); + } else { + /* Force enctype to be raw if using DES3. */ + if (v4_skey->enctype == ENCTYPE_DES3_HMAC_SHA1 || + v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) + v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; + ret = krb_cr_tkt_krb5(v4tkt, + 0, /* flags */ + pname, + pinst, + prealm, + *((unsigned long *)kaddr.contents), + (char *) v5etkt->session->contents, + lifetime, + /* issue_data */ + server_time, + sname, + sinst, + v4_skey); + } krb5_free_enc_tkt_part(context, v5etkt); v5tkt->enc_part2 = NULL; diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c index f72726fff..1afeec2dc 100644 --- a/src/krb524/krb524d.c +++ b/src/krb524/krb524d.c @@ -253,6 +253,7 @@ krb5_error_code do_connection(s, context) krb5_data msgdata, tktdata; char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p; int n, ret, saddrlen; + krb5_kvno v4kvno; /* Clear out keyblock contents so we don't accidentally free the stack.*/ v5_service_key.contents = v4_service_key.contents = 0; @@ -292,14 +293,28 @@ krb5_error_code do_connection(s, context) printf("V5 ticket decoded\n"); if ((ret = lookup_service_key(context, v5tkt->server, - v5tkt->enc_part.enctype, - &v5_service_key))) + v5tkt->enc_part.enctype, + v5tkt->enc_part.kvno, + &v5_service_key, NULL))) goto error; if ((ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES3_CBC_RAW, + 0, /* highest kvno */ + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_LOCAL_DES3_HMAC_SHA1, + 0, + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES3_HMAC_SHA1, + 0, + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, ENCTYPE_DES_CBC_CRC, - &v4_service_key))) - goto error; + 0, + &v4_service_key, &v4kvno))) + goto error; if (debug) printf("service key retrieved\n"); @@ -334,7 +349,7 @@ error: if (ret) goto write_msg; - n = htonl(v5tkt->enc_part.kvno); + n = htonl(v4kvno); memcpy(p, (char *) &n, sizeof(int)); p += sizeof(int); msgdata.length += sizeof(int); @@ -363,32 +378,35 @@ write_msg: return ret; } -krb5_error_code lookup_service_key(context, p, ktype, key) +krb5_error_code lookup_service_key(context, p, ktype, kvno, key, kvnop) krb5_context context; krb5_principal p; krb5_enctype ktype; + krb5_kvno kvno; krb5_keyblock *key; + krb5_kvno *kvnop; { int ret; krb5_keytab_entry entry; if (use_keytab) { - if ((ret = krb5_kt_get_entry(context, kt, p, 0, ktype, &entry))) + if ((ret = krb5_kt_get_entry(context, kt, p, kvno, ktype, &entry))) return ret; memcpy(key, (char *) &entry.key, sizeof(krb5_keyblock)); return 0; } else if (use_master) { - return kdc_get_server_key(context, p, key, NULL, ktype); + return kdc_get_server_key(context, p, key, kvnop, ktype, kvno); } return 0; } -krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype) +krb5_error_code kdc_get_server_key(context, service, key, kvnop, ktype, kvno) krb5_context context; krb5_principal service; krb5_keyblock *key; - krb5_kvno *kvno; + krb5_kvno *kvnop; krb5_enctype ktype; + krb5_kvno kvno; { krb5_error_code ret; kadm5_principal_ent_rec server; @@ -409,14 +427,14 @@ krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype) ktype, (ktype == ENCTYPE_DES_CBC_CRC) ? KRB5_KDB_SALTTYPE_V4 : -1, - -1, - key, NULL, kvno)) && + kvno, + key, NULL, kvnop)) && (ret = kadm5_decrypt_key(handle, &server, ktype, -1, - -1, - key, NULL, kvno))) { + kvno, + key, NULL, kvnop))) { kadm5_free_principal_ent(handle, &server); return (KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); } diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index dd0e7b561..566afc88f 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,34 @@ +Tue Sep 22 21:19:01 1998 Tom Yu + + * prng.c (krb5_c_random_make_octets): Fix to nfold into 15 bytes, + not one byte. + +Mon Sep 21 15:23:19 1998 Tom Yu + + * prng.c (krb5_c_random_seed): Fix memory leak. + +Mon Sep 14 23:21:17 1998 Tom Yu + + * old/decrypt.c (krb5_old_decrypt): Fix memory leak. + +Tue Sep 1 19:33:38 1998 Tom Yu + + * etypes.c: Add ETYPE_LOCAL_DES3_HMAC_SHA1 to deal with marc's + des3 code. ETYPE_DES3_HMAC_SHA1 remains the same for now. + +Mon Aug 17 23:40:11 1998 Tom Yu + + * keyhash_provider/k5_md4des.c (k5_md4des_verify): Add + compatibility for krb5-beta5 checksums. + + * keyhash_provider/k5_md5des.c (k5_md5des_verify): Add + compatibility for krb5-beta5 checksums. Fix typos similar to + those corrected in k5_md4des.c. + +Sun Jul 19 12:00:00 1998 Marc Horowitz + + * *.c: replace the crypto layer. + Wed Apr 15 18:02:44 1998 Tom Yu * Makefile.in (LIB): Rename to k5crypto. diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index 468818cb8..48d035a78 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -1,7 +1,10 @@ thisconfigdir=. BUILDTOP=$(REL)$(U)$(S)$(U) -LOCAL_SUBDIRS=des crc32 md4 md5 sha os -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/crc32 -I$(srcdir)/des -I$(srcdir)/md4 -I$(srcdir)/md5 -I$(srcdir)/sha +LOCAL_SUBDIRS=crc32 des dk enc_provider hash_provider keyhash_provider \ + md4 md5 old raw sha1 +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/enc_provider \ + -I$(srcdir)/hash_provider -I$(srcdir)/keyhash_provider \ + -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk ##DOSBUILDTOP = ..\.. ##DOSLIBNAME=crypto.lib @@ -9,37 +12,102 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/crc32 -I$(srcdir)/des -I$(srcdir)/md4 -I$ ##DOSOBJFILELIST=@crypto.lst @des.lst @md4.lst @md5.lst @sha.lst @crc32.lst @os.lst ##DOSOBJFILEDEP =crypto.lst des.lst md4.lst md5.lst sha.lst crc32.lst os.lst -MAC_SUBDIRS = des sha md4 md5 crc32 os - -OBJS= cryptoconf.$(OBJEXT) \ - encrypt_data.$(OBJEXT) \ - krb5_glue.$(OBJEXT) \ - decrypt_data.$(OBJEXT) \ - des_crc.$(OBJEXT) \ - des_md5.$(OBJEXT) \ - des3_sha.$(OBJEXT) \ - des3_raw.$(OBJEXT) \ - raw_des.$(OBJEXT) - -SRCS= $(srcdir)/cryptoconf.c \ - $(srcdir)/encrypt_data.c \ - $(srcdir)/krb5_glue.c \ - $(srcdir)/decrypt_data.c \ - $(srcdir)/des_crc.c \ - $(srcdir)/des_md5.c \ - $(srcdir)/des3_sha.c \ - $(srcdir)/des3_raw.c \ - $(srcdir)/raw_des.c +MAC_SUBDIRS = crc32 des dk enc_provider hash_provider keyhash_provider \ + md4 md5 old raw sha1 + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS=\ + block_size.o \ + checksum_length.o \ + cksumtype_to_string.o \ + cksumtypes.o \ + coll_proof_cksum.o \ + decrypt.o \ + encrypt.o \ + encrypt_length.o \ + enctype_compare.o \ + enctype_to_string.o \ + etypes.o \ + hmac.o \ + keyed_cksum.o \ + keyed_checksum_types.o \ + make_checksum.o \ + make_random_key.o \ + nfold.o \ + old_api_glue.o \ + prng.o \ + string_to_cksumtype.o \ + string_to_enctype.o \ + string_to_key.o \ + valid_cksumtype.o \ + valid_enctype.o \ + verify_checksum.o + +OBJS=\ + block_size.$(OBJEXT) \ + checksum_length.$(OBJEXT) \ + cksumtype_to_string.$(OBJEXT) \ + cksumtypes.$(OBJEXT) \ + coll_proof_cksum.$(OBJEXT) \ + decrypt.$(OBJEXT) \ + encrypt.$(OBJEXT) \ + encrypt_length.$(OBJEXT) \ + enctype_compare.$(OBJEXT) \ + enctype_to_string.$(OBJEXT) \ + etypes.$(OBJEXT) \ + hmac.$(OBJEXT) \ + keyed_cksum.$(OBJEXT) \ + keyed_checksum_types.$(OBJEXT) \ + make_checksum.$(OBJEXT) \ + make_random_key.$(OBJEXT) \ + nfold.$(OBJEXT) \ + old_api_glue.$(OBJEXT) \ + prng.$(OBJEXT) \ + string_to_cksumtype.$(OBJEXT) \ + string_to_enctype.$(OBJEXT) \ + string_to_key.$(OBJEXT) \ + valid_cksumtype.$(OBJEXT) \ + valid_enctype.$(OBJEXT) \ + verify_checksum.$(OBJEXT) + +SRCS=\ + $(subdir)/block_size.c \ + $(subdir)/checksum_length.c \ + $(subdir)/cksumtype_to_string.c \ + $(subdir)/cksumtypes.c \ + $(subdir)/coll_proof_cksum.c \ + $(subdir)/decrypt.c \ + $(subdir)/encrypt.c \ + $(subdir)/encrypt_length.c \ + $(subdir)/enctype_compare.c \ + $(subdir)/enctype_to_string.c \ + $(subdir)/etypes.c \ + $(subdir)/hmac.c \ + $(subdir)/keyed_cksum.c \ + $(subdir)/keyed_checksum_types.c\ + $(subdir)/make_checksum.c \ + $(subdir)/make_random_key.c \ + $(subdir)/nfold.c \ + $(subdir)/old_api_glue.c \ + $(subdir)/prng.c \ + $(subdir)/string_to_cksumtype.c \ + $(subdir)/string_to_enctype.c \ + $(subdir)/string_to_key.c \ + $(subdir)/valid_cksumtype.c \ + $(subdir)/valid_enctype.c \ + $(subdir)/verify_checksum.c + LIB=k5crypto LIBMAJOR=2 -LIBMINOR=0 +LIBMINOR=1 RELDIR=crypto -STLIBOBJS=cryptoconf.o encrypt_data.o decrypt_data.o \ - des_crc.o des_md5.o des3_sha.o des3_raw.o raw_des.o krb5_glue.o -STOBJLISTS=des/OBJS.ST md4/OBJS.ST md5/OBJS.ST sha/OBJS.ST crc32/OBJS.ST \ - os/OBJS.ST OBJS.ST +STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ + hash_provider/OBJS.ST keyhash_provider/OBJS.ST md4/OBJS.ST \ + md5/OBJS.ST old/OBJS.ST raw/OBJS.ST sha1/OBJS.ST OBJS.ST # No dependencies. Record places to find this shared object if the target # link editor and loader support it. @@ -58,7 +126,14 @@ libcrypto.lib: clean-unix:: clean-liblinks clean-libs clean-libobjs -check-unix:: +check-unix:: t_nfold + $(RUN_SETUP) ./t_nfold + +t_nfold$(EXEEXT): t_nfold.$(OBJEXT) nfold.$(OBJEXT) + $(CC_LINK) -o $@ t_nfold.$(OBJEXT) nfold.$(OBJEXT) + +clean:: + $(RM) t_nfold.o t_nfold all-windows:: cd crc32 @@ -67,61 +142,101 @@ all-windows:: cd ..\des @echo Making in crypto\des -$(MAKE) -$(MFLAGS) + cd ..\dk + @echo Making in crypto\dk + -$(MAKE) -$(MFLAGS) + cd ..\enc_provider + @echo Making in crypto\enc_provider + -$(MAKE) -$(MFLAGS) + cd ..\hash_provider + @echo Making in crypto\hash_provider + -$(MAKE) -$(MFLAGS) + cd ..\keyhash_provider + @echo Making in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) cd ..\md4 @echo Making in crypto\md4 -$(MAKE) -$(MFLAGS) - cd ..\os - @echo Making in crypto\os - -$(MAKE) -$(MFLAGS) cd ..\md5 @echo Making in crypto\md5 -$(MAKE) -$(MFLAGS) - cd ..\sha - @echo Making in crypto\sha + cd ..\old + @echo Making in crypto\old + -$(MAKE) -$(MFLAGS) + cd ..\raw + @echo Making in crypto\raw + -$(MAKE) -$(MFLAGS) + cd ..\sha1 + @echo Making in crypto\sha1 -$(MAKE) -$(MFLAGS) - cd .. clean-windows:: cd crc32 - @echo Making clean in crypto\crc32 + @echo Making in clean crypto\crc32 -$(MAKE) -$(MFLAGS) clean cd ..\des @echo Making clean in crypto\des -$(MAKE) -$(MFLAGS) clean + cd ..\dk + @echo Making clean in crypto\dk + -$(MAKE) -$(MFLAGS) clean + cd ..\enc_provider + @echo Making clean in crypto\enc_provider + -$(MAKE) -$(MFLAGS) clean + cd ..\hash_provider + @echo Making clean in crypto\hash_provider + -$(MAKE) -$(MFLAGS) clean + cd ..\keyhash_provider + @echo Making clean in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) clean cd ..\md4 @echo Making clean in crypto\md4 -$(MAKE) -$(MFLAGS) clean cd ..\md5 @echo Making clean in crypto\md5 -$(MAKE) -$(MFLAGS) clean - cd ..\sha - @echo Making clean in crypto\sha + cd ..\old + @echo Making clean in crypto\old -$(MAKE) -$(MFLAGS) clean - cd ..\os - @echo Making clean in crypto\os + cd ..\raw + @echo Making clean in crypto\raw + -$(MAKE) -$(MFLAGS) clean + cd ..\sha1 + @echo Making clean in crypto\sha1 -$(MAKE) -$(MFLAGS) clean - cd .. - @echo Making clean locally check-windows:: cd crc32 - @echo Making check in crypto\crc32 + @echo Making in check crypto\crc32 -$(MAKE) -$(MFLAGS) check cd ..\des @echo Making check in crypto\des -$(MAKE) -$(MFLAGS) check + cd ..\dk + @echo Making check in crypto\dk + -$(MAKE) -$(MFLAGS) check + cd ..\enc_provider + @echo Making check in crypto\enc_provider + -$(MAKE) -$(MFLAGS) check + cd ..\hash_provider + @echo Making check in crypto\hash_provider + -$(MAKE) -$(MFLAGS) check + cd ..\keyhash_provider + @echo Making check in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) check cd ..\md4 @echo Making check in crypto\md4 -$(MAKE) -$(MFLAGS) check cd ..\md5 @echo Making check in crypto\md5 -$(MAKE) -$(MFLAGS) check - cd ..\sha - @echo Making check in crypto\sha + cd ..\old + @echo Making check in crypto\old -$(MAKE) -$(MFLAGS) check - cd ..\os - @echo Making check in crypto\os + cd ..\raw + @echo Making check in crypto\raw + -$(MAKE) -$(MFLAGS) check + cd ..\sha1 + @echo Making check in crypto\sha1 -$(MAKE) -$(MFLAGS) check - cd .. - diff --git a/src/lib/crypto/block_size.c b/src/lib/crypto/block_size.c new file mode 100644 index 000000000..de5c3ac89 --- /dev/null +++ b/src/lib/crypto/block_size.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_block_size(context, enctype, blocksize) + krb5_context context; + krb5_enctype enctype; + size_t *blocksize; +{ + int i; + + for (i=0; iblock_size))(blocksize); + + return(0); +} diff --git a/src/lib/crypto/checksum_length.c b/src/lib/crypto/checksum_length.c new file mode 100644 index 000000000..38773cae0 --- /dev/null +++ b/src/lib/crypto/checksum_length.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_error_code +krb5_c_checksum_length(context, cksumtype, length) + krb5_context context; + krb5_cksumtype cksumtype; + size_t *length; +{ + int i; + + for (i=0; ihash_size))(length); + else + (*(krb5_cksumtypes_list[i].hash->hash_size))(length); + + return(0); +} + diff --git a/src/lib/crypto/cksumtype_to_string.c b/src/lib/crypto/cksumtype_to_string.c new file mode 100644 index 000000000..21cc5905f --- /dev/null +++ b/src/lib/crypto/cksumtype_to_string.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_cksumtype_to_string(cksumtype, buffer, buflen) + krb5_cksumtype cksumtype; + char FAR * buffer; + size_t buflen; +{ + int i; + + for (i=0; i buflen) + return(ENOMEM); + + strcpy(buffer, krb5_cksumtypes_list[i].out_string); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/cksumtypes.c b/src/lib/crypto/cksumtypes.c new file mode 100644 index 000000000..8107d3b8f --- /dev/null +++ b/src/lib/crypto/cksumtypes.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "hash_provider.h" +#include "keyhash_provider.h" +#include "cksumtypes.h" + +struct krb5_cksumtypes krb5_cksumtypes_list[] = { + { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF, + "crc32", "CRC-32", + 0, NULL, + &krb5_hash_crc32 }, + + { CKSUMTYPE_RSA_MD4, 0, + "md4", "RSA-MD4", + 0, NULL, + &krb5_hash_md4 }, + { CKSUMTYPE_RSA_MD4_DES, 0, + "md4-des", "RSA-MD4 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_md4des, + NULL }, + + { CKSUMTYPE_DESCBC, 0, + "des-cbc", "DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_descbc, + NULL }, + + { CKSUMTYPE_RSA_MD5, 0, + "md5", "RSA-MD5", + 0, NULL, + &krb5_hash_md5 }, + { CKSUMTYPE_RSA_MD5_DES, 0, + "md5-des", "RSA-MD5 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_md5des, + NULL }, + + { CKSUMTYPE_NIST_SHA, 0, + "sha", "NIST-SHA", + 0, NULL, + &krb5_hash_sha1 }, + + { CKSUMTYPE_HMAC_SHA1, KRB5_CKSUMFLAG_DERIVE, + "hmac-sha1", "HMAC-SHA1", + 0, NULL, + &krb5_hash_sha1 }, +}; + +int krb5_cksumtypes_length = +sizeof(krb5_cksumtypes_list)/sizeof(struct krb5_cksumtypes); + diff --git a/src/lib/crypto/cksumtypes.h b/src/lib/crypto/cksumtypes.h new file mode 100644 index 000000000..900a7c891 --- /dev/null +++ b/src/lib/crypto/cksumtypes.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" + +extern struct krb5_cksumtypes krb5_cksumtypes_list[]; +extern int krb5_cksumtypes_length; + diff --git a/src/lib/crypto/coll_proof_cksum.c b/src/lib/crypto/coll_proof_cksum.c new file mode 100644 index 000000000..07925c641 --- /dev/null +++ b/src/lib/crypto/coll_proof_cksum.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_boolean is_coll_proof_cksum(ctype) + krb5_cksumtype ctype; +{ + int i; + + for (i=0; i + + * *.c: replace the crypto layer. + Wed Feb 18 16:05:45 1998 Tom Yu * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/lib/crypto/crc32/Makefile.in b/src/lib/crypto/crc32/Makefile.in index b1ad86bdd..97ab64cf0 100644 --- a/src/lib/crypto/crc32/Makefile.in +++ b/src/lib/crypto/crc32/Makefile.in @@ -7,25 +7,23 @@ CFLAGS = $(CCOPTS) $(DEFS) ##DOS##OBJFILE=..\crc32.lst ##WIN16##LIBNAME=..\crypto.lib -STLIBOBJS=crc.o -OBJS= crc.$(OBJEXT) -SRCS= $(srcdir)/crc.c +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) -##DOS##LIBOBJS = $(OBJS) +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -all-unix:: all-libobjs +STLIBOBJS= crc32.o + +OBJS= crc32.$(OBJEXT) -crctest: crctest.$(OBJEXT) $(OBJS) - $(RM) crctest - $(CC) -o crctest crctest.$(OBJEXT) $(CFLAGS) $(LDFLAGS) $(OBJS) +SRCS= $(srcdir)/crc32.c -crctest.exe: - $(CC) -o crctest.exe $(CFLAGS2) $(SRCS) +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs -check:: crctest$(EXEEXT) - $(C)crctest$(EXEEXT) < $(srcdir)$(S)crc-test +includes:: depend -clean:: - $(RM) crctest$(EXEEXT) crctest.$(OBJEXT) +depend:: $(SRCS) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/crc32/crc-32.h b/src/lib/crypto/crc32/crc-32.h index 28d0dc451..1b05b9ac6 100644 --- a/src/lib/crypto/crc32/crc-32.h +++ b/src/lib/crypto/crc32/crc-32.h @@ -24,11 +24,41 @@ * Definitions for the CRC-32 checksum */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #ifndef KRB5_CRC32__ #define KRB5_CRC32__ -#define CRC32_CKSUM_LENGTH (4*sizeof(krb5_octet)) +#define CRC32_CKSUM_LENGTH 4 + +void +mit_crc32 PROTOTYPE((krb5_const krb5_pointer in, krb5_const size_t in_length, + unsigned long *c)); extern krb5_checksum_entry crc32_cksumtable_entry; diff --git a/src/lib/crypto/crc32/crc32.c b/src/lib/crypto/crc32/crc32.c new file mode 100644 index 000000000..654981fc9 --- /dev/null +++ b/src/lib/crypto/crc32/crc32.c @@ -0,0 +1,166 @@ +/* + * lib/crypto/crc32/crc.c + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * + * CRC-32/AUTODIN-II routines + */ + +#include "k5-int.h" +#include "crc-32.h" + +/* This table and block of comments are taken from code labeled: */ +/* + * Copyright (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + */ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +static u_long const crc_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + +void +mit_crc32(in, in_length, cksum) + krb5_const krb5_pointer in; + krb5_const size_t in_length; + unsigned long *cksum; +{ + register u_char *data; + register u_long c = 0; + register int idx; + size_t i; + + data = (u_char *)in; + for (i = 0; i < in_length; i++) { + idx = (int) (data[i] ^ c); + idx &= 0xff; + c >>= 8; + c ^= crc_table[idx]; + } + + *cksum = c; +} diff --git a/src/lib/crypto/cryptoconf.c b/src/lib/crypto/cryptoconf.c deleted file mode 100644 index 62be74581..000000000 --- a/src/lib/crypto/cryptoconf.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * lib/crypto/cryptoconf.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. - * - * - * Cryptosystem configurations - */ - -#include "k5-int.h" - -#if defined(PROVIDE_DES_CBC_CRC) || defined(PROVIDE_CRC32) -#include "crc-32.h" -#define CRC32_CKENTRY &crc32_cksumtable_entry -#else -#define CRC32_CKENTRY 0 -#endif - -#ifdef PROVIDE_RSA_MD4 -#include "rsa-md4.h" -#define MD4_CKENTRY &rsa_md4_cksumtable_entry -#define MD4_DES_CKENTRY &rsa_md4_des_cksumtable_entry -#else -#define MD4_CKENTRY 0 -#define MD4_DES_CKENTRY 0 -#endif - -#ifdef PROVIDE_RSA_MD5 -#include "rsa-md5.h" -#define MD5_CKENTRY &rsa_md5_cksumtable_entry -#define MD5_DES_CKENTRY &rsa_md5_des_cksumtable_entry -#else -#define MD5_CKENTRY 0 -#define MD5_DES_CKENTRY 0 -#endif - -#ifdef PROVIDE_NIST_SHA -#include "shs.h" -/* #define SHA_CKENTRY &nist_sha_cksumtable_entry */ -/* #define HMAC_SHA_CKENTRY &hmac_sha_cksumtable_entry */ -#define SHA_CKENTRY 0 -#define HMAC_SHA_CKENTRY 0 -#else -#define SHA_CKENTRY 0 -#define HMAC_SHA_CKENTRY 0 -#endif - -#ifdef PROVIDE_SNEFRU -#define XEROX_CKENTRY &snefru_cksumtable_entry -#else -#define XEROX_CKENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_CKSUM -#include "des_int.h" -#define _DES_DONE__ -#define DES_CBC_CKENTRY &krb5_des_cbc_cksumtable_entry -#else -#define DES_CBC_CKENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_CRC -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_CRC_CSENTRY &krb5_des_crc_cst_entry -#else -#define DES_CBC_CRC_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_MD5 -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_MD5_CSENTRY &krb5_des_md5_cst_entry -#else -#define DES_CBC_MD5_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_RAW -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_RAW_CSENTRY &krb5_raw_des_cst_entry -#else -#define DES_CBC_RAW_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES3_CBC_SHA -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -/* Don't try to enable triple DES unless you know what you are doing; */ -/* the current implementation of triple DES is NOT the final and */ -/* correct implementation.!!! */ -/* #define DES3_CBC_SHA_CSENTRY &krb5_des3_sha_cst_entry */ -#define DES3_CBC_SHA_CSENTRY 0 -#else -#define DES3_CBC_SHA_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES3_CBC_RAW -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -/* #define DES3_CBC_RAW_CSENTRY &krb5_des3_raw_cst_entry */ -#define DES3_CBC_RAW_CSENTRY 0 -#else -#define DES3_CBC_RAW_CSENTRY 0 -#endif - - -/* WARNING: - make sure the order of entries in these tables matches the #defines in - "krb5/encryption.h" - */ - -krb5_cs_table_entry * NEAR krb5_enctype_array[] = { - 0, /* ENCTYPE_NULL */ - DES_CBC_CRC_CSENTRY, /* ENCTYPE_DES_CBC_CRC */ - 0, /* ENCTYPE_DES_CBC_MD4 */ - DES_CBC_MD5_CSENTRY, /* ENCTYPE_DES_CBC_MD5 */ - DES_CBC_RAW_CSENTRY, /* ENCTYPE_DES_CBC_RAW */ - DES3_CBC_SHA_CSENTRY, /* ENCTYPE_DES3_CBC_SHA */ - DES3_CBC_RAW_CSENTRY /* ENCTYPE_DES3_CBC_RAW */ -}; - -krb5_enctype krb5_max_enctype = sizeof(krb5_enctype_array)/sizeof(krb5_enctype_array[0]) - 1; - -krb5_checksum_entry * NEAR krb5_cksumarray[] = { - 0, - CRC32_CKENTRY, /* 1 - CKSUMTYPE_CRC32 */ - MD4_CKENTRY, /* 2 - CKSUMTYPE_RSA_MD4 */ - MD4_DES_CKENTRY, /* 3 - CKSUMTYPE_RSA_MD4_DES */ - DES_CBC_CKENTRY, /* 4 - CKSUMTYPE_DESCBC */ - 0, /* 5 - des-mac-k */ - 0, /* 6 - rsa-md4-des-k */ - MD5_CKENTRY, /* 7 - CKSUMTYPE_RSA_MD5 */ - MD5_DES_CKENTRY, /* 8 - CKSUMTYPE_RSA_MD5_DES */ - SHA_CKENTRY, /* 9 - CKSUMTYPE_NIST_SHA */ - HMAC_SHA_CKENTRY /* 10 - CKSUMTYPE_NIST_SHA_DES3 */ -}; - -krb5_cksumtype krb5_max_cksum = sizeof(krb5_cksumarray)/sizeof(krb5_cksumarray[0]); - -#undef _DES_DONE__ diff --git a/src/lib/crypto/decrypt.c b/src/lib/crypto/decrypt.c new file mode 100644 index 000000000..0d66ec0c0 --- /dev/null +++ b/src/lib/crypto/decrypt.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_decrypt(context, key, usage, ivec, input, output) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_enc_data *input; + krb5_data *output; +{ + int i; + + for (i=0; ienctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + if ((input->enctype != ENCTYPE_UNKNOWN) && + (krb5_enctypes_list[i].etype != input->enctype)) + return(KRB5_BAD_ENCTYPE); + + return((*(krb5_enctypes_list[i].decrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, &input->ciphertext, output)); +} diff --git a/src/lib/crypto/decrypt_data.c b/src/lib/crypto/decrypt_data.c deleted file mode 100644 index ae886d0c9..000000000 --- a/src/lib/crypto/decrypt_data.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "k5-int.h" - -/* - * This routine takes a key and a krb5_enc_data structure as input, and - * outputs the decrypted data in a krb5_data structure. Note that - * the krb5_data structure is not allocated. - */ -krb5_error_code -krb5_decrypt_data(context, key, ivec, enc_data, data) - krb5_context context; - krb5_keyblock * key; - krb5_pointer ivec; - krb5_enc_data * enc_data; - krb5_data * data; -{ - krb5_error_code retval; - krb5_encrypt_block eblock; - - krb5_use_enctype(context, &eblock, key->enctype); - data->length = enc_data->ciphertext.length; - if (!(data->data = malloc(data->length))) - return ENOMEM; - - if ((retval = krb5_process_key(context, &eblock, key)) != 0) - goto cleanup; - - if ((retval = krb5_decrypt(context, - (krb5_pointer) enc_data->ciphertext.data, - (krb5_pointer) data->data, - enc_data->ciphertext.length, &eblock, ivec))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - (void) krb5_finish_key(context, &eblock); - - return 0; - -cleanup: - if (data->data) { - free(data->data); - data->data = 0; - } - return retval; -} diff --git a/src/lib/crypto/des/.rconf b/src/lib/crypto/des/.rconf deleted file mode 100644 index b88696486..000000000 --- a/src/lib/crypto/des/.rconf +++ /dev/null @@ -1,8 +0,0 @@ -ignore fp.c -ignore ip.c -ignore key_perm.h -ignore odd.h -ignore p.c -ignore p_table.h -ignore s_table.h -ignore doc diff --git a/src/lib/crypto/des/ChangeLog b/src/lib/crypto/des/ChangeLog index e236a9cb9..70c431aa5 100644 --- a/src/lib/crypto/des/ChangeLog +++ b/src/lib/crypto/des/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz + + * *.c: replace the crypto layer. + Wed Feb 18 16:06:23 1998 Tom Yu * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/lib/crypto/des/FUNCTIONS b/src/lib/crypto/des/FUNCTIONS deleted file mode 100644 index 7ed082e32..000000000 --- a/src/lib/crypto/des/FUNCTIONS +++ /dev/null @@ -1,26 +0,0 @@ -File Function Where? - -weak_key.c mit_des_is_weak_key crypto -string2key.c mit_des_string_to_key ? -random_key.c mit_des_random_key ? -process_ky.c mit_des_process_key ? -new_rn_key.c mit_des_new_random_key ? - mit_des_init_random_number_generator ? - mit_des_set_random_generator_seed ? - mit_des_set_sequence_number ? - mit_des_generate_random_block ? -krb_glue.c mit_des_encrypt_func ? - mit_des_decrypt_func ? -key_sched.c mit_des_key_sched crypto -key_parity.c mit_des_fixup_key_parity crypto - mit_des_check_key_parity crypto -init_rkey.c mit_des_init_random_key crypto -finish_key.c mit_des_finish_key crypto -fin_rndkey.c mit_des_finish_random_key crypto -enc_dec.c mit_des_cbc_encrypt crypto -des.c mit_des_ecb_encrypt crypto -cs_entry.c (var) mit_des_cryptosystem_entry krb5 - (var) krb5_des_cst_entry krb5 - (var) mit_des_cbc_cksumtable_entry krb5 -cksum.c mit_des_cbc_cksum crypto -cbc_cksum.c mit_des_cbc_checksum crypto diff --git a/src/lib/crypto/des/Makefile.in b/src/lib/crypto/des/Makefile.in index 3f9311b96..fdef9e869 100644 --- a/src/lib/crypto/des/Makefile.in +++ b/src/lib/crypto/des/Makefile.in @@ -13,77 +13,41 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf STLIBOBJS=\ - afsstring2key.o \ - cbc_cksum.o \ - finish_key.o \ - fin_rndkey.o \ - init_rkey.o \ - process_ky.o \ - random_key.o \ - string2key.o \ - key_sched.o \ - weak_key.o \ + afsstring2key.o \ + d3_cbc.o \ + d3_kysched.o \ f_cbc.o \ - f_cksum.o \ - f_sched.o \ - f_ecb.o \ + f_cksum.o \ f_parity.o \ + f_sched.o \ f_tables.o \ - d3_cbc.o \ - d3_ecb.o \ - d3_kysched.o \ - d3_procky.o \ - d3_str2ky.o \ - u_nfold.o \ - u_rn_key.o - -OBJS= afsstring2key.$(OBJEXT) \ - cbc_cksum.$(OBJEXT) \ - finish_key.$(OBJEXT) \ - fin_rndkey.$(OBJEXT) \ - init_rkey.$(OBJEXT) \ - process_ky.$(OBJEXT) \ - random_key.$(OBJEXT) \ - string2key.$(OBJEXT) \ - key_sched.$(OBJEXT) \ - weak_key.$(OBJEXT) \ + key_sched.o \ + string2key.o \ + weak_key.o + +OBJS= afsstring2key.$(OBJEXT) \ + d3_cbc.$(OBJEXT) \ + d3_kysched.$(OBJEXT) \ f_cbc.$(OBJEXT) \ - f_cksum.$(OBJEXT) \ - f_sched.$(OBJEXT) \ - f_ecb.$(OBJEXT) \ + f_cksum.$(OBJEXT) \ f_parity.$(OBJEXT) \ + f_sched.$(OBJEXT) \ f_tables.$(OBJEXT) \ - d3_cbc.$(OBJEXT) \ - d3_ecb.$(OBJEXT) \ - d3_kysched.$(OBJEXT) \ - d3_procky.$(OBJEXT) \ - d3_str2ky.$(OBJEXT) \ - u_nfold.$(OBJEXT) \ - u_rn_key.$(OBJEXT) - -SRCS= $(srcdir)/afsstring2key.c \ - $(srcdir)/cbc_cksum.c \ - $(srcdir)/finish_key.c \ - $(srcdir)/fin_rndkey.c \ - $(srcdir)/init_rkey.c \ - $(srcdir)/process_ky.c \ - $(srcdir)/random_key.c \ - $(srcdir)/string2key.c \ + key_sched.$(OBJEXT) \ + string2key.$(OBJEXT) \ + weak_key.$(OBJEXT) + +SRCS= $(srcdir)/afsstring2key.c \ + $(srcdir)/d3_cbc.c \ + $(srcdir)/d3_kysched.c \ + $(srcdir)/f_cbc.c \ + $(srcdir)/f_cksum.c \ + $(srcdir)/f_parity.c \ + $(srcdir)/f_sched.c \ + $(srcdir)/f_tables.c \ $(srcdir)/key_sched.c \ $(srcdir)/weak_key.c \ - $(srcdir)/f_cbc.c \ - $(srcdir)/f_cksum.c \ - $(srcdir)/f_sched.c \ - $(srcdir)/f_ecb.c \ - $(srcdir)/f_parity.c \ - $(srcdir)/f_tables.c \ - $(srcdir)/d3_cbc.c \ - $(srcdir)/d3_ecb.c \ - $(srcdir)/d3_kysched.c \ - $(srcdir)/d3_procky.c \ - $(srcdir)/d3_str2ky.c \ - $(srcdir)/u_nfold.c \ - $(srcdir)/u_rn_key.c + $(srcdir)/string2key.c ##DOS##LIBOBJS = $(OBJS) @@ -93,22 +57,18 @@ includes:: depend depend:: $(SRCS) -# FIXME, this is left from the previous DES implementation. -clean:: - $(RM) fp.c ip.c key_perm.h odd.h p.c p_table.h s_table.h - -verify$(EXEEXT): t_verify.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ t_verify.$(OBJEXT) process_ky.o key_sched.o \ - ../cryptoconf.o ../des_crc.o $(KRB5_BASE_LIBS) +TOBJS = key_sched.$(OBJEXT) f_sched.$(OBJEXT) f_cbc.$(OBJEXT) \ + f_tables.$(OBJEXT) f_cksum.$(OBJEXT) -destest$(EXEEXT): destest.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ destest.$(OBJEXT) process_ky.o key_sched.o \ - ../cryptoconf.o ../des_crc.o $(KRB5_BASE_LIBS) +verify$(EXEEXT): t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ + $(COM_ERR_DEPLIB) + $(CC_LINK) -o $@ t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ + -lcom_err -t_random$(EXEEXT): t_random.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ t_random.$(OBJEXT) $(KRB5_BASE_LIBS) +destest$(EXEEXT): destest.$(OBJEXT) $(TOBJS) + $(CC_LINK) -o $@ destest.$(OBJEXT) $(TOBJS) -check-unix:: destest verify +check-unix:: verify destest $(RUN_SETUP) ./verify -z $(RUN_SETUP) ./verify -m $(RUN_SETUP) ./verify @@ -118,6 +78,6 @@ check-windows:: clean:: $(RM) destest$(EXEEXT) verify$(EXEEXT) destest.$(OBJEXT) \ - t_verify.$(OBJEXT) t_random.$(OBJEXT) t_random$(EXEEXT) + t_verify.$(OBJEXT) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/des/afsstring2key.c b/src/lib/crypto/des/afsstring2key.c index 36c42c482..7eac0807c 100644 --- a/src/lib/crypto/des/afsstring2key.c +++ b/src/lib/crypto/des/afsstring2key.c @@ -6,6 +6,32 @@ * constructed by Mark Eichin, Cygnus Support, 1995. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "des_int.h" #include @@ -13,8 +39,7 @@ static char *afs_crypt PROTOTYPE((char*,char*)); krb5_error_code -mit_afs_string_to_key (eblock, keyblock, data, salt) - const krb5_encrypt_block FAR * eblock; +mit_afs_string_to_key (keyblock, data, salt) krb5_keyblock FAR * keyblock; const krb5_data FAR * data; const krb5_data FAR * salt; @@ -29,7 +54,7 @@ mit_afs_string_to_key (eblock, keyblock, data, salt) register krb5_octet *key = keyblock->contents; if (data->length <= 8) { - char password[9]; /* trailing null for crypt() */ + char password[9]; /* trailing nul for crypt() */ strncpy(password, realm, 8); for (i=0; i<8; i++) if (isupper(password[i])) @@ -39,6 +64,7 @@ mit_afs_string_to_key (eblock, keyblock, data, salt) for (i=0; i<8; i++) if (password[i] == '\0') password[i] = 'X'; + password[8] = '\0'; strncpy(key, (char *) afs_crypt(password, "#~") + 2, 8); for (i=0; i<8; i++) key[i] <<= 1; diff --git a/src/lib/crypto/des/cbc_cksum.c b/src/lib/crypto/des/cbc_cksum.c deleted file mode 100644 index 29a38a0a5..000000000 --- a/src/lib/crypto/des/cbc_cksum.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * lib/crypto/des/cbc_cksum.c - * - * Copyright 1985, 1986, 1987, 1988, 1990 by the Massachusetts Institute - * of Technology. - * All Rights Reserved. - * - * Under U.S. law, this software may not be exported outside the US - * without license from the U.S. Commerce department. - * - * These routines form the library interface to the DES facilities. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - produces cbc cheksum of sequence "in" of the length "in_length" - with the help of key "key" of size "key_size" (which should be 8); - fills out krb5_checksum structure. - - caller is responsible for allocating & freeing "contents" element in - krb5_checksum structure. - - returns: errors -*/ - -static krb5_error_code mit_des_cbc_checksum - PROTOTYPE((krb5_const krb5_pointer, - krb5_const size_t, - krb5_const krb5_pointer, - krb5_const size_t, - krb5_checksum FAR * )); - -static krb5_error_code mit_des_cbc_verf_cksum - PROTOTYPE ((krb5_const krb5_checksum FAR *, - krb5_const krb5_pointer, - krb5_const size_t, - krb5_const krb5_pointer, - krb5_const size_t )); - -static krb5_error_code -mit_des_cbc_checksum(in, in_length, key, key_size, cksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer key; - krb5_const size_t key_size; - krb5_checksum FAR * cksum; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if (cksum->length < sizeof(mit_des_cblock)) - return KRB5_BAD_MSIZE; - if (key_size != sizeof(mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule)))) - return ENOMEM; - -#define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\ - free( (char *) schedule); } - - switch (mit_des_key_sched ((krb5_octet *)key, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - ; - } - - cksum->checksum_type = CKSUMTYPE_DESCBC; - cksum->length = sizeof(mit_des_cblock); - mit_des_cbc_cksum(in, cksum->contents, in_length, schedule, key); - - cleanup(); - - return 0; -} - -static krb5_error_code -mit_des_cbc_verf_cksum(cksum, in, in_length, key, key_size) - krb5_const krb5_checksum FAR * cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer key; - krb5_const size_t key_size; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - mit_des_cblock contents; - krb5_error_code retval; - - if (key_size != sizeof(mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule)))) - return ENOMEM; - -#define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\ - free( (char *) schedule); } - - switch (mit_des_key_sched ((krb5_octet *)key, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - ; - } - - mit_des_cbc_cksum(in, contents, in_length, schedule, key); - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_DESCBC) { - if (cksum->length == sizeof(mit_des_cblock)) { - if (memcmp((char *) cksum->contents, - (char *) contents, - sizeof(mit_des_cblock))) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - cleanup(); - - return retval; -} - -krb5_checksum_entry krb5_des_cbc_cksumtable_entry = { - 0, - mit_des_cbc_checksum, - mit_des_cbc_verf_cksum, - sizeof(mit_des_cblock), - 1, /* is collision proof */ - 1, /* is keyed */ -}; diff --git a/src/lib/crypto/des/d3_ecb.c b/src/lib/crypto/des/d3_ecb.c deleted file mode 100644 index 306f97dd6..000000000 --- a/src/lib/crypto/des/d3_ecb.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * 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 Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "des_int.h" -#include "f_tables.h" - -/* - * Triple-DES ECB encryption mode. - */ - -int -mit_des3_ecb_encrypt(in, out, sched1, sched2, sched3, encrypt) - const mit_des_cblock FAR *in; - mit_des_cblock FAR *out; - mit_des_key_schedule sched1, sched2, sched3; - int encrypt; -{ - if (encrypt) { - mit_des_ecb_encrypt(in, out, sched1, encrypt); - mit_des_ecb_encrypt(out, out, sched2, !encrypt); - mit_des_ecb_encrypt(out, out, sched3, encrypt); - } else { - mit_des_ecb_encrypt(in, out, sched3, encrypt); - mit_des_ecb_encrypt(out, out, sched2, !encrypt); - mit_des_ecb_encrypt(out, out, sched1, encrypt); - } - return 0; -} diff --git a/src/lib/crypto/des/d3_procky.c b/src/lib/crypto/des/d3_procky.c deleted file mode 100644 index 9c969a823..000000000 --- a/src/lib/crypto/des/d3_procky.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * 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 Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code -mit_des3_process_key (eblock, keyblock) - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if ((keyblock->enctype != ENCTYPE_DES3_CBC_SHA) && - (keyblock->enctype != ENCTYPE_DES3_CBC_RAW)) - return KRB5_PROG_ETYPE_NOSUPP; - - if (keyblock->length != sizeof (mit_des3_cblock)) - return KRB5_BAD_KEYSIZE; - - if ( !(schedule = (struct mit_des_ks_struct *) malloc(3*sizeof(mit_des_key_schedule))) ) - return ENOMEM; -#define cleanup() { free( (char *) schedule); } - - switch (mit_des3_key_sched (*(mit_des3_cblock *)keyblock->contents, - *(mit_des3_key_schedule *)schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - } - - eblock->key = (krb5_keyblock *) keyblock; - eblock->priv = (krb5_pointer) schedule; - eblock->priv_size = (krb5_int32) 3*sizeof(mit_des_key_schedule); - - return 0; -} diff --git a/src/lib/crypto/des/d3_str2ky.c b/src/lib/crypto/des/d3_str2ky.c deleted file mode 100644 index ed9f5183d..000000000 --- a/src/lib/crypto/des/d3_str2ky.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * 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 Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - * Triple-DES string-to-key algorithm - * - * 168-fold the input string (appended with any salt), and treat the resulting - * 168 bits as three DES keys sans parity. Process each set of 56 bits into - * a usable DES key with odd parity, and twice encrypt the set of three usable - * DES keys using Triple-DES CBC mode. The result is then treated as three - * DES keys, and should be corrected for parity. Any DES key that is weak or - * semi-weak is to be corrected by eXclusive-ORing with 00000000000000F0. - */ - -static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -krb5_error_code -mit_des3_string_to_key (eblock, keyblock, data, salt) -const krb5_encrypt_block FAR * eblock; -krb5_keyblock FAR * keyblock; -const krb5_data FAR * data; -const krb5_data FAR * salt; -{ - char *copystr; - mit_des_cblock *key; - unsigned int j; - - int length; - mit_des3_key_schedule ks; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; - - if ((enctype == ENCTYPE_DES3_CBC_SHA) || - (enctype == ENCTYPE_DES3_CBC_RAW)) - keyblock->length = sizeof(mit_des3_cblock); - else - return (KRB5_PROG_ETYPE_NOSUPP); - - if ( !(keyblock->contents = (krb5_octet *)malloc(keyblock->length)) ) - return(ENOMEM); - - keyblock->magic = KV5M_KEYBLOCK; - keyblock->enctype = enctype; - key = (mit_des_cblock *)keyblock->contents; - - if (salt) - length = data->length + salt->length; - else - length = data->length; - - if (length < keyblock->length) - length = keyblock->length; - - copystr = malloc((size_t) length); - if (!copystr) { - free(keyblock->contents); - keyblock->contents = 0; - return ENOMEM; - } - - memset(copystr, 0, length); - memcpy(copystr, (char *) data->data, data->length); - if (salt) - memcpy(copystr + data->length, (char *)salt->data, salt->length); - - /* n-fold into des3 key sans parity */ - if (mit_des_n_fold(copystr, length, keyblock->contents, - keyblock->length * 7 / 8)) - return EINVAL; - - /* Add space for parity (low bit) */ - for (j = keyblock->length; j--; ) { - register int k; - - k = (8-(j%8)) & 7; - keyblock->contents[j] = - ((keyblock->contents[j*7/8] << k) & 0xfe) + - ((k>1) ? keyblock->contents[j*7/8 +1] >> (8-k) : 0); - } - - /* fix key parity */ - for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) { - mit_des_fixup_key_parity(key[j]); - if (mit_des_is_weak_key(key[j])) - ((krb5_octet *)(key[j]))[7] ^= 0xf0; - } - - /* Now, CBC encrypt with itself */ - (void) mit_des3_key_sched(*((mit_des3_cblock *)key), ks); - (void) mit_des3_cbc_encrypt(key, key, keyblock->length, - ((mit_des_key_schedule *)ks)[0], - ((mit_des_key_schedule *)ks)[1], - ((mit_des_key_schedule *)ks)[2], - zero_ivec, TRUE); - (void) mit_des3_cbc_encrypt(key, key, keyblock->length, - ((mit_des_key_schedule *)ks)[0], - ((mit_des_key_schedule *)ks)[1], - ((mit_des_key_schedule *)ks)[2], - key[2], TRUE); - - /* erase key_sked */ - memset((char *)ks, 0, sizeof(ks)); - - /* clean & free the input string */ - memset(copystr, 0, (size_t) length); - krb5_xfree(copystr); - - /* now fix up key parity again */ - for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) { - mit_des_fixup_key_parity(key[j]); - if (mit_des_is_weak_key(key[j])) - ((krb5_octet *)(key[j]))[7] ^= 0xf0; - } - - return 0; -} diff --git a/src/lib/crypto/des/des.h b/src/lib/crypto/des/des.h deleted file mode 100644 index bd0a30b37..000000000 --- a/src/lib/crypto/des/des.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * include/des.h - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * - * For copying and distribution information, please see the file - * . - * - * Include file for the Data Encryption Standard library. - */ - -/* only do the whole thing once */ -#ifndef DES_DEFS -#define DES_DEFS - -#include "k5-int.h" - -#ifndef DES_INT32 -#ifdef SIZEOF_INT -#if SIZEOF_INT >= 4 -#define DES_INT32 int -#else -#define DES_INT32 long -#endif -#else /* !defined(SIZEOF_INT) */ -#include -#if (UINT_MAX >= 0xffffffff) -#define DES_INT32 int -#else -#define DES_INT32 long -#endif -#endif /* !defined(SIZEOF_INT) */ -#endif /* !defined(DES_INT32) */ - -#ifndef DES_UINT32 -#define DES_UINT32 unsigned DES_INT32 -#endif - -#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/src/lib/crypto/des/des_int.h b/src/lib/crypto/des/des_int.h index df8e9ca1e..0f8190861 100644 --- a/src/lib/crypto/des/des_int.h +++ b/src/lib/crypto/des/des_int.h @@ -24,6 +24,32 @@ * Private include file for the Data Encryption Standard library. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* only do the whole thing once */ #ifndef DES_INTERNAL_DEFS #define DES_INTERNAL_DEFS @@ -112,8 +138,7 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE) /* afsstring2key.c */ extern krb5_error_code mit_afs_string_to_key - PROTOTYPE((const krb5_encrypt_block FAR *eblock, - krb5_keyblock FAR *keyblock, + PROTOTYPE((krb5_keyblock FAR *keyblock, const krb5_data FAR *data, const krb5_data FAR *salt)); diff --git a/src/lib/crypto/des/destest.c b/src/lib/crypto/des/destest.c index 1e077a423..bf442e869 100644 --- a/src/lib/crypto/des/destest.c +++ b/src/lib/crypto/des/destest.c @@ -25,20 +25,43 @@ */ -#include "k5-int.h" +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "des_int.h" #include "com_err.h" -extern int errno; -extern mit_des_ecb_encrypt(); - #include - void convert PROTOTYPE((char *, unsigned char [])); void des_cblock_print_file PROTOTYPE((mit_des_cblock, FILE *)); +char zeroblock[8] = {0,0,0,0,0,0,0,0}; + void main(argc, argv) int argc; @@ -46,38 +69,23 @@ char *argv[]; { char block1[17], block2[17], block3[17]; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_context context; mit_des_cblock key, input, output, output2; - krb5_error_code retval; + mit_des_key_schedule sched; int num = 0; + int retval; int error = 0; - /* This is a crock and we know it... We win because - none of these tests rely on a valid context pointer */ - context = 0; - - /* do some initialisation */ - initialize_krb5_error_table(); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.magic = KV5M_KEYBLOCK; - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof (mit_des_cblock); - keyblock.contents = (krb5_octet *)key; while (scanf("%16s %16s %16s", block1, block2, block3) == 3) { convert(block1, key); convert(block2, input); convert(block3, output); - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des test", retval, "can't process key"); - exit(-1); + if (retval = mit_des_key_sched(key, sched)) { + fprintf(stderr, "des test: can't process key"); + exit(1); } - mit_des_ecb_encrypt(&input, &output2, - (struct mit_des_ks_struct *)eblock.priv,1); + mit_des_cbc_encrypt(&input, &output2, 8, sched, zeroblock, 1); if (memcmp((char *)output2, (char *)output, 8)) { fprintf(stderr, @@ -91,8 +99,7 @@ char *argv[]; /* * Now try decrypting.... */ - mit_des_ecb_encrypt(&output, &output2, - (struct mit_des_ks_struct *)eblock.priv,0); + mit_des_cbc_encrypt(&output, &output2, 8, sched, zeroblock, 0); if (memcmp((char *)output2, (char *)input, 8)) { fprintf(stderr, @@ -103,10 +110,6 @@ char *argv[]; error++; } - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key"); - exit(-1); - } num++; } @@ -157,7 +160,6 @@ unsigned char cblock[]; * Fake out the DES library, for the purposes of testing. */ -#include "des.h" #include "des_int.h" int diff --git a/src/lib/crypto/des/f_README b/src/lib/crypto/des/f_README deleted file mode 100644 index 0d381e373..000000000 --- a/src/lib/crypto/des/f_README +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -Sorry about the poor quality of installation instructions. Included -here are replacements for the DES portions of Eric Young's kerberos -DES library replacement. To use this you will need his distribution. -Untar the latter and: - -(1) Copy all .c and .h files into the distribution directory. This will - overwrite some files and add others. - -(2) Apply the patch included here to set_key.c in the distribution directory. - -(3) Edit the Imakefile (or the Makefile) to include the following files - on the SRCS= line: - - des_tables.c ecb_buffer.c make_sched.c - - Add the following files to the OBJS= line: - - des_tables.o ecb_buffer.o make_sched.o - - Add the following file to the CODE= line: - - des_tables.h - -Recompile and you're done. - -The salient differences between this DES and Eric Young's are as follows: - -(1) There are no dependencies on byte ordering, the ability to do - unaligned loads and stores, or any other machine dependencies - that I know of. There are no #ifdef's. The code could probably - be made faster by adding such things, but not enough to be worth - it. - -(2) Combined S and P tables are used for the inner loop of the cipher - routine and the E expansion is computed on the fly, like Eric - Young's code, but the computation is reordered from the standard - to save instructions. - -(3) The initial and final permutations are table driven, and take - about the same amount of work as a single round of the inner - loop (i.e. only about 12% of the work done for an ecb encryption - is spent in the IP and FP code). - -(4) Since NTP (for which this DES was originally implemented) uses - lots of keys to encrypt small things, the key permutation code - has been well worked over and is quite speedy (the amount of - work required to permute a key is on the order of that required - to do a single ECB encryption, more or less). - -(5) Since the code required to do an ECB encryption using the tables - is actually fairly compact, even with lots of inlining, it was - implemented as a macro and is expanded in situ where needed. - -On the one machine I ran a comparison on this code ran 80% faster than -Eric's, compiled into a slightly smaller space, and did pass destest. -I suspect this stuff is also faster, and not a lot larger, than the -library MIT doesn't export with kerberos. You mileage may vary. - -The silly copyright was a (probably ineffective) afterthought. If it -really inconveniences you give me a call. diff --git a/src/lib/crypto/des/f_ecb.c b/src/lib/crypto/des/f_ecb.c deleted file mode 100644 index a1d1dcb0c..000000000 --- a/src/lib/crypto/des/f_ecb.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -/* - * des_ecb_encrypt.c - do an encryption in ECB mode - */ -#include "des_int.h" -#include "f_tables.h" - -/* - * des_ecb_encrypt - {en,de}crypt a block in ECB mode - */ -int -mit_des_ecb_encrypt(in, out, schedule, encrypt) - const mit_des_cblock *in; - mit_des_cblock *out; - mit_des_key_schedule schedule; - int encrypt; -{ - register unsigned DES_INT32 left, right; - register unsigned DES_INT32 temp; - register int i; - - { - /* - * Need a temporary for copying the data in - */ - register unsigned char *datap; - - /* - * Copy the input block into the registers - */ - datap = (unsigned char *)in; - GET_HALF_BLOCK(left, datap); - GET_HALF_BLOCK(right, datap); - } - - /* - * Do the initial permutation. - */ - DES_INITIAL_PERM(left, right, temp); - - /* - * Now the rounds. Use different code depending on whether it - * is an encryption or a decryption (gross, should keep both - * sets of keys in the key schedule instead). - */ - if (encrypt) { - register unsigned DES_INT32 *kp; - - kp = (unsigned DES_INT32 *)schedule; - for (i = 0; i < 8; i++) { - DES_SP_ENCRYPT_ROUND(left, right, temp, kp); - DES_SP_ENCRYPT_ROUND(right, left, temp, kp); - } - } else { - register unsigned DES_INT32 *kp; - - /* - * Point kp past end of schedule - */ - kp = ((unsigned DES_INT32 *)schedule) + (2 * 16);; - for (i = 0; i < 8; i++) { - DES_SP_DECRYPT_ROUND(left, right, temp, kp); - DES_SP_DECRYPT_ROUND(right, left, temp, kp); - } - } - - /* - * Do the final permutation - */ - DES_FINAL_PERM(left, right, temp); - - /* - * Finally, copy the result out a byte at a time - */ - { - register unsigned char *datap; - - datap = (unsigned char *)out; - PUT_HALF_BLOCK(left, datap); - PUT_HALF_BLOCK(right, datap); - } - - /* - * return nothing - */ - return (0); -} diff --git a/src/lib/crypto/des/f_pcbc.c b/src/lib/crypto/des/f_pcbc.c deleted file mode 100644 index cb445446b..000000000 --- a/src/lib/crypto/des/f_pcbc.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -/* - * des_pcbc_encrypt.c - encrypt a string of characters in error propagation mode - */ -#include "des_int.h" -#include "f_tables.h" - -/* - * des_pcbc_encrypt - {en,de}crypt a stream in PCBC mode - */ -int -mit_des_pcbc_encrypt(in, out, length, schedule, ivec, encrypt) - mit_des_cblock *in; - mit_des_cblock *out; - long length; - mit_des_key_schedule schedule; - mit_des_cblock ivec; - int encrypt; -{ - register unsigned DES_INT32 left, right; - register unsigned DES_INT32 temp; - register unsigned DES_INT32 *kp; - register unsigned char *ip, *op; - - /* - * Copy the key pointer, just once - */ - kp = (unsigned DES_INT32 *)schedule; - - /* - * Deal with encryption and decryption separately. - */ - if (encrypt) { - register unsigned DES_INT32 plainl; - register unsigned DES_INT32 plainr; - - /* - * Initialize left and right with the contents of the initial - * vector. - */ - ip = (unsigned char *)ivec; - GET_HALF_BLOCK(left, ip); - GET_HALF_BLOCK(right, ip); - - /* - * Suitably initialized, now work the length down 8 bytes - * at a time. - */ - ip = (unsigned char *)in; - op = (unsigned char *)out; - while (length > 0) { - /* - * Get block of input. If the length is - * greater than 8 this is straight - * forward. Otherwise we have to fart around. - */ - if (length > 8) { - GET_HALF_BLOCK(plainl, ip); - GET_HALF_BLOCK(plainr, ip); - left ^= plainl; - right ^= plainr; - length -= 8; - } else { - /* - * Oh, shoot. We need to pad the - * end with zeroes. Work backwards - * to do this. We know this is the - * last block, though, so we don't have - * to save the plain text. - */ - ip += (int) length; - switch(length) { - case 8: - right ^= *(--ip) & FF_UINT32; - case 7: - right ^= (*(--ip) & FF_UINT32) << 8; - case 6: - right ^= (*(--ip) & FF_UINT32) << 16; - case 5: - right ^= (*(--ip) & FF_UINT32) << 24; - case 4: - left ^= *(--ip) & FF_UINT32; - case 3: - left ^= (*(--ip) & FF_UINT32) << 8; - case 2: - left ^= (*(--ip) & FF_UINT32) << 16; - case 1: - left ^= (*(--ip) & FF_UINT32) << 24; - break; - } - length = 0; - } - - /* - * Encrypt what we have - */ - DES_DO_ENCRYPT(left, right, temp, kp); - - /* - * Copy the results out - */ - PUT_HALF_BLOCK(left, op); - PUT_HALF_BLOCK(right, op); - - /* - * Xor with the old plain text - */ - left ^= plainl; - right ^= plainr; - } - } else { - /* - * Decrypting is harder than encrypting because of - * the necessity of remembering a lot more things. - * Should think about this a little more... - */ - unsigned DES_INT32 ocipherl, ocipherr; - unsigned DES_INT32 cipherl, cipherr; - - if (length <= 0) - return 0; - - /* - * Prime the old cipher with ivec. - */ - ip = (unsigned char *)ivec; - GET_HALF_BLOCK(ocipherl, ip); - GET_HALF_BLOCK(ocipherr, ip); - - /* - * Now do this in earnest until we run out of length. - */ - ip = (unsigned char *)in; - op = (unsigned char *)out; - for (;;) { /* check done inside loop */ - /* - * Read a block from the input into left and - * right. Save this cipher block for later. - */ - GET_HALF_BLOCK(left, ip); - GET_HALF_BLOCK(right, ip); - cipherl = left; - cipherr = right; - - /* - * Decrypt this. - */ - DES_DO_DECRYPT(left, right, temp, kp); - - /* - * Xor with the old cipher to get plain - * text. Output 8 or less bytes of this. - */ - left ^= ocipherl; - right ^= ocipherr; - if (length > 8) { - length -= 8; - PUT_HALF_BLOCK(left, op); - PUT_HALF_BLOCK(right, op); - /* - * Save current cipher block here - */ - ocipherl = cipherl ^ left; - ocipherr = cipherr ^ right; - } else { - /* - * Trouble here. Start at end of output, - * work backwards. - */ - op += (int) length; - switch(length) { - case 8: - *(--op) = (unsigned char) (right & 0xff); - case 7: - *(--op) = (unsigned char) ((right >> 8) & 0xff); - case 6: - *(--op) = (unsigned char) ((right >> 16) & 0xff); - case 5: - *(--op) = (unsigned char) ((right >> 24) & 0xff); - case 4: - *(--op) = (unsigned char) (left & 0xff); - case 3: - *(--op) = (unsigned char) ((left >> 8) & 0xff); - case 2: - *(--op) = (unsigned char) ((left >> 16) & 0xff); - case 1: - *(--op) = (unsigned char) ((left >> 24) & 0xff); - break; - } - break; /* we're done */ - } - } - } - - /* - * Done, return nothing. - */ - return 0; -} diff --git a/src/lib/crypto/des/fin_rndkey.c b/src/lib/crypto/des/fin_rndkey.c deleted file mode 100644 index 7b8a2c385..000000000 --- a/src/lib/crypto/des/fin_rndkey.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * lib/crypto/des/fin_rndkey.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. or Lehman Brothers not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. M.I.T. and Lehman Brothers - * make no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied - * warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - free any resources held by "seed" and assigned by init_random_key() - */ - -krb5_error_code mit_des_finish_random_key (eblock, p_state) - const krb5_encrypt_block * eblock; - krb5_pointer * p_state; -{ - mit_des_random_state * state = *p_state; - - if (! state) return 0; - - if (state->sequence.data) { - memset((char *)state->sequence.data, 0, state->sequence.length); - krb5_xfree(state->sequence.data); - } - - mit_des_finish_key(&state->eblock); - - krb5_xfree(state); - *p_state = 0; - return 0; -} diff --git a/src/lib/crypto/des/finish_key.c b/src/lib/crypto/des/finish_key.c deleted file mode 100644 index e7e9e13ae..000000000 --- a/src/lib/crypto/des/finish_key.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * lib/crypto/des/finish_key.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - does any necessary clean-up on the eblock (such as releasing - resources held by eblock->priv). - - returns: errors - */ - -krb5_error_code -mit_des_finish_key (eblock) - krb5_encrypt_block FAR * eblock; -{ - if (eblock->priv) { - memset((char *)eblock->priv, 0, (size_t) eblock->priv_size); - free(eblock->priv); - } - eblock->priv = 0; - eblock->priv_size = 0; - /* free/clear other stuff here? */ - return 0; -} diff --git a/src/lib/crypto/des/init_rkey.c b/src/lib/crypto/des/init_rkey.c deleted file mode 100644 index 5096647ec..000000000 --- a/src/lib/crypto/des/init_rkey.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * lib/crypto/des/init_rkey.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - initialize the random key generator using the encryption key, - "seedblock", and allocating private sequence information, filling - in "seed" with the address of such information. - "seed" is later passed to the random_key() function to provide - sequence information. - */ - -#ifndef min -#define min(a,b) (((a) > (b)) ? (b) : (a)) -#endif - -krb5_error_code -mit_des_init_random_key (eblock, seedblock, state) - const krb5_encrypt_block * eblock; - const krb5_keyblock * seedblock; - krb5_pointer * state; -{ - mit_des_random_state * p_state = 0; - krb5_keyblock *new_key; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; - krb5_error_code kret = 0; - krb5_address **addrs = 0; - krb5_data seed; - krb5_int32 now; - krb5_int32 unow; - unsigned char *cp; - - switch (enctype) - { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - enctype = ENCTYPE_DES_CBC_RAW; - break; - - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - enctype = ENCTYPE_DES3_CBC_RAW; - break; - - default: - return KRB5_BAD_ENCTYPE; - } - - p_state = (mit_des_random_state *) malloc(sizeof(mit_des_random_state)); - *state = (krb5_pointer) p_state; - - if (! p_state) { - kret = ENOMEM; - goto cleanup; - } - - memset(p_state, 0, sizeof(*p_state)); - p_state->eblock.crypto_entry = krb5_enctype_array[enctype]->system; - p_state->sequence.length = p_state->eblock.crypto_entry->keysize; - p_state->sequence.data = (krb5_pointer) malloc(p_state->sequence.length); - - if (! p_state->sequence.data) { - kret = ENOMEM; - goto cleanup; - } - - /* - * Generate a temporary value that is based on the - * input seed and the hostid (sequence number) - * such that it gives no useful information about the input. - * - * Then use the temporary value as the new seed and the current - * time as a sequence number to give us a stream that was not - * previously used. - * - * This result will be the seed for the random number stream - * (the sequence number will start at zero). - */ - - /* seed = input */ - seed.data = seedblock->contents; - seed.length = seedblock->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - if (kret) goto cleanup; - - /* sequence = hostid */ - if (!krb5_crypto_os_localaddr(&addrs) && addrs && *addrs) { - memcpy((char *)p_state->sequence.data, (char *)addrs[0]->contents, - min(p_state->sequence.length, addrs[0]->length)); - /* XXX may not do all of the sequence number. */ - } - if (addrs) { - /* can't use krb5_free_addresses due to circular dependencies in - libraries */ - register krb5_address **addr2; - for (addr2 = addrs; *addr2; addr2++) { - krb5_xfree((*addr2)->contents); - krb5_xfree(*addr2); - } - krb5_xfree(addrs); - } - - /* tmp.seed = random(input,hostid) */ - kret = mit_des_random_key(NULL, p_state, &new_key); - if (kret) goto cleanup; - seed.data = new_key->contents; - seed.length = new_key->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - (void) memset(new_key->contents, 0, new_key->length); - krb5_xfree(new_key->contents); - krb5_xfree(new_key); - if (kret) goto cleanup; - - /* sequence = time */ - (void) krb5_crypto_us_timeofday(&now, &unow); - cp = p_state->sequence.data; - *cp++ = (now >> 24) & 0xff; - *cp++ = (now >> 16) & 0xff; - *cp++ = (now >> 8) & 0xff; - *cp++ = now & 0xff; - *cp++ = (unow >> 24) & 0xff; - *cp++ = (unow >> 16) & 0xff; - *cp++ = (unow >> 8) & 0xff; - *cp++ = unow &0xff; - - /* seed = random(tmp.seed, time) */ - kret = mit_des_random_key(NULL, p_state, &new_key); - if (kret) goto cleanup; - seed.data = new_key->contents; - seed.length = new_key->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - (void) memset(new_key->contents, 0, new_key->length); - krb5_xfree(new_key->contents); - krb5_xfree(new_key); - if (kret) goto cleanup; - - return 0; - -cleanup: - if (kret) - mit_des_finish_random_key(eblock, state); - return kret; -} diff --git a/src/lib/crypto/des/process_ky.c b/src/lib/crypto/des/process_ky.c deleted file mode 100644 index 64cef57ad..000000000 --- a/src/lib/crypto/des/process_ky.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * lib/crypto/des/process_ky.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - does any necessary key preprocessing (such as computing key - schedules for DES). - eblock->crypto_entry must be set by the caller; the other elements - of eblock are to be assigned by this function. - [in particular, eblock->key must be set by this function if the key - is needed in raw form by the encryption routine] - - The caller may not move or reallocate "keyblock" before calling - finish_key on "eblock" - - returns: errors - */ - -krb5_error_code -mit_des_process_key (eblock, keyblock) - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if (keyblock->length != sizeof (mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if ( !(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule))) ) - return ENOMEM; -#define cleanup() { free( (char *) schedule); } - - switch (mit_des_key_sched (keyblock->contents, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - eblock->key = (krb5_keyblock *) keyblock; - eblock->priv = (krb5_pointer) schedule; - eblock->priv_size = (krb5_int32) sizeof(mit_des_key_schedule); - return 0; - } -} diff --git a/src/lib/crypto/des/random_key.c b/src/lib/crypto/des/random_key.c deleted file mode 100644 index 1dc4600b4..000000000 --- a/src/lib/crypto/des/random_key.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * lib/crypto/des/random_key.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. or Lehman Brothers not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. M.I.T. and Lehman Brothers - * make no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied - * warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -static void mit_des_generate_random_key - PROTOTYPE((mit_des_random_state * state, krb5_keyblock * randkey)); - - -/* - generate a random encryption key, allocating storage for it and - filling in the keyblock address in *keyblock - */ - -krb5_error_code -mit_des_random_key (eblock, state, keyblock) - const krb5_encrypt_block * eblock; - krb5_pointer state; - krb5_keyblock ** keyblock; -{ - krb5_keyblock *randkey; - int keysize = ((mit_des_random_state *)state)->eblock.crypto_entry->keysize; - - if (eblock == NULL) - /* We are being called from the random number initialization routine */ - eblock = &((mit_des_random_state *)state)->eblock; - - if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey)))) - return ENOMEM; - if (!(randkey->contents = (krb5_octet *)malloc(keysize))) { - krb5_xfree(randkey); - return ENOMEM; - } - randkey->magic = KV5M_KEYBLOCK; - randkey->length = keysize; - randkey->enctype = eblock->crypto_entry->proto_enctype; - - do { - mit_des_generate_random_key(state, randkey); - mit_des_fixup_keyblock_parity(randkey); - } while (mit_des_is_weak_keyblock(randkey)); - - *keyblock = randkey; - return 0; -} - -static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -static void -mit_des_generate_random_key(state, randkey) - mit_des_random_state * state; - krb5_keyblock * randkey; -{ - krb5_encrypt_block *eblock = &state->eblock; - int i; - - (* state->eblock.crypto_entry->encrypt_func) - (state->sequence.data /*in*/, randkey->contents /*out*/, - state->sequence.length, eblock, zero_ivec); - if (state->sequence.length > sizeof(mit_des_cblock)) - (* state->eblock.crypto_entry->encrypt_func) - (randkey->contents /*in*/, randkey->contents /*out*/, - randkey->length, eblock, - randkey->contents + randkey->length - sizeof(mit_des_cblock)); - - /* Increment the sequence number, with wraparound (LSB) */ - for (i = 0; i < state->sequence.length; i++) { - state->sequence.data[i] = (state->sequence.data[i] + 1) & 0xff; - if (state->sequence.data[i]) - break; - } -} diff --git a/src/lib/crypto/des/string2key.c b/src/lib/crypto/des/string2key.c index 8a2b1415b..79b7c9cbd 100644 --- a/src/lib/crypto/des/string2key.c +++ b/src/lib/crypto/des/string2key.c @@ -21,6 +21,32 @@ * or implied warranty. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "des_int.h" @@ -41,8 +67,7 @@ */ krb5_error_code -mit_des_string_to_key (eblock, keyblock, data, salt) -const krb5_encrypt_block FAR * eblock; +mit_des_string_to_key_int (keyblock, data, salt) krb5_keyblock FAR * keyblock; const krb5_data FAR * data; const krb5_data FAR * salt; @@ -59,28 +84,19 @@ const krb5_data FAR * salt; register char *p_char; char k_char[64]; mit_des_key_schedule key_sked; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; #ifndef min #define min(A, B) ((A) < (B) ? (A): (B)) #endif - if ((enctype != ENCTYPE_DES_CBC_CRC) && (enctype != ENCTYPE_DES_CBC_MD4) && - (enctype != ENCTYPE_DES_CBC_MD5) && (enctype != ENCTYPE_DES_CBC_RAW)) - return (KRB5_PROG_ETYPE_NOSUPP); - - if ( !(keyblock->contents = (krb5_octet *)malloc(sizeof(mit_des_cblock))) ) - return(ENOMEM); - keyblock->magic = KV5M_KEYBLOCK; keyblock->length = sizeof(mit_des_cblock); - keyblock->enctype = eblock->crypto_entry->proto_enctype; key = keyblock->contents; if (salt) { if (salt->length == -1) { /* cheat and do AFS string2key instead */ - return mit_afs_string_to_key (eblock, keyblock, data, salt); + return mit_afs_string_to_key (keyblock, data, salt); } else length = data->length + salt->length; } diff --git a/src/lib/crypto/des/t_random.c b/src/lib/crypto/des/t_random.c deleted file mode 100644 index bc013bdab..000000000 --- a/src/lib/crypto/des/t_random.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * lib/crypto/des/t_random.c - * - * Copyright 1996 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. - * - * - * Test a DES implementation against known inputs & outputs - */ - -#include "k5-int.h" -#include "des_int.h" -#include -#include "com_err.h" - -extern krb5_cryptosystem_entry mit_des_cryptosystem_entry; - -char *progname; -int nflag = 2; -int vflag; -int mflag; -int zflag; -int pid; -int mit_des_debug; - -krb5_data kdata; - -unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f }; -unsigned char zerokey[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - -void print_key(key) - krb5_keyblock *key; -{ - int i; - - printf("key type: %d, length = %d, contents =", key->enctype, - key->length); - for (i=0; i < key->length; i++) { - printf(" %02x", key->contents[i]); - } - printf("\n"); -} - -/* - * Can also add : - * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?) - */ - -void -main(argc,argv) - int argc; - char *argv[]; -{ - /* Local Declarations */ - krb5_context context; - krb5_encrypt_block eblock; - krb5_keyblock keyblock, *randkey; - void *random_seed = 0; - -#ifdef WINDOWS - /* Set screen window buffer to infinite size -- MS default is tiny. */ - _wsetscreenbuf (fileno (stdout), _WINBUFINF); -#endif - - /* do some initialisation */ - krb5_init_context(&context); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - - keyblock.contents = key2; - - printf("init_random: "); - print_key(&keyblock); - krb5_init_random_key(context, &eblock, &keyblock, &random_seed); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_finish_random_key(context, &eblock, &random_seed); - - keyblock.contents = zerokey; - - printf("\n\ninit_random: "); - print_key(&keyblock); - - krb5_init_random_key(context, &eblock, &keyblock, &random_seed); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_finish_random_key(context, &eblock, &random_seed); - - krb5_free_context(context); -} - diff --git a/src/lib/crypto/des/t_verify.c b/src/lib/crypto/des/t_verify.c index 82a73e21f..e8a7dc0ee 100644 --- a/src/lib/crypto/des/t_verify.c +++ b/src/lib/crypto/des/t_verify.c @@ -28,13 +28,37 @@ * -1 ==> error */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "des_int.h" #include #include "com_err.h" -extern krb5_cryptosystem_entry mit_des_cryptosystem_entry; - char *progname; int nflag = 2; int vflag; @@ -43,10 +67,6 @@ int zflag; int pid; int mit_des_debug; -krb5_encrypt_block eblock; -krb5_keyblock keyblock; -krb5_data kdata; - unsigned char cipher_text[64]; unsigned char clear_text[64] = "Now is the time for all " ; unsigned char clear_text2[64] = "7654321 Now is the time for "; @@ -56,23 +76,6 @@ unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0}; unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */ unsigned char *input; -unsigned char *nfold_in[] = { - "basch", - "eichin", - "sommerfeld", - "MASSACHVSETTS INSTITVTE OF TECHNOLOGY" }; - -unsigned char nfold_192[4][24] = { - { 0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde, 0x2d, - 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31, 0x64, 0x3f }, - { 0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b, 0x1b, 0x43, - 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0, 0xd2, 0xdc, 0xca }, - { 0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4, 0xe7, 0x11, - 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5, 0xde, 0xf7, 0x5c }, - { 0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82, 0xb3, 0x08, - 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9, 0x54, 0x0c, 0x1b } -}; - /* 0x0123456789abcdef */ unsigned char default_key[8] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef @@ -86,7 +89,6 @@ unsigned char default_ivec[8] = { unsigned char *ivec; unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */ int i,j; -krb5_error_code retval; unsigned char cipher1[8] = { 0x25,0xdd,0xac,0x3e,0x96,0x17,0x64,0x67 @@ -117,14 +119,15 @@ unsigned char mresult[8] = { * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?) */ -void +mit_des_key_schedule sched; + +int main(argc,argv) int argc; char *argv[]; { /* Local Declarations */ - krb5_context context; - int in_length; + int in_length, retval; void do_encrypt(); void do_decrypt(); @@ -164,23 +167,13 @@ main(argc,argv) } /* do some initialisation */ - initialize_krb5_error_table(); - krb5_init_context(&context); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); /* use known input and key */ /* ECB zero text zero key */ if (zflag) { input = zero_text; - keyblock.contents = (krb5_octet *)zero_key; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process zero key"); - exit(-1); - } + mit_des_key_sched(zero_key, sched); printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n"); do_encrypt(input,cipher_text); printf("\tcipher = (low to high bytes)\n\t\t"); @@ -188,26 +181,17 @@ main(argc,argv) printf("%02x ",cipher_text[j]); printf("\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish zero key"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)zresult, 8) ) { printf("verify: error in zero key test\n"); exit(-1); } - krb5_free_context(context); exit(0); } if (mflag) { input = msb_text; - keyblock.contents = (krb5_octet *)key3; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key3"); - exit(-1); - } + mit_des_key_sched(key3, sched); printf("plaintext = 0x00 00 00 00 00 00 00 40, "); printf("key = 0x80 01 01 01 01 01 01 01\n"); printf(" cipher = 0xa380e02a6be54696\n"); @@ -218,26 +202,17 @@ main(argc,argv) } printf("\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key3"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)mresult, 8) ) { printf("verify: error in msb test\n"); exit(-1); } - krb5_free_context(context); exit(0); } /* ECB mode Davies and Price */ { input = zero_text; - keyblock.contents = (krb5_octet *)key2; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key2"); - exit(-1); - } + mit_des_key_sched(key2, sched); printf("Examples per FIPS publication 81, keys ivs and cipher\n"); printf("in hex. These are the correct answers, see below for\n"); printf("the actual answers.\n\n"); @@ -253,10 +228,6 @@ main(argc,argv) printf("%02x ",cipher_text[j]); printf("\n\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key2"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)cipher1, 8) ) { printf("verify: error in ECB encryption\n"); exit(-1); @@ -267,11 +238,7 @@ main(argc,argv) /* ECB mode */ { - keyblock.contents = (krb5_octet *)default_key; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key2"); - exit(-1); - } + mit_des_key_sched(default_key, sched); input = clear_text; ivec = default_ivec; printf("EXAMPLE ECB\tkey = 0123456789abcdef\n"); @@ -306,14 +273,14 @@ main(argc,argv) if (retval = mit_des_cbc_encrypt((mit_des_cblock *) input, (mit_des_cblock *) cipher_text, (size_t) in_length, - (struct mit_des_ks_struct *)eblock.priv, + sched, ivec, MIT_DES_ENCRYPT)) { com_err("des verify", retval, "can't encrypt"); exit(-1); } printf("\tciphertext = (low to high bytes)\n"); - for (i = 0; i <= 7; i++) { + for (i = 0; i <= 2; i++) { printf("\t\t"); for (j = 0; j <= 7; j++) { printf("%02x ",cipher_text[i*8+j]); @@ -323,7 +290,7 @@ main(argc,argv) if (retval = mit_des_cbc_encrypt((mit_des_cblock *) cipher_text, (mit_des_cblock *) clear_text, (size_t) in_length, - eblock.priv, + sched, ivec, MIT_DES_DECRYPT)) { com_err("des verify", retval, "can't decrypt"); @@ -345,16 +312,12 @@ main(argc,argv) printf("or some part thereof\n"); input = clear_text2; mit_des_cbc_cksum(input,cipher_text,(long) strlen((char *)input), - eblock.priv,ivec); + sched,ivec); printf("ACTUAL CBC checksum\n"); printf("\t\tencrypted cksum = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) printf("%02x ",cipher_text[j]); printf("\n\n"); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key2"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)checksum, 8) ) { printf("verify: error in CBC cheksum\n"); exit(-1); @@ -362,25 +325,6 @@ main(argc,argv) else printf("verify: CBC checksum is correct\n\n"); - printf("N-fold\n"); - for (i=0; i> (k&7)) : 0)) - & 0xff; - - for (k=0, j=inlen; j--; ) { - k += outbuf[(bytes+j) % outlen] + tempbuf[j]; - outbuf[(bytes+j) % outlen] = k & 0xff; - k >>= 8; - } - j = bytes % outlen; - while (k) { - if (j == 0) - j = outlen; - j--; - k += outbuf[j]; - outbuf[j] = k & 0xff; - k >>= 8; - } - bytes += inlen; - } while (bytes % outlen); - - free(tempbuf); - - return 0; -} diff --git a/src/lib/crypto/des/u_rn_key.c b/src/lib/crypto/des/u_rn_key.c deleted file mode 100644 index 44d3c7383..000000000 --- a/src/lib/crypto/des/u_rn_key.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 1996 by Richard P. Basch. All Rights Reserved. - * Copyright 1996 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * 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 Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * - * Based on the version written by Mark Lillibridge, MIT Project Athena. - * - * Under U.S. law, this software may not be exported outside the US - * without license from the U.S. Commerce department. - */ - -#include "k5-int.h" -#include "des_int.h" - -int -mit_des_is_weak_keyblock(keyblock) - krb5_keyblock * keyblock; -{ - int i; - - for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) - if (mit_des_is_weak_key(*((mit_des_cblock *)keyblock->contents + i))) - return 1; - return 0; -} - -void -mit_des_fixup_keyblock_parity(keyblock) - krb5_keyblock * keyblock; -{ - int i; - - for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) - mit_des_fixup_key_parity(*((mit_des_cblock *)keyblock->contents + i)); -} - -/* - * mit_des_set_random_generator_seed: this routine is used to select a random - * number stream. The stream that results is - * totally determined by the passed in key. - * (I.e., calling this routine again with the - * same key allows repeating a sequence of - * random numbers) - */ -krb5_error_code -mit_des_set_random_generator_seed(seed, p_state) - const krb5_data * seed; - krb5_pointer p_state; -{ - krb5_error_code kret; - register int i; - mit_des_cblock *new_key; - mit_des_random_state *state = p_state; - - if (state->eblock.key) { - if (state->eblock.key->contents) { - memset(state->eblock.key->contents, 0, state->eblock.key->length); - krb5_xfree(state->eblock.key->contents); - } - } - - state->eblock.key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)); - if (! state->eblock.key) - return ENOMEM; - - state->eblock.key->enctype = state->eblock.crypto_entry->proto_enctype; - state->eblock.key->length = state->eblock.crypto_entry->keysize; - state->eblock.key->contents = (krb5_octet *)malloc(state->eblock.key->length); - if (! state->eblock.key->contents) { - krb5_xfree(state->eblock.key); - state->eblock.key = 0; - return ENOMEM; - } - - kret = mit_des_n_fold(seed->data, seed->length, - state->eblock.key->contents, state->eblock.key->length); - if (kret) return kret; - - mit_des_fixup_keyblock_parity(state->eblock.key); - - for (i = 0; i < state->eblock.key->length/sizeof(mit_des_cblock); i++) { - new_key = (mit_des_cblock *)state->eblock.key->contents + i; - if (mit_des_is_weak_key(*new_key)) { - (*new_key)[0] ^= 0xF0; - mit_des_fixup_key_parity(*new_key); - } - } - - /* destroy any old key schedule */ - mit_des_finish_key(&state->eblock); - - /* compute the key schedule */ - (* state->eblock.crypto_entry->process_key) - (&state->eblock, state->eblock.key); - - /* now we can destroy the key... */ - memset(state->eblock.key->contents, 0, state->eblock.key->length); - krb5_xfree(state->eblock.key->contents); - krb5_xfree(state->eblock.key); - state->eblock.key = (krb5_keyblock *) 0; - - /* "seek" to the start of the stream: */ - memset(state->sequence.data, 0, state->sequence.length); - - return 0; -} - -krb5_error_code -mit_des_set_random_sequence_number(sequence, p_state) - const krb5_data *sequence; - krb5_pointer p_state; -{ - mit_des_random_state *state = p_state; - int length = state->eblock.crypto_entry->keysize; - - if (length > sequence->length) - length = sequence->length; - - memcpy(state->sequence.data, sequence->data, length); - - return 0; -} diff --git a/src/lib/crypto/des3_raw.c b/src/lib/crypto/des3_raw.c deleted file mode 100644 index 62e3d724d..000000000 --- a/src/lib/crypto/des3_raw.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * lib/crypto/des3_raw.c - * - * Copyright 1996 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code mit_des3_raw_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des3_raw_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_cryptosystem_entry mit_des3_raw_cryptosystem_entry = { - 0, - mit_des3_raw_encrypt_func, - mit_des3_raw_decrypt_func, - mit_des3_process_key, - mit_des_finish_key, - mit_des3_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - 0, - sizeof(mit_des3_cblock), - ENCTYPE_DES3_CBC_RAW - }; - -krb5_cs_table_entry krb5_des3_raw_cst_entry = { - 0, - &mit_des3_raw_cryptosystem_entry, - 0 - }; - -krb5_error_code -mit_des3_raw_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - return (mit_des3_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *)key->priv, - ((struct mit_des_ks_struct *)key->priv) + 1, - ((struct mit_des_ks_struct *)key->priv) + 2, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT)); -} - -krb5_error_code -mit_des3_raw_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - int sumsize; - - /* round up to des block size */ - - sumsize = krb5_roundup(size, sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - memcpy((char *)out, (char *)in, size); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des3_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *)key->priv, - ((struct mit_des_ks_struct *)key->priv) + 1, - ((struct mit_des_ks_struct *)key->priv) + 2, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); -} diff --git a/src/lib/crypto/des3_sha.c b/src/lib/crypto/des3_sha.c deleted file mode 100644 index 9b060e589..000000000 --- a/src/lib/crypto/des3_sha.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * lib/crypto/des3-sha.c - * - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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 Lehman Brothers or M.I.T. not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. Lehman Brothers and - * M.I.T. make no representations about the suitability of this - * software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "shs.h" -#include "des_int.h" - - -#define DES3_SHA_CONFOUNDER_SIZE sizeof(mit_des_cblock) - -static krb5_error_code -mit_des3_sha_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_error_code -mit_des3_sha_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static mit_des_cblock zero_ivec = { 0 }; - -static krb5_cryptosystem_entry mit_des3_sha_cryptosystem_entry = { - 0, - mit_des3_sha_encrypt_func, - mit_des3_sha_decrypt_func, - mit_des3_process_key, - mit_des_finish_key, - mit_des3_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - NIST_SHA_CKSUM_LENGTH + DES3_SHA_CONFOUNDER_SIZE, - sizeof(mit_des3_cblock), - ENCTYPE_DES3_CBC_SHA - }; - -krb5_cs_table_entry krb5_des3_sha_cst_entry = { - 0, - &mit_des3_sha_cryptosystem_entry, - 0 - }; - - -static krb5_error_code -mit_des3_sha_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[NIST_SHA_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes - our checksum is NIST_SHA_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size + mit_des3_sha_cryptosystem_entry.pad_minimum, - mit_des3_sha_cryptosystem_entry.block_length); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(DES3_SHA_CONFOUNDER_SIZE, out))) - return retval; - - memcpy((char *)out + mit_des3_sha_cryptosystem_entry.pad_minimum, - (char *)in, size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_SHA,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - retval = nist_sha_cksumtable_entry.sum_func((krb5_pointer) out, sumsize, - 0, 0, &cksum); - if (retval) - return retval; - - memcpy((char *)out + DES3_SHA_CONFOUNDER_SIZE, - (char *)contents, NIST_SHA_CKSUM_LENGTH); - - /* We depend here on the ability of this DES-3 implementation to - encrypt plaintext to ciphertext in-place. */ - retval = mit_des3_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ((struct mit_des_ks_struct *) key->priv) + 1, - ((struct mit_des_ks_struct *) key->priv) + 2, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_ENCRYPT); - return retval; -} - -static krb5_error_code -mit_des3_sha_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[NIST_SHA_CKSUM_LENGTH]; - krb5_octet contents_get[NIST_SHA_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < krb5_roundup(mit_des3_sha_cryptosystem_entry.pad_minimum, - mit_des3_sha_cryptosystem_entry.block_length)) - return KRB5_BAD_MSIZE; - - retval = mit_des3_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ((struct mit_des_ks_struct *) key->priv) + 1, - ((struct mit_des_ks_struct *) key->priv) + 2, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + DES3_SHA_CONFOUNDER_SIZE; - memcpy((char *)contents_get, p, NIST_SHA_CKSUM_LENGTH); - memset(p, 0, NIST_SHA_CKSUM_LENGTH); - - retval = nist_sha_cksumtable_entry.sum_func(out, size, 0, 0, &cksum); - if (retval) - return retval; - - if (memcmp((char *)contents_get, - (char *)contents_prd, - NIST_SHA_CKSUM_LENGTH)) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - memmove((char *)out, (char *)out + - mit_des3_sha_cryptosystem_entry.pad_minimum, - size - mit_des3_sha_cryptosystem_entry.pad_minimum); - return 0; -} diff --git a/src/lib/crypto/des_crc.c b/src/lib/crypto/des_crc.c deleted file mode 100644 index 6317f61d7..000000000 --- a/src/lib/crypto/des_crc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * lib/crypto/des-crc.32 - * - * Copyright 1994 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "crc-32.h" -#include "des_int.h" - -krb5_error_code mit_des_crc_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des_crc_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - - -static krb5_cryptosystem_entry mit_des_crc_cryptosystem_entry = { - 0, - mit_des_crc_encrypt_func, - mit_des_crc_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_CRC - }; - -krb5_cs_table_entry krb5_des_crc_cst_entry = { - 0, - &mit_des_crc_cryptosystem_entry, - 0 - }; - - -krb5_error_code -mit_des_crc_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[CRC32_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - -/* if ( size < sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; */ - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes (one cblock); - our checksum is CRC32_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size+CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock)+CRC32_CKSUM_LENGTH, (char *)in, - size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_CRC32,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - if ((retval = crc32_cksumtable_entry.sum_func((krb5_pointer) out, - sumsize, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents, - CRC32_CKSUM_LENGTH); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); - -} - -krb5_error_code -mit_des_crc_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[CRC32_CKSUM_LENGTH]; - krb5_octet contents_get[CRC32_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < 2*sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; - - retval = mit_des_cbc_encrypt((const mit_des_cblock FAR *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + sizeof(mit_des_cblock); - memcpy((char *)contents_get, p, CRC32_CKSUM_LENGTH); - memset(p, 0, CRC32_CKSUM_LENGTH); - - if ((retval = crc32_cksumtable_entry.sum_func(out, size, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - if (memcmp((char *)contents_get, (char *)contents_prd, CRC32_CKSUM_LENGTH) ) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - memmove((char *)out, (char *)out + - sizeof(mit_des_cblock) + CRC32_CKSUM_LENGTH, - size - sizeof(mit_des_cblock) - CRC32_CKSUM_LENGTH); - return 0; -} diff --git a/src/lib/crypto/des_md5.c b/src/lib/crypto/des_md5.c deleted file mode 100644 index 6794f568f..000000000 --- a/src/lib/crypto/des_md5.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * lib/crypto/des-md5.32 - * - * Copyright 1994 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "rsa-md5.h" -#include "des_int.h" - -krb5_error_code mit_des_md5_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des_md5_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static mit_des_cblock zero_ivec = { 0 }; - -static krb5_cryptosystem_entry mit_des_md5_cryptosystem_entry = { - 0, - mit_des_md5_encrypt_func, - mit_des_md5_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_MD5 - }; - -krb5_cs_table_entry krb5_des_md5_cst_entry = { - 0, - &mit_des_md5_cryptosystem_entry, - 0 - }; - - -krb5_error_code -mit_des_md5_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[RSA_MD5_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - -/* if ( size < sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; */ - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes (one cblock); - our checksum is RSA_MD5_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size+RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock)+RSA_MD5_CKSUM_LENGTH, (char *)in, - size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_MD5,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - if ((retval = rsa_md5_cksumtable_entry.sum_func((krb5_pointer) out, - sumsize, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents, - RSA_MD5_CKSUM_LENGTH); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_ENCRYPT)); - -} - -krb5_error_code -mit_des_md5_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[RSA_MD5_CKSUM_LENGTH]; - krb5_octet contents_get[RSA_MD5_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < 2*sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; - - retval = mit_des_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + sizeof(mit_des_cblock); - memcpy((char *)contents_get, p, RSA_MD5_CKSUM_LENGTH); - memset(p, 0, RSA_MD5_CKSUM_LENGTH); - - if ((retval = rsa_md5_cksumtable_entry.sum_func(out, size, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - if (memcmp((char *)contents_get, (char *)contents_prd, RSA_MD5_CKSUM_LENGTH) ) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - memmove((char *)out, (char *)out + - sizeof(mit_des_cblock) + RSA_MD5_CKSUM_LENGTH, - size - sizeof(mit_des_cblock) - RSA_MD5_CKSUM_LENGTH); - return 0; -} diff --git a/src/lib/crypto/encrypt.c b/src/lib/crypto/encrypt.c new file mode 100644 index 000000000..76b8c8403 --- /dev/null +++ b/src/lib/crypto/encrypt.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_encrypt(context, key, usage, ivec, input, output) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_enc_data *output; +{ + int i; + + for (i=0; ienctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + output->magic = KV5M_ENC_DATA; + output->kvno = 0; + output->enctype = key->enctype; + + return((*(krb5_enctypes_list[i].encrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, input, &output->ciphertext)); +} diff --git a/src/lib/crypto/encrypt_data.c b/src/lib/crypto/encrypt_data.c deleted file mode 100644 index b2f039f33..000000000 --- a/src/lib/crypto/encrypt_data.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "k5-int.h" - -/* - * This routine takes a key and a krb5_data structure as input, and - * outputs the encrypted data in a krb5_enc_data structure. Note that - * the krb5_enc_data structure is not allocated, and the kvno field is - * not filled in. - */ -krb5_error_code -krb5_encrypt_data(context, key, ivec, data, enc_data) - krb5_context context; - krb5_keyblock * key; - krb5_pointer ivec; - krb5_data * data; - krb5_enc_data * enc_data; -{ - krb5_error_code retval; - krb5_encrypt_block eblock; - - krb5_use_enctype(context, &eblock, key->enctype); - - enc_data->magic = KV5M_ENC_DATA; - enc_data->kvno = 0; - enc_data->enctype = key->enctype; - enc_data->ciphertext.length = krb5_encrypt_size(data->length, - eblock.crypto_entry); - enc_data->ciphertext.data = malloc(enc_data->ciphertext.length); - if (enc_data->ciphertext.data == 0) - return ENOMEM; - - if ((retval = krb5_process_key(context, &eblock, key)) != 0) - goto cleanup; - - if ((retval = krb5_encrypt(context, (krb5_pointer) data->data, - (krb5_pointer) enc_data->ciphertext.data, - data->length, &eblock, ivec))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - (void) krb5_finish_key(context, &eblock); - - return 0; - -cleanup: - free(enc_data->ciphertext.data); - return retval; -} - diff --git a/src/lib/crypto/encrypt_length.c b/src/lib/crypto/encrypt_length.c new file mode 100644 index 000000000..005b2211d --- /dev/null +++ b/src/lib/crypto/encrypt_length.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_encrypt_length(context, enctype, inputlen, length) + krb5_context context; + krb5_enctype enctype; + size_t inputlen; + size_t *length; +{ + int i; + + for (i=0; i buflen) + return(ENOMEM); + + strcpy(buffer, krb5_enctypes_list[i].out_string); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c new file mode 100644 index 000000000..cebb5bda5 --- /dev/null +++ b/src/lib/crypto/etypes.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "enc_provider.h" +#include "hash_provider.h" +#include "etypes.h" +#include "old.h" +#include "raw.h" +#include "dk.h" + +/* these will be linear searched. if they ever get big, a binary + search or hash table would be better, which means these would need + to be sorted. An array would be more efficient, but that assumes + that the keytypes are all near each other. I'd rather not make + that assumption. */ + +struct krb5_keytypes krb5_enctypes_list[] = { + { ENCTYPE_DES_CBC_CRC, + "des-cbc-crc", "DES cbc mode with CRC-32", + &krb5_enc_des, &krb5_hash_crc32, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", "DES cbc mode with RSA-MD4", + &krb5_enc_des, &krb5_hash_md4, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", "DES cbc mode with RSA-MD5", + &krb5_enc_des, &krb5_hash_md5, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", "DES cbc mode raw", + &krb5_enc_des, NULL, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", "Triple DES cbc mode raw", + &krb5_enc_des3, NULL, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5_dk_string_to_key }, + + { ENCTYPE_DES3_HMAC_SHA1, + "des3-hmac-sha1", "Triple DES with HMAC/sha1", + &krb5_enc_des3, &krb5_hash_sha1, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5_dk_string_to_key }, + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", "DES with HMAC/sha1", + &krb5_enc_des, &krb5_hash_sha1, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5_dk_string_to_key }, +}; + +int krb5_enctypes_length = +sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes); diff --git a/src/lib/crypto/etypes.h b/src/lib/crypto/etypes.h new file mode 100644 index 000000000..53d8b655a --- /dev/null +++ b/src/lib/crypto/etypes.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" + +extern struct krb5_keytypes krb5_enctypes_list[]; +extern int krb5_enctypes_length; diff --git a/src/lib/crypto/hmac.c b/src/lib/crypto/hmac.c new file mode 100644 index 000000000..7cf11a6c7 --- /dev/null +++ b/src/lib/crypto/hmac.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" + +/* + * the HMAC transform looks like: + * + * H(K XOR opad, H(K XOR ipad, text)) + * + * where H is a cryptographic hash + * K is an n byte key + * ipad is the byte 0x36 repeated blocksize times + * opad is the byte 0x5c repeated blocksize times + * and text is the data being protected + */ + +krb5_error_code +krb5_hmac(hash, key, icount, input, output) + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + unsigned int icount; + krb5_const krb5_data *input; + krb5_data *output; +{ + size_t hashsize, blocksize; + unsigned char *xorkey, *ihash; + int i; + krb5_data *hashin, hashout; + krb5_error_code ret; + + (*(hash->hash_size))(&hashsize); + (*(hash->block_size))(&blocksize); + + if (key->length > blocksize) + return(KRB5_CRYPTO_INTERNAL); + if (output->length < hashsize) + return(KRB5_BAD_MSIZE); + /* if this isn't > 0, then there won't be enough space in this + array to compute the outer hash */ + if (icount == 0) + return(KRB5_CRYPTO_INTERNAL); + + /* allocate space for the xor key, hash input vector, and inner hash */ + + if ((xorkey = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + if ((ihash = (unsigned char *) malloc(hashsize)) == NULL) { + free(xorkey); + return(ENOMEM); + } + if ((hashin = (krb5_data *)malloc(sizeof(krb5_data)*(icount+1))) == NULL) { + free(ihash); + free(xorkey); + return(ENOMEM); + } + + /* create the inner padded key */ + + memset(xorkey, 0x36, blocksize); + + for (i=0; ilength; i++) + xorkey[i] ^= key->contents[i]; + + /* compute the inner hash */ + + for (i=0; ihash))(icount+1, hashin, &hashout))) + goto cleanup; + + /* create the outer padded key */ + + memset(xorkey, 0x5c, blocksize); + + for (i=0; ilength; i++) + xorkey[i] ^= key->contents[i]; + + /* compute the outer hash */ + + hashin[0].length = blocksize; + hashin[0].data = xorkey; + hashin[1] = hashout; + + output->length = hashsize; + + if (ret = ((*(hash->hash))(2, hashin, output))) + memset(output->data, 0, output->length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(xorkey, 0, blocksize); + memset(ihash, 0, hashsize); + + free(hashin); + free(ihash); + free(xorkey); + + return(ret); +} diff --git a/src/lib/crypto/keyed_checksum_types.c b/src/lib/crypto/keyed_checksum_types.c new file mode 100644 index 000000000..cf0b736f2 --- /dev/null +++ b/src/lib/crypto/keyed_checksum_types.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" +#include "cksumtypes.h" + +static int etype_match(e1, e2) + krb5_enctype e1, e2; +{ + int i1, i2; + + for (i1=0; i1pad_minimum, crypto->block_length); -} - -krb5_boolean KRB5_CALLCONV -valid_enctype(ktype) - krb5_const krb5_enctype ktype; -{ - return ((ktype<=krb5_max_enctype) && (ktype>0) && krb5_enctype_array[ktype]); -} - -krb5_boolean KRB5_CALLCONV -valid_cksumtype(cktype) - krb5_const krb5_cksumtype cktype; -{ - return ((cktype<=krb5_max_cksum) && (cktype>0) && krb5_cksumarray[cktype]); -} - -krb5_boolean KRB5_CALLCONV -is_coll_proof_cksum(cktype) - krb5_const krb5_cksumtype cktype; -{ - return(krb5_cksumarray[cktype]->is_collision_proof); -} - -krb5_boolean KRB5_CALLCONV -is_keyed_cksum(cktype) - krb5_const krb5_cksumtype cktype; -{ - return (krb5_cksumarray[cktype]->uses_key); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_use_enctype(context, eblock, enctype) - krb5_context context; - krb5_encrypt_block FAR * eblock; - krb5_const krb5_enctype enctype; -{ - eblock->crypto_entry = krb5_enctype_array[(enctype)]->system; - return 0; -} - -KRB5_DLLIMP size_t KRB5_CALLCONV -krb5_checksum_size(context, cktype) - krb5_context context; - krb5_const krb5_cksumtype cktype; -{ - return krb5_cksumarray[cktype]->checksum_length; -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_calculate_checksum(context, cktype, in, in_length, seed, seed_length, outcksum) - krb5_context context; - krb5_const krb5_cksumtype cktype; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - return krb5_x(((*krb5_cksumarray[cktype]->sum_func)), - (in, in_length, seed, seed_length, outcksum)); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_verify_checksum(context, cktype, cksum, in, in_length, seed, seed_length) - krb5_context context; - krb5_const krb5_cksumtype cktype; - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - return krb5_x((*krb5_cksumarray[cktype]->sum_verf_func), - (cksum, in, in_length, seed, seed_length)); -} - -KRB5_DLLIMP krb5_enctype KRB5_CALLCONV -krb5_eblock_enctype(context, eblock) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; -{ - return eblock->crypto_entry->proto_enctype; -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_encrypt(context, inptr, outptr, size, eblock, ivec) - krb5_context context; - krb5_const krb5_pointer inptr; - krb5_pointer outptr; - krb5_const size_t size; - krb5_encrypt_block FAR * eblock; - krb5_pointer ivec; -{ - return krb5_x(eblock->crypto_entry->encrypt_func, - (inptr, outptr, size, eblock, ivec)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_decrypt(context, inptr, outptr, size, eblock, ivec) - krb5_context context; - krb5_const krb5_pointer inptr; - krb5_pointer outptr; - krb5_const size_t size; - krb5_encrypt_block FAR * eblock; - krb5_pointer ivec; -{ - return krb5_x(eblock->crypto_entry->decrypt_func, - (inptr, outptr, size, eblock, ivec)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_process_key(context, eblock, key) - krb5_context context; - krb5_encrypt_block FAR * eblock; - krb5_const krb5_keyblock FAR * key; -{ - return krb5_x(eblock->crypto_entry->process_key, - (eblock, key)); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_finish_key(context, eblock) - krb5_context context; - krb5_encrypt_block FAR * eblock; -{ - return krb5_x(eblock->crypto_entry->finish_key,(eblock)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_string_to_key(context, eblock, keyblock, data, princ) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_keyblock FAR * keyblock; - krb5_const krb5_data FAR * data; - krb5_const krb5_data FAR * princ; -{ - return krb5_x(eblock->crypto_entry->string_to_key, - (eblock, keyblock, data, princ)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_init_random_key(context, eblock, keyblock, ptr) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_const krb5_keyblock FAR * keyblock; - krb5_pointer FAR * ptr; -{ - return krb5_x(eblock->crypto_entry->init_random_key, - (eblock, keyblock, ptr)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_finish_random_key(context, eblock, ptr) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_pointer FAR * ptr; -{ - return krb5_x(eblock->crypto_entry->finish_random_key, - (eblock, ptr)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_random_key(context, eblock, ptr, keyblock) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_pointer ptr; - krb5_keyblock FAR * FAR * keyblock; -{ - return krb5_x(eblock->crypto_entry->random_key, - (eblock, ptr, keyblock)); -} - - diff --git a/src/lib/crypto/make_checksum.c b/src/lib/crypto/make_checksum.c new file mode 100644 index 000000000..b2faef191 --- /dev/null +++ b/src/lib/crypto/make_checksum.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "cksumtypes.h" +#include "etypes.h" + +krb5_error_code +krb5_c_make_checksum(context, cksumtype, key, usage, input, cksum) + krb5_context context; + krb5_cksumtype cksumtype; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *input; + krb5_checksum *cksum; +{ + int i, e1, e2; + krb5_data data; + krb5_error_code ret; + size_t cksumlen; + + for (i=0; ihash_size))(&cksumlen); + else + (*(krb5_cksumtypes_list[i].hash->hash_size))(&cksumlen); + + cksum->length = cksumlen; + + if ((cksum->contents = (krb5_octet *) malloc(cksum->length)) == NULL) + return(ENOMEM); + + data.length = cksum->length; + data.data = cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash) { + /* check if key is compatible */ + + if (krb5_cksumtypes_list[i].keyed_etype) { + for (e1=0; e1enctype) + break; + + if ((e1 == krb5_enctypes_length) || + (e2 == krb5_enctypes_length) || + (krb5_enctypes_list[e1].enc != krb5_enctypes_list[e2].enc)) { + ret = KRB5_BAD_ENCTYPE; + goto cleanup; + } + } + + ret = (*(krb5_cksumtypes_list[i].keyhash->hash))(key, 0, input, &data); + } else if (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE) { + /* any key is ok */ + + ret = krb5_dk_make_checksum(krb5_cksumtypes_list[i].hash, + key, usage, input, &data); + } else { + /* no key is used */ + + ret = (*(krb5_cksumtypes_list[i].hash->hash))(1, input, &data); + } + + if (!ret) { + cksum->magic = KV5M_CHECKSUM; + cksum->checksum_type = cksumtype; + } + +cleanup: + if (ret) { + memset(cksum->contents, 0, cksum->length); + free(cksum->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/make_random_key.c b/src/lib/crypto/make_random_key.c new file mode 100644 index 000000000..391f56dfc --- /dev/null +++ b/src/lib/crypto/make_random_key.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_make_random_key(context, enctype, random_key) + krb5_context context; + krb5_enctype enctype; + krb5_keyblock *random_key; +{ + int i; + krb5_error_code ret; + struct krb5_enc_provider *enc; + size_t keybytes, keylength; + krb5_data random; + unsigned char *bytes; + + for (i=0; ikeysize))(&keybytes, &keylength); + + if ((bytes = (unsigned char *) malloc(keybytes)) == NULL) + return(ENOMEM); + if ((random_key->contents = (krb5_octet *) malloc(keylength)) == NULL) { + free(bytes); + return(ENOMEM); + } + + random.data = bytes; + random.length = keybytes; + + if (ret = krb5_c_random_make_octets(context, &random)) + goto cleanup; + + random_key->magic = KV5M_KEYBLOCK; + random_key->enctype = enctype; + random_key->length = keylength; + + ret = ((*(enc->make_key))(&random, random_key)); + +cleanup: + memset(bytes, 0, keybytes); + free(bytes); + + if (ret) { + memset(random_key->contents, 0, keylength); + free(random_key->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/md4/.rconf b/src/lib/crypto/md4/.rconf deleted file mode 100644 index de30fd8c9..000000000 --- a/src/lib/crypto/md4/.rconf +++ /dev/null @@ -1,2 +0,0 @@ -ignore RFC1186.TXT -ignore RFC1186B.TXT diff --git a/src/lib/crypto/md4/ChangeLog b/src/lib/crypto/md4/ChangeLog index 3ca8c0872..7714d4a43 100644 --- a/src/lib/crypto/md4/ChangeLog +++ b/src/lib/crypto/md4/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz + + * *.c: replace the crypto layer. + Tue Mar 3 08:39:47 1998 Ezra Peisach * Makefile.in (t_cksum): Do not depend on libkrb5.a, use diff --git a/src/lib/crypto/md4/Makefile.in b/src/lib/crypto/md4/Makefile.in index 739b34b84..be6baebb0 100644 --- a/src/lib/crypto/md4/Makefile.in +++ b/src/lib/crypto/md4/Makefile.in @@ -1,7 +1,6 @@ thisconfigdir=./.. BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -# -I$(srcdir) is needed to pull in $(srcdir)/rsa-md4.h for ./t_mddriver.c. -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des -I"$(srcdir)" +CFLAGS = $(CCOPTS) $(DEFS) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=md4 @@ -11,16 +10,22 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des -I"$(srcdir)" PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) -RUN_SETUP=@KRB5_RUN_ENV@ +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS=md4.o md4glue.o md4crypto.o -OBJS= md4.$(OBJEXT) md4glue.$(OBJEXT) md4crypto.$(OBJEXT) -SRCS= $(srcdir)/md4.c $(srcdir)/md4glue.c $(srcdir)/md4crypto.c +STLIBOBJS= md4.o + +OBJS= md4.$(OBJEXT) + +SRCS= $(srcdir)/md4.c ##DOS##LIBOBJS = $(OBJS) all-unix:: all-libobjs +includes:: depend + +depend:: $(SRCS) + t_mddriver.c: $(srcdir)/../md5/t_mddriver.c $(CP) $(srcdir)/../md5/t_mddriver.c t_mddriver.c @@ -35,24 +40,13 @@ t_mddriver.exe: $(CC) -DMD=4 $(CFLAGS2) -o t_mddriver t_mddriver.c md4.c $(RM) md4.obj -t_cksum.c: $(srcdir)/../md5/t_cksum.c - $(CP) $(srcdir)/../md5/t_cksum.c t_cksum.c - -t_cksum.o: t_cksum.c - $(CC) -DMD=4 $(CFLAGS) -c t_cksum.c - -t_cksum: t_cksum.o $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o t_cksum t_cksum.o $(KRB5_BASE_LIBS) - -check-unix:: t_mddriver t_cksum +check-unix:: t_mddriver $(RUN_SETUP) $(C)t_mddriver -x - $(RUN_SETUP) $(C)t_cksum "this is a test" check-windows:: t_mddriver$(EXEEXT) $(C)t_mddriver$(EXEEXT) -x clean:: $(RM) t_mddriver$(EXEEXT) t_mddriver.$(OBJEXT) t_mddriver.c - $(RM) t_cksum$(EXEEXT) t_cksum.$(OBJEXT) t_cksum.c clean-unix:: clean-libobjs diff --git a/src/lib/crypto/md4/md4crypto.c b/src/lib/crypto/md4/md4crypto.c deleted file mode 100644 index eac9647f2..000000000 --- a/src/lib/crypto/md4/md4crypto.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * lib/crypto/md4/md4crypto.c - * - * Copyright 1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Kerberos glue for MD4 sample implementation. - */ - -#include "k5-int.h" -#include "rsa-md4.h" -#include "des_int.h" /* we cheat a bit and call it directly... */ - -/* - * In Kerberos V5 Beta 5 and previous releases the RSA-MD4-DES implementation - * did not follow RFC1510. The folowing definitions control the compatibility - * with these releases. - * - * If MD4_K5BETA_COMPAT is defined, then compatability mode is enabled. That - * means that both checksum functions are compiled and available for use and - * the additional interface md4_crypto_compat_ctl() is defined. - * - * If MD4_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then - * the compatible behaviour becomes the default. - * - */ -#define MD4_K5BETA_COMPAT -#define MD4_K5BETA_COMPAT_DEF - - -/* Windows needs to these prototypes for the assignment below */ - -#ifdef MD4_K5BETA_COMPAT -krb5_error_code -krb5_md4_crypto_compat_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum *outcksum)); -#endif - -krb5_error_code -krb5_md4_crypto_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum *outcksum)); - -krb5_error_code -krb5_md4_crypto_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static mit_des_cblock zero_ivec = { 0 }; - -static void -krb5_md4_calculate_cksum(md4ctx, confound, confound_length, in, in_length) - krb5_MD4_CTX *md4ctx; - krb5_pointer confound; - size_t confound_length; - krb5_pointer in; - size_t in_length; -{ - krb5_MD4Init(md4ctx); - if (confound && confound_length) - krb5_MD4Update(md4ctx, confound, confound_length); - krb5_MD4Update(md4ctx, in, in_length); - krb5_MD4Final(md4ctx); -} - -#ifdef MD4_K5BETA_COMPAT -/* - * Generate the RSA-MD4-DES checksum in a manner which is compatible with - * K5 Beta implementations. Sigh... - */ -krb5_error_code -krb5_md4_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[OLD_RSA_MD4_DES_CKSUM_LENGTH]; - krb5_octet *input = (krb5_octet *)in; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - krb5_MD4_CTX working; - - if (outcksum->length < OLD_RSA_MD4_DES_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES; - outcksum->length = OLD_RSA_MD4_DES_CKSUM_LENGTH; - - memcpy((char *)outtmp, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *)seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - OLD_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} -#endif /* MD4_K5BETA_COMPAT */ - -/* - * Generate the RSA-MD4-DES checksum correctly. - */ -krb5_error_code -krb5_md4_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD4_CTX working; - - /* Generate the confounder in place */ - if ((retval = krb5_random_confounder(RSA_MD4_DES_CONFOUND_LENGTH, outtmp))) - return(retval); - - /* Calculate the checksum */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD4_DES_CONFOUND_LENGTH, - in, - in_length); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES; - outcksum->length = NEW_RSA_MD4_DES_CKSUM_LENGTH; - - /* Now blast in the digest */ - memcpy((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH); - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - - /* Set up the temporary copy of the key (see RFC 1510 section 6.4.3) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (icontents, - NEW_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - zero_ivec, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} - -krb5_error_code -krb5_md4_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD4_CTX working; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD4_DES) { -#ifdef MD4_K5BETA_COMPAT - /* - * We have a backwards compatibility problem here. Kerberos - * version 5 Beta 5 and previous releases did not correctly - * generate RSA-MD4-DES checksums. The way that we can - * differentiate is by the length of the provided checksum. - * If it's only OLD_RSA_MD4_DES_CKSUM_LENGTH, then it's the - * old style, otherwise it's the correct implementation. - */ - if (cksum->length == OLD_RSA_MD4_DES_CKSUM_LENGTH) { - /* - * If we're verifying the Old Style (tm) checksum, then we can just - * recalculate the checksum and encrypt it and see if it's the - * same. - */ - - /* Recalculate the checksum with no confounder */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) NULL, - (size_t) 0, - in, - in_length); - - /* Use the key "as-is" */ - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *) seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt the checksum */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0], - (mit_des_cblock *)&outtmp[0], - RSA_MD4_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Compare the encrypted checksums */ - if (memcmp((char *) &outtmp[0], - (char *) cksum->contents, - OLD_RSA_MD4_DES_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else -#endif /* MD4_K5BETA_COMPAT */ - if (cksum->length == (NEW_RSA_MD4_DES_CKSUM_LENGTH)) { - /* - * If we're verifying the correct implementation, then we have - * to do a little more work because we must decrypt the checksum - * because it contains the confounder in it. So, figure out - * what our key variant is and then do it! - */ - - /* Set up the variant of the key (see RFC 1510 section 6.4.3) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (icontents, - (mit_des_cblock *)&outtmp[0], - NEW_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - zero_ivec, - MIT_DES_DECRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Now that we have the decrypted checksum, try to regenerate it */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD4_DES_CONFOUND_LENGTH, - in, - in_length); - - /* Compare the checksums */ - if (memcmp((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - return(retval); -} - -krb5_checksum_entry rsa_md4_des_cksumtable_entry = -#if defined(MD4_K5BETA_COMPAT) && defined(MD4_K5BETA_COMPAT_DEF) -{ - 0, - krb5_md4_crypto_compat_sum_func, - krb5_md4_crypto_verify_func, - OLD_RSA_MD4_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#else /* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */ -{ - 0, - krb5_md4_crypto_sum_func, - krb5_md4_crypto_verify_func, - NEW_RSA_MD4_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#endif /* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */ - -#ifdef MD4_K5BETA_COMPAT -/* - * Turn on/off compatible checksum generation. - */ -void -krb5_md4_crypto_compat_ctl(scompat) - krb5_boolean scompat; -{ - if (scompat) { - rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_compat_sum_func; - rsa_md4_des_cksumtable_entry.checksum_length = - OLD_RSA_MD4_DES_CKSUM_LENGTH; - } - else { - rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_sum_func; - rsa_md4_des_cksumtable_entry.checksum_length = - NEW_RSA_MD4_DES_CKSUM_LENGTH; - } -} -#endif /* MD4_K5BETA_COMPAT */ diff --git a/src/lib/crypto/md4/md4driver.c b/src/lib/crypto/md4/md4driver.c deleted file mode 100644 index 425ef2954..000000000 --- a/src/lib/crypto/md4/md4driver.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * lib/crypto/md4/md4driver.c - */ - -/* - ********************************************************************** - ** md4driver.c -- sample routines to test ** - ** RSA Data Security, Inc. MD4 message digest algorithm. ** - ** Created: 2/16/90 RLR ** - ** Updated: 1/91 SRD ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -#include "k5-int.h" -#include "rsa-md4.h" - -/* Prints message digest buffer in mdContext as 32 hexadecimal digits. - Order is from low-order byte to high-order byte of digest. - Each byte is printed with high-order hexadecimal digit first. - */ -static void MDPrint (mdContext) -krb5_MD4_CTX *mdContext; -{ - int i; - - for (i = 0; i < 16; i++) - printf ("%02x", mdContext->digest[i]); -} - -/* size of test block */ -#define TEST_BLOCK_SIZE 1000 - -/* number of blocks to process */ -#define TEST_BLOCKS 2000 - -/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */ -static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS; - -/* A time trial routine, to measure the speed of MD4. - Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE - characters. - */ -static void MDTimeTrial () -{ - krb5_MD4_CTX mdContext; - time_t endTime, startTime; - unsigned char data[TEST_BLOCK_SIZE]; - unsigned int i; - - /* initialize test data */ - for (i = 0; i < TEST_BLOCK_SIZE; i++) - data[i] = (unsigned char)(i & 0xFF); - - /* start timer */ - printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES); - time (&startTime); - - /* digest data in TEST_BLOCK_SIZE byte blocks */ - krb5_MD4Init (&mdContext); - for (i = TEST_BLOCKS; i > 0; i--) - krb5_MD4Update (&mdContext, data, TEST_BLOCK_SIZE); - krb5_MD4Final (&mdContext); - /* stop timer, get time difference */ - time (&endTime); - MDPrint (&mdContext); - printf (" is digest of test input.\n"); - printf - ("Seconds to process test input: %ld\n", (long)(endTime-startTime)); - printf - ("Characters processed per second: %ld\n", - TEST_BYTES/(endTime-startTime)); -} - -/* Computes the message digest for string inString. - Prints out message digest, a space, the string (in quotes) and a - carriage return. - */ -static void MDString (inString) -char *inString; -{ - krb5_MD4_CTX mdContext; - unsigned int len = strlen (inString); - - krb5_MD4Init (&mdContext); - krb5_MD4Update (&mdContext, inString, len); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf (" \"%s\"\n\n", inString); -} - -/* Computes the message digest for a specified file. - Prints out message digest, a space, the file name, and a carriage - return. - */ -static void MDFile (filename) -char *filename; -{ -#ifdef __STDC__ - FILE *inFile = fopen (filename, "rb"); -#else - FILE *inFile = fopen (filename, "r"); -#endif - krb5_MD4_CTX mdContext; - int bytes; - unsigned char data[1024]; - - if (inFile == NULL) { - printf ("%s can't be opened.\n", filename); - return; - } - - krb5_MD4Init (&mdContext); - while ((bytes = fread (data, 1, 1024, inFile)) != 0) - krb5_MD4Update (&mdContext, data, bytes); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf (" %s\n", filename); - fclose (inFile); -} - - -/* Writes the message digest of the data from stdin onto stdout, - followed by a carriage return. - */ -static void MDFilter () -{ - krb5_MD4_CTX mdContext; - int bytes; - unsigned char data[16]; - - krb5_MD4Init (&mdContext); - while ((bytes = fread (data, 1, 16, stdin)) != 0) - krb5_MD4Update (&mdContext, data, bytes); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf ("\n"); -} - -/* Runs a standard suite of test data. - */ -static void MDTestSuite () -{ - printf ("MD4 test suite results:\n\n"); - MDString (""); - MDString ("a"); - MDString ("abc"); - MDString ("message digest"); - MDString ("abcdefghijklmnopqrstuvwxyz"); - MDString - ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); - MDString - ("1234567890123456789012345678901234567890\ -1234567890123456789012345678901234567890"); - /* Contents of file foo are "abc" */ - MDFile ("foo"); -} - -void main (argc, argv) -int argc; -char *argv[]; -{ - int i; - - /* For each command line argument in turn: - ** filename -- prints message digest and name of file - ** -sstring -- prints message digest and contents of string - ** -t -- prints time trial statistics for 1M characters - ** -x -- execute a standard suite of test data - ** (no args) -- writes messages digest of stdin onto stdout - */ - if (argc == 1) - MDFilter (); - else - for (i = 1; i < argc; i++) - if (argv[i][0] == '-' && argv[i][1] == 's') - MDString (argv[i] + 2); - else if (strcmp (argv[i], "-t") == 0) - MDTimeTrial (); - else if (strcmp (argv[i], "-x") == 0) - MDTestSuite (); - else MDFile (argv[i]); -} - -/* - ********************************************************************** - ** End of md4driver.c ** - ******************************* (cut) ******************************** - */ diff --git a/src/lib/crypto/md4/md4glue.c b/src/lib/crypto/md4/md4glue.c deleted file mode 100644 index f7e566e9b..000000000 --- a/src/lib/crypto/md4/md4glue.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * lib/crypto/md4/md4glue.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * Kerberos glue for MD4 sample implementation. - */ - -#include "k5-int.h" -#include "rsa-md4.h" - -/* Windows needs to these prototypes for the assignment below */ - -krb5_error_code -krb5_md4_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md4_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_md4_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD4_CTX working; - - if (outcksum->length < RSA_MD4_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4; - outcksum->length = RSA_MD4_CKSUM_LENGTH; - - memcpy((char *)outcksum->contents, (char *)&working.digest[0], - RSA_MD4_CKSUM_LENGTH); - - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_md4_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD4_CTX working; - krb5_error_code retval; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD4) { - if (cksum->length == RSA_MD4_CKSUM_LENGTH) { - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - if (memcmp((char *) cksum->contents, - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - memset((char *)&working, 0, sizeof(working)); - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - return retval; -} - -krb5_checksum_entry rsa_md4_cksumtable_entry = { - 0, - krb5_md4_sum_func, - krb5_md4_verify_func, - RSA_MD4_CKSUM_LENGTH, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/md5/ChangeLog b/src/lib/crypto/md5/ChangeLog index 1c0026add..79fb94a7d 100644 --- a/src/lib/crypto/md5/ChangeLog +++ b/src/lib/crypto/md5/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz + + * *.c: replace the crypto layer. + Tue Mar 3 08:42:10 1998 Ezra Peisach * Makefile.in (t_cksum): Do not depend on libkrb5.a, use diff --git a/src/lib/crypto/md5/Makefile.in b/src/lib/crypto/md5/Makefile.in index 3707f897b..219fa3081 100644 --- a/src/lib/crypto/md5/Makefile.in +++ b/src/lib/crypto/md5/Makefile.in @@ -1,6 +1,6 @@ thisconfigdir=./.. BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des +CFLAGS = $(CCOPTS) $(DEFS) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=md5 @@ -10,35 +10,35 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) -RUN_SETUP = @KRB5_RUN_ENV@ +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS=md5.o md5glue.o md5crypto.o +STLIBOBJS= md5.o -OBJS= md5.$(OBJEXT) md5glue.$(OBJEXT) md5crypto.$(OBJEXT) -SRCS= $(srcdir)/md5.c $(srcdir)/md5glue.c $(srcdir)/md5crypto.c +OBJS= md5.$(OBJEXT) + +SRCS= $(srcdir)/md5.c ##DOS##LIBOBJS = $(OBJS) all-unix:: all-libobjs +includes:: depend + +depend:: $(SRCS) + t_mddriver: t_mddriver.o md5.o $(CC) $(CFLAGS) $(LDFLAGS) -o t_mddriver t_mddriver.o md5.o t_mddriver.exe: $(CC) $(CFLAGS2) -o t_mddriver.exe t_mddriver.c md5.c -t_cksum: t_cksum.o $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o t_cksum t_cksum.o $(KRB5_BASE_LIBS) - -check-unix:: t_mddriver t_cksum +check-unix:: t_mddriver $(RUN_SETUP) $(C)t_mddriver -x - $(RUN_SETUP) $(C)t_cksum "this is a test" check-windows:: t_mddriver$(EXEEXT) $(C)t_mddriver$(EXEEXT) -x clean:: $(RM) t_mddriver$(EXEEXT) t_mddriver.$(OBJEXT) - $(RM) t_cksum$(EXEEXT) t_cksum.$(OBJEXT) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/md5/md5crypto.c b/src/lib/crypto/md5/md5crypto.c deleted file mode 100644 index b83e50e77..000000000 --- a/src/lib/crypto/md5/md5crypto.c +++ /dev/null @@ -1,353 +0,0 @@ -#include "k5-int.h" -#include "rsa-md5.h" -#include "des_int.h" /* we cheat a bit and call it directly... */ - -/* - * In Kerberos V5 Beta 5 and previous releases the RSA-MD5-DES implementation - * did not follow RFC1510. The folowing definitions control the compatibility - * with these releases. - * - * If MD5_K5BETA_COMPAT is defined, then compatability mode is enabled. That - * means that both checksum functions are compiled and available for use and - * the additional interface krb5_md5_crypto_compat_ctl() is defined. - * - * If MD5_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then - * the compatible behaviour becomes the default. - * - */ -#define MD5_K5BETA_COMPAT -#define MD5_K5BETA_COMPAT_DEF - - -/* Windows needs to these prototypes for the assignment below */ - -#ifdef MD5_K5BETA_COMPAT -krb5_error_code -krb5_md5_crypto_compat_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); -#endif - -krb5_error_code -krb5_md5_crypto_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md5_crypto_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static mit_des_cblock zero_ivec = { 0 }; - -static void -krb5_md5_calculate_cksum(md5ctx, confound, confound_length, in, in_length) - krb5_MD5_CTX *md5ctx; - krb5_pointer in; - size_t in_length; - krb5_pointer confound; - size_t confound_length; -{ - krb5_MD5Init(md5ctx); - if (confound && confound_length) - krb5_MD5Update(md5ctx, confound, confound_length); - krb5_MD5Update(md5ctx, in, in_length); - krb5_MD5Final(md5ctx); -} - -#ifdef MD5_K5BETA_COMPAT -krb5_error_code -krb5_md5_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[OLD_RSA_MD5_DES_CKSUM_LENGTH]; - krb5_octet *input = (krb5_octet *)in; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - - krb5_MD5_CTX working; - - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES; - outcksum->length = OLD_RSA_MD5_DES_CKSUM_LENGTH; - - memcpy((char *)outtmp, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *)seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - OLD_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} -#endif /* MD5_K5BETA_COMPAT */ - -krb5_error_code -krb5_md5_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - krb5_MD5_CTX working; - - if (outcksum->length < NEW_RSA_MD5_DES_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - /* Generate the confounder in place */ - if ((retval = krb5_random_confounder(RSA_MD5_DES_CONFOUND_LENGTH, outtmp))) - return(retval); - - /* Calculate the checksum */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD5_DES_CONFOUND_LENGTH, - in, - in_length); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES; - outcksum->length = NEW_RSA_MD5_DES_CKSUM_LENGTH; - - /* Now blast in the digest */ - memcpy((char *)&outtmp[RSA_MD5_DES_CONFOUND_LENGTH], - (char *)&working.digest[0], - RSA_MD5_CKSUM_LENGTH); - - /* Clean up the droppings */ - memset((char *)&working, 0, sizeof(working)); - - /* Set up the temporary copy of the key (see RFC 1510 section 6.4.5) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (icontents, - NEW_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - zero_ivec, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} - -krb5_error_code -krb5_md5_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD5_CTX working; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD5_DES) { -#ifdef MD5_K5BETA_COMPAT - /* - * We have a backwards compatibility problem here. Kerberos - * version 5 Beta 5 and previous releases did not correctly - * generate RSA-MD5-DES checksums. The way that we can - * differentiate is by the length of the provided checksum. - * If it's only OLD_RSA_MD5_DES_CKSUM_LENGTH, then it's the - * old style, otherwise it's the correct implementation. - */ - if (cksum->length == OLD_RSA_MD5_DES_CKSUM_LENGTH) { - /* - * If we're verifying the Old Style (tm) checksum, then we can just - * recalculate the checksum and encrypt it and see if it's the - * same. - */ - - /* Recalculate the checksum with no confounder */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) NULL, - (size_t) 0, - in, - in_length); - - /* Use the key "as-is" */ - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *) seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt the checksum */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0], - (mit_des_cblock *)&outtmp[0], - OLD_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Compare the encrypted checksums */ - if (memcmp((char *) &outtmp[0], - (char *) cksum->contents, - OLD_RSA_MD5_DES_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else -#endif /* MD5_K5BETA_COMPAT */ - if (cksum->length == (NEW_RSA_MD5_DES_CKSUM_LENGTH)) { - /* - * If we're verifying the correct implementation, then we have - * to do a little more work because we must decrypt the checksum - * because it contains the confounder in it. So, figure out - * what our key variant is and then do it! - */ - - /* Set up the variant of the key (see RFC 1510 section 6.4.5) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (icontents, - (mit_des_cblock *)&outtmp[0], - NEW_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - zero_ivec, - MIT_DES_DECRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Now that we have the decrypted checksum, try to regenerate it */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD5_DES_CONFOUND_LENGTH, - in, - in_length); - - /* Compare the checksums */ - if (memcmp((char *) &outtmp[RSA_MD5_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD5_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - return(retval); -} - -krb5_checksum_entry rsa_md5_des_cksumtable_entry = -#if defined(MD5_K5BETA_COMPAT) && defined(MD5_K5BETA_COMPAT_DEF) -{ - 0, - krb5_md5_crypto_compat_sum_func, - krb5_md5_crypto_verify_func, - OLD_RSA_MD5_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#else /* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */ -{ - 0, - krb5_md5_crypto_sum_func, - krb5_md5_crypto_verify_func, - NEW_RSA_MD5_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#endif /* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */ - -#ifdef MD5_K5BETA_COMPAT -/* - * Turn on/off compatible checksum generation. - */ -void -krb5_md5_crypto_compat_ctl(scompat) - krb5_boolean scompat; -{ - if (scompat) { - rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_compat_sum_func; - rsa_md5_des_cksumtable_entry.checksum_length = - OLD_RSA_MD5_DES_CKSUM_LENGTH; - } - else { - rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_sum_func; - rsa_md5_des_cksumtable_entry.checksum_length = - NEW_RSA_MD5_DES_CKSUM_LENGTH; - } -} -#endif /* MD5_K5BETA_COMPAT */ - diff --git a/src/lib/crypto/md5/md5glue.c b/src/lib/crypto/md5/md5glue.c deleted file mode 100644 index 66d5aa791..000000000 --- a/src/lib/crypto/md5/md5glue.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "k5-int.h" -#include "rsa-md5.h" - -/* Windows needs to these prototypes for the assignment below */ - -krb5_error_code -krb5_md5_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md5_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_md5_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD5_CTX working; - - if (outcksum->length < RSA_MD5_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5; - outcksum->length = RSA_MD5_CKSUM_LENGTH; - - memcpy((char *)outcksum->contents, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_md5_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD5_CTX working; - krb5_error_code retval; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD5) { - if (cksum->length == RSA_MD5_CKSUM_LENGTH) { - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - if (memcmp((char *) cksum->contents, - (char *) &working.digest[0], - RSA_MD5_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - memset((char *)&working, 0, sizeof(working)); - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - return retval; -} - -krb5_checksum_entry rsa_md5_cksumtable_entry = { - 0, - krb5_md5_sum_func, - krb5_md5_verify_func, - RSA_MD5_CKSUM_LENGTH, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/md5/t_cksum.c b/src/lib/crypto/md5/t_cksum.c deleted file mode 100644 index 5bc63709d..000000000 --- a/src/lib/crypto/md5/t_cksum.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * lib/crypto/md5/t_cksum.c - * - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. - * - */ - -/* - * t_cksum.c - Test checksum and checksum compatability for rsa-md[4,5]-des - */ - -#ifndef MD -#define MD 5 -#endif /* MD */ - -#include "k5-int.h" -#if MD == 4 -#include "rsa-md4.h" -#endif /* MD == 4 */ -#if MD == 5 -#include "rsa-md5.h" -#endif /* MD == 5 */ -#include "des_int.h" - -#define MD5_K5BETA_COMPAT -#define MD4_K5BETA_COMPAT - -#if MD == 4 -#define CONFOUNDER_LENGTH RSA_MD4_DES_CONFOUND_LENGTH -#define NEW_CHECKSUM_LENGTH NEW_RSA_MD4_DES_CKSUM_LENGTH -#define OLD_CHECKSUM_LENGTH OLD_RSA_MD4_DES_CKSUM_LENGTH -#define CHECKSUM_TYPE CKSUMTYPE_RSA_MD4_DES -#ifdef MD4_K5BETA_COMPAT -#define K5BETA_COMPAT 1 -#else /* MD4_K5BETA_COMPAT */ -#undef K5BETA_COMPAT -#endif /* MD4_K5BETA_COMPAT */ -#define CKSUM_FUNCTION krb5_md4_crypto_sum_func -#define COMPAT_FUNCTION krb5_md4_crypto_compat_sum_func -#define VERIFY_FUNCTION krb5_md4_crypto_verify_func -#endif /* MD == 4 */ - -#if MD == 5 -#define CONFOUNDER_LENGTH RSA_MD5_DES_CONFOUND_LENGTH -#define NEW_CHECKSUM_LENGTH NEW_RSA_MD5_DES_CKSUM_LENGTH -#define OLD_CHECKSUM_LENGTH OLD_RSA_MD5_DES_CKSUM_LENGTH -#define CHECKSUM_TYPE CKSUMTYPE_RSA_MD5_DES -#ifdef MD5_K5BETA_COMPAT -#define K5BETA_COMPAT 1 -#else /* MD5_K5BETA_COMPAT */ -#undef K5BETA_COMPAT -#endif /* MD5_K5BETA_COMPAT */ -#define CKSUM_FUNCTION krb5_md5_crypto_sum_func -#define COMPAT_FUNCTION krb5_md5_crypto_compat_sum_func -#define VERIFY_FUNCTION krb5_md5_crypto_verify_func -#endif /* MD == 5 */ - -static void -print_checksum(text, number, message, checksum) - char *text; - int number; - char *message; - krb5_checksum *checksum; -{ - int i; - - printf("%s MD%d checksum(\"%s\") = ", text, number, message); - for (i=0; ilength; i++) - printf("%02x", checksum->contents[i]); - printf("\n"); -} - -/* - * Test the checksum verification of Old Style (tm) and correct RSA-MD[4,5]-DES - * checksums. - */ -int -main(argc, argv) - int argc; - char **argv; -{ - int msgindex; - krb5_context kcontext; - krb5_encrypt_block encblock; - krb5_keyblock keyblock; - krb5_error_code kret; - krb5_checksum oldstyle_checksum; - krb5_checksum newstyle_checksum; - krb5_data pwdata; - char *pwd; - - pwd = "test password"; - pwdata.length = strlen(pwd); - pwdata.data = pwd; - krb5_use_enctype(kcontext, &encblock, DEFAULT_KDC_ENCTYPE); - if ((kret = mit_des_string_to_key(&encblock, &keyblock, &pwdata, NULL))) { - printf("mit_des_string_to_key choked with %d\n", kret); - return(kret); - } - if ((kret = mit_des_process_key(&encblock, &keyblock))) { - printf("mit_des_process_key choked with %d\n", kret); - return(kret); - } - - oldstyle_checksum.length = OLD_CHECKSUM_LENGTH; - if (!(oldstyle_checksum.contents = (krb5_octet *) malloc(OLD_CHECKSUM_LENGTH))) { - printf("cannot get memory for old style checksum\n"); - return(ENOMEM); - } - newstyle_checksum.length = NEW_CHECKSUM_LENGTH; - if (!(newstyle_checksum.contents = (krb5_octet *) - malloc(NEW_CHECKSUM_LENGTH))) { - printf("cannot get memory for new style checksum\n"); - return(ENOMEM); - } - for (msgindex = 1; msgindex < argc; msgindex++) { - if ((kret = CKSUM_FUNCTION(argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length, - &newstyle_checksum))) { - printf("krb5_calculate_checksum choked with %d\n", kret); - break; - } - print_checksum("correct", MD, argv[msgindex], &newstyle_checksum); -#ifdef K5BETA_COMPAT - if ((kret = COMPAT_FUNCTION(argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length, - &oldstyle_checksum))) { - printf("old style calculate_checksum choked with %d\n", kret); - break; - } - print_checksum("old", MD, argv[msgindex], &oldstyle_checksum); -#endif /* K5BETA_COMPAT */ - if ((kret = VERIFY_FUNCTION(&newstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on new checksum choked with %d\n", kret); - break; - } - printf("Verify succeeded for \"%s\"\n", argv[msgindex]); -#ifdef K5BETA_COMPAT - if ((kret = VERIFY_FUNCTION(&oldstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on old checksum choked with %d\n", kret); - break; - } - printf("Compatible checksum verify succeeded for \"%s\"\n", - argv[msgindex]); -#endif /* K5BETA_COMPAT */ - newstyle_checksum.contents[0]++; - if (!(kret = VERIFY_FUNCTION(&newstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on new checksum should have choked\n"); - break; - } - printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]); -#ifdef K5BETA_COMPAT - oldstyle_checksum.contents[0]++; - if (!(kret = VERIFY_FUNCTION(&oldstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on old checksum should have choked\n"); - break; - } - printf("Compatible checksum verify of altered checksum OK for \"%s\"\n", - argv[msgindex]); -#endif /* K5BETA_COMPAT */ - kret = 0; - } - if (!kret) - printf("%d tests passed successfully for MD%d checksum\n", argc-1, MD); - return(kret); -} diff --git a/src/lib/crypto/nfold.c b/src/lib/crypto/nfold.c new file mode 100644 index 000000000..07c539ebe --- /dev/null +++ b/src/lib/crypto/nfold.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include + +/* +n-fold(k-bits): + l = lcm(n,k) + r = l/k + s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1) + compute the 1's complement sum: + n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1] +*/ + +/* representation: msb first, assume n and k are multiples of 8, and + that k>=16. this is the case of all the cryptosystems which are + likely to be used. this function can be replaced if that + assumption ever fails. */ + +/* input length is in bits */ + +void +krb5_nfold(inbits, in, outbits, out) + int inbits; + krb5_const unsigned char *in; + int outbits; + unsigned char *out; +{ + int a,b,c,gcd,lcm; + int reps; + int byte, i, msbit; + + /* the code below is more readable if I make these bytes + instead of bits */ + + inbits >>= 3; + outbits >>= 3; + + /* first compute lcm(n,k) */ + + a = outbits; + b = inbits; + + while(b != 0) { + c = b; + b = a%b; + a = c; + } + + lcm = outbits*inbits/a; + + /* now do the real work */ + + memset(out, 0, outbits); + byte = 0; + + /* this will end up cycling through k lcm(k,n)/k times, which + is correct */ + for (i=lcm-1; i>=0; i--) { + /* compute the msbit in k which gets added into this byte */ + msbit = (/* first, start with the msbit in the first, unrotated + byte */ + ((inbits<<3)-1) + /* then, for each byte, shift to the right for each + repetition */ + +(((inbits<<3)+13)*(i/inbits)) + /* last, pick out the correct byte within that + shifted repetition */ + +((inbits-(i%inbits))<<3) + )%(inbits<<3); + + /* pull out the byte value itself */ + byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff; + + /* do the addition */ + byte += out[i%outbits]; + out[i%outbits] = byte&0xff; + +#if 0 + printf("msbit[%d] = %d\tbyte = %02x\tsum = %03x\n", i, msbit, + (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff, byte); +#endif + + /* keep around the carry bit, if any */ + byte >>= 8; + +#if 0 + printf("carry=%d\n", byte); +#endif + } + + /* if there's a carry bit left over, add it back in */ + if (byte) { + for (i=outbits-1; i>=0; i--) { + /* do the addition */ + byte += out[i]; + out[i] = byte&0xff; + + /* keep around the carry bit, if any */ + byte >>= 8; + } + } +} + diff --git a/src/lib/crypto/old_api_glue.c b/src/lib/crypto/old_api_glue.c new file mode 100644 index 000000000..64be9b889 --- /dev/null +++ b/src/lib/crypto/old_api_glue.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" + +krb5_error_code krb5_encrypt(context, inptr, outptr, size, eblock, ivec) + krb5_context context; + krb5_const krb5_pointer inptr; + krb5_pointer outptr; + krb5_const size_t size; + krb5_encrypt_block FAR * eblock; + krb5_pointer ivec; +{ + krb5_data inputd, ivecd; + krb5_enc_data outputd; + size_t blocksize, outlen; + krb5_error_code ret; + + if (ivec) { + if (ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input cleartext data */ + inputd.length = size; + inputd.data = inptr; + + /* The size of the output buffer isn't part of the old api. Not too + safe. So, we assume here that it's big enough. */ + if (ret = krb5_c_encrypt_length(context, eblock->key->enctype, size, + &outlen)) + return(ret); + + outputd.ciphertext.length = outlen; + outputd.ciphertext.data = outptr; + + return(krb5_c_encrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code krb5_decrypt(context, inptr, outptr, size, eblock, ivec) + krb5_context context; + krb5_const krb5_pointer inptr; + krb5_pointer outptr; + krb5_const size_t size; + krb5_encrypt_block FAR * eblock; + krb5_pointer ivec; +{ + krb5_enc_data inputd; + krb5_data outputd, ivecd; + size_t blocksize; + krb5_error_code ret; + + if (ivec) { + if (ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input ciphertext data */ + inputd.enctype = eblock->key->enctype; + inputd.ciphertext.length = size; + inputd.ciphertext.data = inptr; + + /* we don't really know how big this is, but the code tends to assume + that the output buffer size should be the same as the input + buffer size */ + outputd.length = size; + outputd.data = outptr; + + return(krb5_c_decrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code krb5_process_key(context, eblock, key) + krb5_context context; + krb5_encrypt_block FAR * eblock; + krb5_const krb5_keyblock FAR * key; +{ + eblock->key = (krb5_keyblock *) key; + + return(0); +} + +krb5_error_code krb5_finish_key(context, eblock) + krb5_context context; + krb5_encrypt_block FAR * eblock; +{ + return(0); +} + +krb5_error_code krb5_string_to_key(context, eblock, keyblock, data, salt) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_keyblock FAR * keyblock; + krb5_const krb5_data FAR * data; + krb5_const krb5_data FAR * salt; +{ + return(krb5_c_string_to_key(context, eblock->crypto_entry, data, salt, + keyblock)); +} + +krb5_error_code krb5_init_random_key(context, eblock, keyblock, ptr) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_const krb5_keyblock FAR * keyblock; + krb5_pointer FAR * ptr; +{ + krb5_data data; + + data.length = keyblock->length; + data.data = keyblock->contents; + + return(krb5_c_random_seed(context, &data)); +} + +krb5_error_code krb5_finish_random_key(context, eblock, ptr) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_pointer FAR * ptr; +{ + return(0); +} + +krb5_error_code krb5_random_key(context, eblock, ptr, keyblock) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_pointer ptr; + krb5_keyblock FAR * FAR * keyblock; +{ + krb5_keyblock *key; + krb5_error_code ret; + + if ((key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL) + return(ENOMEM); + + if (ret = krb5_c_make_random_key(context, eblock->crypto_entry, key)) + free(key); + + *keyblock = key; + + return(ret); +} + +krb5_enctype krb5_eblock_enctype(context, eblock) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; +{ + return(eblock->crypto_entry); +} + +krb5_error_code krb5_use_enctype(context, eblock, enctype) + krb5_context context; + krb5_encrypt_block FAR * eblock; + krb5_const krb5_enctype enctype; +{ + eblock->crypto_entry = enctype; + + return(0); +} + +size_t krb5_encrypt_size(length, crypto) + size_t length; + krb5_enctype crypto; +{ + size_t ret; + + if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +size_t krb5_checksum_size(context, ctype) + krb5_context context; + krb5_cksumtype ctype; +{ + size_t ret; + + if (krb5_c_checksum_length(context, ctype, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +krb5_error_code krb5_calculate_checksum(context, ctype, in, in_length, + seed, seed_length, outcksum) + krb5_context context; + krb5_const krb5_cksumtype ctype; + krb5_const krb5_pointer in; + krb5_const size_t in_length; + krb5_const krb5_pointer seed; + krb5_const size_t seed_length; + krb5_checksum FAR * outcksum; +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_checksum cksum; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if (ret = krb5_c_make_checksum(context, ctype, &key, 0, &input, &cksum)) + return(ret); + + if (outcksum->length < cksum.length) { + memset(cksum.contents, 0, cksum.length); + free(cksum.contents); + return(KRB5_BAD_MSIZE); + } + + outcksum->magic = cksum.magic; + outcksum->checksum_type = cksum.checksum_type; + memcpy(outcksum->contents, cksum.contents, cksum.length); + outcksum->length = cksum.length; + + free(cksum.contents); + + return(0); +} + +krb5_error_code krb5_verify_checksum(context, ctype, cksum, in, in_length, + seed, seed_length) + krb5_context context; + krb5_cksumtype ctype; + krb5_const krb5_checksum FAR * cksum; + krb5_const krb5_pointer in; + krb5_const size_t in_length; + krb5_const krb5_pointer seed; + krb5_const size_t seed_length; +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_boolean valid; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if (ret = krb5_c_verify_checksum(context, &key, 0, &input, cksum, + &valid)) + return(ret); + + if (!valid) + return(KRB5KRB_AP_ERR_BAD_INTEGRITY); + + return(0); +} + +krb5_error_code krb5_random_confounder(size, ptr) + size_t size; + krb5_pointer ptr; +{ + krb5_data random; + + random.length = size; + random.data = ptr; + + return(krb5_c_random_make_octets(/* XXX */ 0, &random)); +} + +krb5_error_code krb5_encrypt_data(context, key, ivec, data, enc_data) + krb5_context context; + krb5_keyblock *key; + krb5_pointer ivec; + krb5_data *data; + krb5_enc_data *enc_data; +{ + krb5_error_code ret; + size_t enclen, blocksize; + krb5_data ivecd; + + if (ret = krb5_c_encrypt_length(context, key->enctype, data->length, + &enclen)) + return(ret); + + if (ivec) { + if (ret = krb5_c_block_size(context, key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + enc_data->magic = KV5M_ENC_DATA; + enc_data->kvno = 0; + enc_data->enctype = key->enctype; + enc_data->ciphertext.length = enclen; + if ((enc_data->ciphertext.data = malloc(enclen)) == NULL) + return(ENOMEM); + + if (ret = krb5_c_encrypt(context, key, 0, ivec?&ivecd:0, data, enc_data)) + free(enc_data->ciphertext.data); + + return(ret); +} + +krb5_error_code krb5_decrypt_data(context, key, ivec, enc_data, data) + krb5_context context; + krb5_keyblock *key; + krb5_pointer ivec; + krb5_enc_data *enc_data; + krb5_data *data; +{ + krb5_error_code ret; + krb5_data ivecd; + size_t blocksize; + + if (ivec) { + if (ret = krb5_c_block_size(context, key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + data->length = enc_data->ciphertext.length; + if ((data->data = (krb5_octet *) malloc(data->length)) == NULL) + return(ENOMEM); + + if (ret = krb5_c_decrypt(context, key, 0, ivec?&ivecd:0, enc_data, data)) + free(data->data); + + return(0); +} diff --git a/src/lib/crypto/os/.Sanitize b/src/lib/crypto/os/.Sanitize deleted file mode 100644 index 2e24ee69f..000000000 --- a/src/lib/crypto/os/.Sanitize +++ /dev/null @@ -1,39 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -.cvsignore -ChangeLog -Makefile.in -configure -configure.in -c_localaddr.c -c_ustime.c -rnd_confoun.c - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/src/lib/crypto/os/ChangeLog b/src/lib/crypto/os/ChangeLog deleted file mode 100644 index ebcb593a1..000000000 --- a/src/lib/crypto/os/ChangeLog +++ /dev/null @@ -1,204 +0,0 @@ -Wed Feb 18 16:08:30 1998 Tom Yu - - * Makefile.in: Remove trailing slash from thisconfigdir. Fix up - BUILDTOP for new conventions. - -Fri Feb 13 15:20:54 1998 Theodore Ts'o - - * Makefile.in (thisconfigdir), configure.in: Point the - configuration directory at our parent, and remove our - local configure.in - -Mon Feb 2 17:02:29 1998 Theodore Ts'o - - * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile - -Fri Nov 28 21:23:42 1997 Tom Yu - - * configure.in: Add AC_PROG_LN_S to deal with symlinking in - memmove.c. This is a kludge, as we really should have a more sane - way to deal with missing posix functions. - -Thu Sep 25 21:53:11 1997 Tom Yu - - * c_localaddr.c: Replace KRB5_USE_INET with something more sane. - -Tue Aug 12 09:09:14 1997 Ezra Peisach - - * Makefile.in (SRCS): Add $(srcdir) as needed. - -Fri Jul 4 00:13:02 1997 Theodore Y. Ts'o - - * c_localaddr.c (local_addr_fallback_kludge): Added Winsock - kludge for finding your local IP address. May not work - for all stacks, so we use it as a fallback. - -Sat Feb 22 18:54:53 1997 Richard Basch - - * Makefile.in: Use some of the new library list build rules in - win-post.in - -Mon Feb 17 17:24:41 1997 Richard Basch - - * c_ustime.c: Fixed microsecond adjustment code (win32) - -Thu Nov 21 00:58:04 EST 1996 Richard Basch - - * Makefile.in: Win32 build - - * c_ustime.c: The Win32 time calculation is different from DOS' - so the DOS version shouldn't be trying to use the same - part of the ifdef. - - * rnd_confoun.c: Fix function declaration (win32) - -Sun Dec 29 21:54:42 1996 Tom Yu - - * Makefile.in: - * configure.in: Update to use new library building procedure. - -Wed Jun 12 00:12:52 1996 Theodore Ts'o - - * c_ustime.c: Fix WIN32 to be _WIN32 - - * c_localaddr.c: Add #ifdef _WIN32 in places where we had #ifdef _MSDOS - - -Sat Feb 24 00:34:15 1996 Theodore Y. Ts'o - - * c_ustime.c (krb5_crypto_us_timeofday): Add Windows 95/NT time - function. (Does this time function work under Windows? - We'll find out....) - -Thu Feb 15 10:57:27 1996 Ezra Peisach - - * c_localaddr.c: Set magic number in krb5_address. - -Fri Oct 6 22:00:48 1995 Theodore Y. Ts'o - - * Makefile.in: Remove ##DOS!include of config/windows.in. - config/windows.in is now included by wconfig. - -Mon Sep 25 16:49:15 1995 Theodore Y. Ts'o - - * Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the - Makefile. - -Fri Sep 22 12:00:00 1995 James Mattly - - * c_localaddr.c: change close on a socket to closesocket, sockets on - macintosh arn't files - -Wed Sep 13 10:33:53 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: PC builds all C files because of function name changes. - * c_localtime.c, c_ustime.c: removed INTERFACE keyword. - -Wed Sep 13 17:32:36 1995 Theodore Y. Ts'o - - * c_localaddr.c (krb5_crypto_os_localaddr): Clear the buffer - before calling the SIOCGIFCONF ioctl. This makes purify - happy. - -Thu Sep 7 12:00:00 1995 James Mattly - - * Renamed ustime.c to c_ustime.c - * Renamed localaddr.c to c_localaddr.c because Mac can't have - two files with the same name. - * Makefile.in, .Sanitize updated for the above change. - -Thu Aug 24 18:40:48 1995 Theodore Y. Ts'o - - * .Sanitize: Update file list - -Sat Jul 29 03:17:21 1995 Tom Yu - - * localaddr.c (krb5_crypto_os_localaddr): Don't bash the return - from SIOCGIFCONF with the output of a SIOCGIFFLAGS. Duh. - -Wed Jul 19 17:17:54 1995 Tom Yu - - * localaddr.c: also add definition of max if it's not there. - - * localaddr.c: fix definition of ifreq_size so it actually works - -Mon Jul 17 16:04:00 1995 Sam Hartman - - * localaddr.c (krb5_crypto_os_localaddr): Deal with variable sized - ifreq structures if sockaddr contains sa_len field. - - * configure.in: Check to see if struct sockaddr has sa_len. - -Thu Jul 6 17:13:11 1995 Tom Yu - - * localaddr.c: migrated from lib/krb5/os - - * ustime.c: migrated from lib/krb5/os; removed context variable - from arglist. - - * Makefile.in: don't copy or remove localaddr.c and ustime.c; - they're local now. - -Fri Jun 9 19:18:41 1995 - - * configure.in: Remove standardized set of autoconf macros, which - are now handled by CONFIG_RULES. - -Thu May 25 22:16:35 1995 Theodore Y. Ts'o (tytso@dcl) - - * configure.in, Makefile.in: Add support for shared libraries. - -Thu Apr 13 15:49:16 1995 Keith Vetter (keithv@fusion.com) - - * *.[ch]: removed unneeded INTERFACE from non-api functions. - -Sat Mar 25 15:38:23 1995 Mark Eichin - - * Makefile.in (memmove.c): memmove.c is in krb5/posix, not krb5/os. - -Wed Mar 22 11:44:07 1995 - - * Makefile.in: Use $(SRCTOP) instead of $(srcdir), since Mac's - don't like dealing with $(U)$(U). - -Fri Mar 17 16:21:46 1995 Theodore Y. Ts'o (tytso@dcl) - - * Makefile.in: Fix rules for localdr.c, ustime.c, and memmove.c so - that they reference $(srcdir) where appropriate. - -Thu Mar 16 21:24:43 1995 John Gilmore (gnu at toad.com) - - * Makefile.in (LDFLAGS): Eliminate, comes in from pre.in. - (all-mac): Add. - (localaddr.c, ustime.c, memmove.c): Fix paths to work on Mac. - -Tue Mar 14 17:23:02 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: no longer need to bring in ustime and localaddr for - windows since everything's going into one DLL in the end. - -Thu Mar 2 17:56:48 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: changed LIBNAME for the PC, and brought in ustime - and localaddr from the krb/os directory. - * rnd_conf.c: added cast to the seed assignment. - -Mon Feb 20 16:25:36 1995 Keith Vetter (keithv@fusion.com) - - * Makfile.in: made to work for the PC - * rnd_confoun.c: added windows INTERFACE keyword - -Wed Jan 25 20:24:35 1995 John Gilmore (gnu at toad.com) - - * rnd_confoun.c: Replace <.../...> includes with "..."s. - -Mon Oct 24 14:58:14 1994 (tytso@rsx-11) - - * configure.in: - * rnd_confoun.c (krb5_random_confounder): Use the srand48/lrand48 - functions if available. - -Fri Oct 14 00:21:05 1994 Theodore Y. Ts'o (tytso@dcl) - - * Makefile.in: Remove symlinked files on make clean. - diff --git a/src/lib/crypto/os/Makefile.in b/src/lib/crypto/os/Makefile.in deleted file mode 100644 index d4c5f4141..000000000 --- a/src/lib/crypto/os/Makefile.in +++ /dev/null @@ -1,28 +0,0 @@ -thisconfigdir=./.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) - -##DOS##BUILDTOP = ..\..\.. -##DOS##PREFIXDIR=os -##DOS##OBJFILE=..\os.lst -##WIN16##LIBNAME=..\crypto.lib - -STLIBOBJS = rnd_confoun.o c_localaddr.o c_ustime.o @LIBOBJS@ - -COBJS= rnd_confoun.$(OBJEXT) c_localaddr.$(OBJEXT) c_ustime.$(OBJEXT) -OBJS= $(COBJS) $(LIBOBJS) - -SRCS= $(srcdir)/rnd_confoun.c $(srcdir)/c_localaddr.c $(srcdir)/c_ustime.c - -##DOS##LIBOBJS = $(COBJS) - -all-unix:: all-libobjs - -memmove.c: $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c - -$(LN) $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c $@ - -memmove.o: memmove.c - -clean-unix:: clean-libobjs -clean:: - $(RM) memmove.c diff --git a/src/lib/crypto/os/c_localaddr.c b/src/lib/crypto/os/c_localaddr.c deleted file mode 100644 index 3b3bcb474..000000000 --- a/src/lib/crypto/os/c_localaddr.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * lib/crypto/os/c_localaddr.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. - * - * - * Return the protocol addresses supported by this host. - * - * XNS support is untested, but "Should just work". - */ - - -#define NEED_SOCKETS -#include "k5-int.h" - -#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32) - -/* needed for solaris, harmless elsewhere... */ -#define BSD_COMP -#include -#include -#include - -/* - * The SIOCGIF* ioctls require a socket. - * It doesn't matter *what* kind of socket they use, but it has to be - * a socket. - * - * Of course, you can't just ask the kernel for a socket of arbitrary - * type; you have to ask for one with a valid type. - * - */ -#ifdef HAVE_NETINET_IN_H - -#include - -#ifndef USE_AF -#define USE_AF AF_INET -#define USE_TYPE SOCK_DGRAM -#define USE_PROTO 0 -#endif - -#endif - -#ifdef KRB5_USE_NS - -#include - -#ifndef USE_AF -#define USE_AF AF_NS -#define USE_TYPE SOCK_DGRAM -#define USE_PROTO 0 /* guess */ -#endif - -#endif -/* - * Add more address families here. - */ - -/* - * BSD 4.4 defines the size of an ifreq to be - * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len - * However, under earlier systems, sa_len isn't present, so the size is - * just sizeof(struct ifreq) - */ -#ifdef HAVE_SA_LEN -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif -#define ifreq_size(i) max(sizeof(struct ifreq),\ - sizeof((i).ifr_name)+(i).ifr_addr.sa_len) -#else -#define ifreq_size(i) sizeof(struct ifreq) -#endif /* HAVE_SA_LEN*/ - - - -extern int errno; - -/* - * Return all the protocol addresses of this host. - * - * We could kludge up something to return all addresses, assuming that - * they're valid kerberos protocol addresses, but we wouldn't know the - * real size of the sockaddr or know which part of it was actually the - * host part. - * - * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's. - */ - -krb5_error_code -krb5_crypto_os_localaddr(addr) - krb5_address ***addr; -{ - struct ifreq *ifr, ifreq; - struct ifconf ifc; - int s, code, n, i; - char buf[1024]; - krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ]; - int n_found; - int mem_err = 0; - - memset(buf, 0, sizeof(buf)); - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - - s = socket (USE_AF, USE_TYPE, USE_PROTO); - if (s < 0) - return errno; - - code = ioctl (s, SIOCGIFCONF, (char *)&ifc); - if (code < 0) { - int retval = errno; - closesocket (s); - return retval; - } - n = ifc.ifc_len; - -n_found = 0; - for (i = 0; i < n; i+= ifreq_size(*ifr) ) { - krb5_address *address; - ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); - - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); - if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) - continue; - -#ifdef IFF_LOOPBACK - if (ifreq.ifr_flags & IFF_LOOPBACK) - continue; -#endif - - if (!(ifreq.ifr_flags & IFF_UP)) - /* interface is down; skip */ - continue; - - /* ifr->ifr_addr has what we want! */ - switch (ifr->ifr_addr.sa_family) { -#ifdef HAVE_NETINET_IN_H - case AF_INET: - { - struct sockaddr_in *in = - (struct sockaddr_in *)&ifr->ifr_addr; - - address = (krb5_address *) - malloc (sizeof(krb5_address)); - if (address) { - address->magic = KV5M_ADDRESS; - address->addrtype = ADDRTYPE_INET; - address->length = sizeof(struct in_addr); - address->contents = (unsigned char *)malloc(address->length); - if (!address->contents) { - krb5_xfree(address); - address = 0; - mem_err++; - } else { - memcpy ((char *)address->contents, - (char *)&in->sin_addr, - address->length); - break; - } - } else mem_err++; - } -#endif -#ifdef KRB5_USE_NS - case AF_XNS: - { - struct sockaddr_ns *ns = - (struct sockaddr_ns *)&ifr->ifr_addr; - address = (krb5_address *) - malloc (sizeof (krb5_address) + sizeof (struct ns_addr)); - if (address) { - address->magic = KV5M_ADDRESS; - address->addrtype = ADDRTYPE_XNS; - - /* XXX should we perhaps use ns_host instead? */ - - address->length = sizeof(struct ns_addr); - address->contents = (unsigned char *)malloc(address->length); - if (!address->contents) { - krb5_xfree(address); - address = 0; - mem_err++; - } else { - memcpy ((char *)address->contents, - (char *)&ns->sns_addr, - address->length); - break; - } - } else mem_err++; - break; - } -#endif - /* - * Add more address families here.. - */ - default: - continue; - } - if (address) - addr_temp[n_found++] = address; - address = 0; - } - closesocket(s); - - *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1)); - if (*addr == 0) - mem_err++; - - if (mem_err) { - for (i=0; imagic = KV5M_ADDRESS; - (*addr)[0]->addrtype = hostrec->h_addrtype; - (*addr)[0]->length = hostrec->h_length; - (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length); - if (!(*addr)[0]->contents) { - free((*addr)[0]); - free(*addr); - return ENOMEM; - } else { - memcpy ((*addr)[0]->contents, - hostrec->h_addr, - (*addr)[0]->length); - } - /* FIXME, deal with the case where gethostent returns multiple addrs */ - - return(0); -} -#endif diff --git a/src/lib/crypto/os/rnd_confoun.c b/src/lib/crypto/os/rnd_confoun.c deleted file mode 100644 index e904cb5c7..000000000 --- a/src/lib/crypto/os/rnd_confoun.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * lib/crypto/os/rnd_confoun.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * 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. - * - * - * krb5_random_confounder() - */ - -#include "k5-int.h" - -#ifdef HAVE_SYS_TIME_H -#include -#ifdef TIME_WITH_SYS_TIME -#include -#endif -#else -#include -#endif - -#ifdef HAVE_SRAND48 -#define SRAND srand48 -#define RAND lrand48 -#define RAND_TYPE long -#endif - -#if !defined(RAND_TYPE) && defined(HAVE_SRAND) -#define SRAND srand -#define RAND rand -#define RAND_TYPE int -#endif - -#if !defined(RAND_TYPE) && defined(HAVE_SRANDOM) -#define SRAND srandom -#define RAND random -#define RAND_TYPE long -#endif - -#if !defined(RAND_TYPE) -You need a random number generator! -#endif - -/* - * Generate a random confounder - */ -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_random_confounder(size, fillin) -size_t size; -krb5_pointer fillin; -{ - static int seeded = 0; - register krb5_octet *real_fill; - RAND_TYPE rval; - - if (!seeded) { - /* time() defined in 4.12.2.4, but returns a time_t, which is an - "arithmetic type" (4.12.1) */ - rval = (RAND_TYPE) time(0); - SRAND(rval); -#ifdef HAVE_GETPID - rval = RAND(); - rval ^= getpid(); - SRAND(rval); -#endif - seeded = 1; - } - - real_fill = (krb5_octet *)fillin; - while (size > 0) { - rval = RAND(); - *real_fill = rval & 0xff; - real_fill++; - size--; - if (size) { - *real_fill = (rval >> 8) & 0xff; - real_fill++; - size--; - } - } - return 0; -} diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c new file mode 100644 index 000000000..2d4f6647d --- /dev/null +++ b/src/lib/crypto/prng.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "enc_provider.h" + +/* This random number generator is a feedback generator based on a + block cipher. It uses DES by default, since it guaranteed to be + present in the system, but can be changed. As new seed data comes + in, the old state is folded with the new seed into new state. Each + time random bytes are requested, the seed is used as a key and + cblock, and the encryption is used as the output. The output is + fed back as new seed data, as described above. */ + +/* this can be replaced with another encryption provider, since + everything below uses it abstractly */ + +struct krb5_enc_provider *enc = &krb5_enc_des; + +/* XXX state. Should it be in krb5_context? */ + +static int inited = 0; +static size_t blocksize, keybytes, keylength; +static int random_count; +/* keybytes | state-block | encblock | key | new-keybytes | new-state-block */ +static unsigned char *random_state; +#define STATE (random_state) +#define STATEKEY (STATE) +#define STATEBLOCK (STATEKEY+keybytes) +#define STATESIZE (keybytes+blocksize) +#define OUTPUT (STATE) +#define OUTPUTSIZE (STATESIZE+blocksize) +#define RANDBLOCK (STATEBLOCK+blocksize) +#define KEYCONTENTS (RANDBLOCK+blocksize) +#define NEWSTATE (KEYCONTENTS+keylength) +#define ALLSTATESIZE (keybytes+blocksize*2+keylength+keybytes+blocksize) + +krb5_error_code +krb5_c_random_seed(krb5_context context, krb5_data *data) +{ + unsigned char *fold_input; + + if (inited == 0) { + /* this does a bunch of malloc'ing up front, so that + generating random keys doesn't have to malloc, so it can't + fail. seeding still malloc's, but that's less common. */ + + enc->block_size(&blocksize); + enc->keysize(&keybytes, &keylength); + if ((random_state = (unsigned char *) malloc(ALLSTATESIZE)) == NULL) + return(ENOMEM); + random_count = 0; + inited = 1; + + krb5_nfold(data->length*8, data->data, STATESIZE*8, STATE); + + return(0); + } + + if ((fold_input = + (unsigned char *) malloc(data->length+STATESIZE)) == NULL) + return(ENOMEM); + + memcpy(fold_input, data->data, data->length); + memcpy(fold_input+data->length, STATE, STATESIZE); + + krb5_nfold((data->length+STATESIZE)*8, fold_input, + STATESIZE*8, STATE); + free(fold_input); + return(0); +} + +krb5_error_code +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + krb5_error_code ret; + krb5_data data1, data2; + krb5_keyblock key; + int bytes; + + if (inited == 0) { + /* i need some entropy. I'd use the current time and pid, but + that could cause portability problems. */ + abort(); + } + + bytes = 0; + + while (bytes < data->length) { + if (random_count == 0) { + /* set up random krb5_data, and key to be filled in */ + data1.length = keybytes; + data1.data = STATEKEY; + key.length = keylength; + key.contents = KEYCONTENTS; + + /* fill it in */ + if (ret = ((*(enc->make_key))(&data1, &key))) + return(ret); + + /* encrypt the block */ + data1.length = blocksize; + data1.data = STATEBLOCK; + data2.length = blocksize; + data2.data = RANDBLOCK; + if (ret = ((*(enc->encrypt))(&key, NULL, &data1, &data2))) + return(ret); + + /* fold the new output back into the state */ + + krb5_nfold(OUTPUTSIZE*8, OUTPUT, STATESIZE*8, NEWSTATE); + memcpy(STATE, NEWSTATE, STATESIZE); + + random_count = blocksize; + } + + if ((data->length - bytes) <= random_count) { + memcpy(data->data + bytes, RANDBLOCK+(blocksize-random_count), + data->length - bytes); + random_count -= (data->length - bytes); + break; + } + + memcpy(data->data + bytes, RANDBLOCK+(blocksize - random_count), + random_count); + + bytes += random_count; + random_count = 0; + } + + return(0); +} diff --git a/src/lib/crypto/raw_des.c b/src/lib/crypto/raw_des.c deleted file mode 100644 index 65e0ebdbb..000000000 --- a/src/lib/crypto/raw_des.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * lib/crypto/raw-des.c - * - * Copyright 1994, 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code mit_raw_des_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_raw_des_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_cryptosystem_entry mit_raw_des_cryptosystem_entry = { - 0, - mit_raw_des_encrypt_func, - mit_raw_des_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - 0, - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_RAW - }; - -krb5_cs_table_entry krb5_raw_des_cst_entry = { - 0, - &mit_raw_des_cryptosystem_entry, - 0 - }; - -krb5_error_code -mit_raw_des_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - return (mit_des_cbc_encrypt ((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *)key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT)); -} - -krb5_error_code -mit_raw_des_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - int sumsize; - - /* round up to des block size */ - - sumsize = krb5_roundup(size, sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - memcpy((char *)out, (char *)in, size); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt (out, - out, - sumsize, - (struct mit_des_ks_struct *)key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); -} diff --git a/src/lib/crypto/sha/.Sanitize b/src/lib/crypto/sha/.Sanitize deleted file mode 100644 index 886bb2b0a..000000000 --- a/src/lib/crypto/sha/.Sanitize +++ /dev/null @@ -1,42 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -.cvsignore -ChangeLog -Makefile.in -configure -configure.in -sha_crypto.c -sha_glue.c -shs.c -shs.h -hmac_sha.c -t_shs.c - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/src/lib/crypto/sha/ChangeLog b/src/lib/crypto/sha/ChangeLog deleted file mode 100644 index 19abbbf6e..000000000 --- a/src/lib/crypto/sha/ChangeLog +++ /dev/null @@ -1,89 +0,0 @@ -Wed Feb 18 16:09:05 1998 Tom Yu - - * Makefile.in: Remove trailing slash from thisconfigdir. Fix up - BUILDTOP for new conventions. - -Fri Feb 13 15:20:54 1998 Theodore Ts'o - - * Makefile.in (thisconfigdir), configure.in: Point the - configuration directory at our parent, and remove our - local configure.in - -Mon Feb 2 17:02:29 1998 Theodore Ts'o - - * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile - -Tue Oct 28 16:37:18 1997 Tom Yu - - * shs.c, sha_glue.c, hmac_sha.c: Fix to deal with LONG wider than - 32 bits. - - * t_shs.c: Print out the actual and expected values on error. - -Sat Feb 22 18:52:09 1997 Richard Basch - - * Makefile.in: Use some of the new library list build rules in - win-post.in - -Thu Jan 30 21:31:39 1997 Richard Basch - - * sha_crypto.c sha_glue.c: - Declare the functions to take const args where possible - Remove extra includes - - * sha_crypto.c: Function prototypes did not match function names. - -Thu Nov 21 00:58:04 EST 1996 Richard Basch - - * Makefile.in: Win32 build fixed - -Sun Dec 29 21:56:35 1996 Tom Yu - - * Makefile.in: - * configure.in: Update to use new library build procedure. - -Wed Aug 28 17:40:53 1996 Theodore Ts'o - - * shs.c: Only include sys/types.h if present. - - * configure.in: Check for sys/types.h - -Thu Jun 13 10:54:27 1996 Ezra Peisach - - * hmac_sha.c: Include string.h for memcpy prototype - -Sat Jun 8 07:44:35 1996 Ezra Peisach (epeisach@mit.edu) - - * shs.c (longReverse): Test for big vs little endian failed for - little endian machines. - -Thu Jun 6 15:43:26 1996 Theodore Y. Ts'o - - * shs.c (longReverse): Don't use htonl(); it doesn't exist under - Windows. Instead do the test by casting a pointer to an - integer to a char *. - -Mon May 20 17:15:32 1996 Theodore Y. Ts'o - - * t_shs.c (main): Don't do timing tests; it takes too long! - -Tue May 14 17:09:36 1996 Richard Basch - - * .Sanitize: reflect current files - * Makefile.in: added hmac-sha - * hmac_sha.c: implement HMAC-SHA - * sha_crypto.c: use hmac-sha - * sha_glue.c: sanity check the passed in checksum length - * shs.h: replaced sha-des3 with hmac-sha - -Fri May 10 11:19:53 1996 Ezra Peisach - - * shs.c (longReverse): Remove extraneous \. - (expand): Start #define in first column. - -Fri May 10 01:19:18 1996 Richard Basch - - * Makefile.in configure.in t_shs.c sha_glue.c sha_crypto.c shs.c shs.h: - Initial check-in of the functions to support the NIST FIPS 180 - SHA algorithm. Provide interfaces for cksum-sha, cksum-sha-des3. - (enctype-des3-sha is also being defined) diff --git a/src/lib/crypto/sha/Makefile.in b/src/lib/crypto/sha/Makefile.in deleted file mode 100644 index 058ac0db0..000000000 --- a/src/lib/crypto/sha/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -thisconfigdir=./.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des - -##DOS##BUILDTOP = ..\..\.. -##DOS##PREFIXDIR=sha -##DOS##OBJFILE=..\sha.lst -##WIN16##LIBNAME=..\crypto.lib - -STLIBOBJS=shs.o hmac_sha.o sha_crypto.o sha_glue.o - -OBJS= shs.$(OBJEXT) \ - hmac_sha.$(OBJEXT) \ - sha_crypto.$(OBJEXT) \ - sha_glue.$(OBJEXT) - -SRCS= $(srcdir)/shs.c \ - $(srcdir)/hmac_sha.c \ - $(srcdir)/sha_crypto.c \ - $(srcdir)/sha_glue.c - - -##DOS##LIBOBJS = $(OBJS) - - -all-unix:: all-libobjs - -t_shs: t_shs.o shs.o - $(CC) $(CFLAGS) $(LDFLAGS) -o t_shs t_shs.o shs.o - -t_shs.exe: - $(CC) $(CFLAGS2) -o t_shs.exe t_shs.c shs.c - -check-unix:: t_shs - $(C)t_shs -x - -check-windows:: t_shs$(EXEEXT) - $(C)t_shs$(EXEEXT) -x - -clean:: - $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) - -clean-unix:: clean-libobjs diff --git a/src/lib/crypto/sha/hmac_sha.c b/src/lib/crypto/sha/hmac_sha.c deleted file mode 100644 index d57092e69..000000000 --- a/src/lib/crypto/sha/hmac_sha.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include "shs.h" - -#define PAD_SZ 64 - - -krb5_error_code -hmac_sha(text, text_len, key, key_len, digest) - krb5_octet * text; /* pointer to data stream */ - int text_len; /* length of data stream */ - krb5_octet * key; /* pointer to authentication key */ - int key_len; /* length of authentication key */ - krb5_octet * digest; /* caller digest to be filled in */ -{ - SHS_INFO context; - krb5_octet k_ipad[PAD_SZ]; /* inner padding - key XORd with ipad */ - krb5_octet k_opad[PAD_SZ]; /* outer padding - key XORd with opad */ - int i; - krb5_octet *cp; - LONG *lp; - - /* sanity check parameters */ - if (!text || !key || !digest) - /* most heinous, probably should log something */ - return EINVAL; - - /* if key is longer than 64 bytes reset it to key=SHA(key) */ - if (key_len > sizeof(k_ipad)) { - shsInit(&context); - shsUpdate(&context, key, key_len); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - key = digest; - key_len = SHS_DIGESTSIZE; - } - - /* - * the HMAC_SHA transform looks like: - * - * SHA(K XOR opad, SHA(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in pads */ - memset(k_ipad, 0x36, sizeof(k_ipad)); - memset(k_opad, 0x5c, sizeof(k_opad)); - - /* XOR key with ipad and opad values */ - for (i = 0; i < key_len; i++) { - k_ipad[i] ^= key[i]; - k_opad[i] ^= key[i]; - } - - /* - * perform inner SHA - */ - shsInit(&context); - shsUpdate(&context, k_ipad, sizeof(k_ipad)); - shsUpdate(&context, text, text_len); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - - /* - * perform outer SHA - */ - shsInit(&context); - shsUpdate(&context, k_opad, sizeof(k_opad)); - shsUpdate(&context, digest, SHS_DIGESTSIZE); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - - return 0; -} diff --git a/src/lib/crypto/sha/sha_crypto.c b/src/lib/crypto/sha/sha_crypto.c deleted file mode 100644 index b539b1199..000000000 --- a/src/lib/crypto/sha/sha_crypto.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "shs.h" - -/* Windows needs to these prototypes for the assignment below */ - -static krb5_error_code -krb5_sha_crypto_sum_func - PROTOTYPE((krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -static krb5_error_code -krb5_sha_crypto_verify_func - PROTOTYPE((krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static krb5_error_code -krb5_sha_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_error_code retval; - - if (outcksum->length < HMAC_SHA_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - outcksum->checksum_type = CKSUMTYPE_HMAC_SHA; - outcksum->length = HMAC_SHA_CKSUM_LENGTH; - - retval = hmac_sha(in, in_length, seed, seed_length, outcksum->contents); - return retval; -} - -static krb5_error_code -krb5_sha_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet digest[HMAC_SHA_CKSUM_LENGTH]; - krb5_error_code retval; - - if (cksum->checksum_type != CKSUMTYPE_HMAC_SHA) - return KRB5KRB_AP_ERR_INAPP_CKSUM; - if (cksum->length != HMAC_SHA_CKSUM_LENGTH) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - retval = hmac_sha(in, in_length, seed, seed_length, digest); - if (retval) goto cleanup; - - if (memcmp((char *)digest, (char *)cksum->contents, cksum->length)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - -cleanup: - memset((char *)digest, 0, sizeof(digest)); - return retval; -} - -krb5_checksum_entry hmac_sha_cksumtable_entry = -{ - 0, - krb5_sha_crypto_sum_func, - krb5_sha_crypto_verify_func, - HMAC_SHA_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; diff --git a/src/lib/crypto/sha/sha_glue.c b/src/lib/crypto/sha/sha_glue.c deleted file mode 100644 index 58a93b723..000000000 --- a/src/lib/crypto/sha/sha_glue.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "shs.h" - -krb5_error_code -krb5_sha_sum_func - PROTOTYPE((krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_sha_verify_func - PROTOTYPE((krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_sha_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_octet *cp; - LONG *lp; - SHS_INFO working; - - if (outcksum->length < SHS_DIGESTSIZE) - return KRB5_BAD_MSIZE; - - shsInit(&working); - shsUpdate(&working, input, in_length); - shsFinal(&working); - - outcksum->checksum_type = CKSUMTYPE_NIST_SHA; - outcksum->length = SHS_DIGESTSIZE; - - cp = outcksum->contents; - lp = working.digest; - while (lp < working.digest + 16) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = (*lp++) & 0xff; - } - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_sha_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - SHS_INFO working; - krb5_error_code retval; - int i; - krb5_octet *cp; - - if (cksum->checksum_type != CKSUMTYPE_NIST_SHA) - return KRB5KRB_AP_ERR_INAPP_CKSUM; - if (cksum->length != SHS_DIGESTSIZE) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - shsInit(&working); - shsUpdate(&working, input, in_length); - shsFinal(&working); - - retval = 0; - for (i = 0, cp = cksum->contents; i < 5; i++, cp += 4) { - if (working.digest[i] != - (LONG) cp[0] << 24 | (LONG) cp[1] << 16 | - (LONG) cp[2] << 8 | (LONG) cp[3]) { - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - break; - } - } - memset((char *) &working, 0, sizeof(working)); - return retval; -} - -krb5_checksum_entry nist_sha_cksumtable_entry = { - 0, - krb5_sha_sum_func, - krb5_sha_verify_func, - SHS_DIGESTSIZE, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/sha/shs.c b/src/lib/crypto/sha/shs.c deleted file mode 100644 index e18f3af9e..000000000 --- a/src/lib/crypto/sha/shs.c +++ /dev/null @@ -1,392 +0,0 @@ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include -#include "shs.h" - -/* The SHS f()-functions. The f1 and f3 functions can be optimized to - save one boolean operation each - thanks to Rich Schroeppel, - rcs@cs.arizona.edu for discovering this */ - -#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ -#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ -#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ -#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ - -/* The SHS Mysterious Constants */ - -#define K1 0x5A827999L /* Rounds 0-19 */ -#define K2 0x6ED9EBA1L /* Rounds 20-39 */ -#define K3 0x8F1BBCDCL /* Rounds 40-59 */ -#define K4 0xCA62C1D6L /* Rounds 60-79 */ - -/* SHS initial values */ - -#define h0init 0x67452301L -#define h1init 0xEFCDAB89L -#define h2init 0x98BADCFEL -#define h3init 0x10325476L -#define h4init 0xC3D2E1F0L - -/* Note that it may be necessary to add parentheses to these macros if they - are to be called with expressions as arguments */ - -/* 32-bit rotate left - kludged with shifts */ - -#define ROTL(n,X) (((X) << (n)) & 0xffffffff | ((X) >> (32 - n))) - -/* The initial expanding function. The hash function is defined over an - 80-word expanded input array W, where the first 16 are copies of the input - data, and the remaining 64 are defined by - - W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] - - This implementation generates these values on the fly in a circular - buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this - optimization. - - The updated SHS changes the expanding function by adding a rotate of 1 - bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor - for this information */ - -#ifdef NEW_SHS -#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ - W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ))) -#else -#define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \ - W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) -#endif /* NEW_SHS */ - -/* The prototype SHS sub-round. The fundamental sub-round is: - - a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; - b' = a; - c' = ROTL( 30, b ); - d' = c; - e' = d; - - but this is implemented by unrolling the loop 5 times and renaming the - variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. - This code is then replicated 20 times for each of the 4 functions, using - the next 20 values from the W[] array each time */ - -#define subRound(a, b, c, d, e, f, k, data) \ - ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, \ - e &= 0xffffffff, b = ROTL( 30, b ) ) - -/* Initialize the SHS values */ - -void shsInit(shsInfo) - SHS_INFO *shsInfo; -{ - /* Set the h-vars to their initial values */ - shsInfo->digest[ 0 ] = h0init; - shsInfo->digest[ 1 ] = h1init; - shsInfo->digest[ 2 ] = h2init; - shsInfo->digest[ 3 ] = h3init; - shsInfo->digest[ 4 ] = h4init; - - /* Initialise bit count */ - shsInfo->countLo = shsInfo->countHi = 0; -} - -/* Perform the SHS transformation. Note that this code, like MD5, seems to - break some optimizing compilers due to the complexity of the expressions - and the size of the basic block. It may be necessary to split it into - sections, e.g. based on the four subrounds - - Note that this corrupts the shsInfo->data area */ - -static void SHSTransform KRB5_PROTOTYPE((LONG *digest, LONG *data)); - -static -void SHSTransform(digest, data) - LONG *digest; - LONG *data; -{ - LONG A, B, C, D, E; /* Local vars */ - LONG eData[ 16 ]; /* Expanded data */ - - /* Set up first buffer and local data buffer */ - A = digest[ 0 ]; - B = digest[ 1 ]; - C = digest[ 2 ]; - D = digest[ 3 ]; - E = digest[ 4 ]; - memcpy(eData, data, sizeof (eData)); - - /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ - subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); - subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); - subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); - subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); - subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); - - subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); - - subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); - - subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); - - /* Build message digest */ - digest[ 0 ] += A; - digest[ 0 ] &= 0xffffffff; - digest[ 1 ] += B; - digest[ 1 ] &= 0xffffffff; - digest[ 2 ] += C; - digest[ 2 ] &= 0xffffffff; - digest[ 3 ] += D; - digest[ 3 ] &= 0xffffffff; - digest[ 4 ] += E; - digest[ 4 ] &= 0xffffffff; -} - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. It is possible to make the code endianness- - independant by fiddling around with data at the byte level, but this - makes for very slow code, so we rely on the user to sort out endianness - at compile time */ - -void longReverse( LONG *buffer, int byteCount ) -{ - LONG value; - static int init = 0; - char *cp; - - switch (init) { - case 0: - init=1; - cp = (char *) &init; - if (*cp == 1) { - init=2; - break; - } - init=1; - /* fall through - MSB */ - case 1: - return; - } - - byteCount /= sizeof( LONG ); - while( byteCount-- ) { - value = *buffer; - value = ( ( value & 0xFF00FF00L ) >> 8 ) | - ( ( value & 0x00FF00FFL ) << 8 ); - *buffer++ = ( value << 16 ) | ( value >> 16 ); - } -} - -/* Update SHS for a block of data */ - -void shsUpdate(shsInfo, buffer, count) - SHS_INFO *shsInfo; - BYTE *buffer; - int count; -{ - LONG tmp; - int dataCount, canfill; - LONG *lp; - - /* Update bitcount */ - tmp = shsInfo->countLo; - shsInfo->countLo = tmp + (((LONG) count) << 3 ); - if ((shsInfo->countLo &= 0xffffffff) < tmp) - shsInfo->countHi++; /* Carry from low to high */ - shsInfo->countHi += count >> 29; - - /* Get count of bytes already in data */ - dataCount = (int) (tmp >> 3) & 0x3F; - - /* Handle any leading odd-sized chunks */ - if (dataCount) { - lp = shsInfo->data + dataCount / 4; - canfill = (count >= dataCount); - dataCount = SHS_DATASIZE - dataCount; - - if (dataCount % 4) { - /* Fill out a full 32 bit word first if needed -- this - is not very efficient (computed shift amount), - but it shouldn't happen often. */ - while (dataCount % 4 && count > 0) { - *lp |= (LONG) *buffer++ << ((3 - dataCount++ % 4) * 8); - count--; - } - lp++; - } - while (lp < shsInfo->data + 16) { - *lp = (LONG) *buffer++ << 24; - *lp |= (LONG) *buffer++ << 16; - *lp |= (LONG) *buffer++ << 8; - *lp++ |= (LONG) *buffer++; - if ((count -= 4) < 4 && lp < shsInfo->data + 16) { - *lp = 0; - switch (count % 4) { - case 3: - *lp |= (LONG) buffer[2] << 8; - case 2: - *lp |= (LONG) buffer[1] << 16; - case 1: - *lp |= (LONG) buffer[0] << 24; - } - break; - count = 0; - } - } - if (canfill) { - SHSTransform(shsInfo->digest, shsInfo->data); - } - } - - /* Process data in SHS_DATASIZE chunks */ - while (count >= SHS_DATASIZE) { - lp = shsInfo->data; - while (lp < shsInfo->data + 16) { - *lp = ((LONG) *buffer++) << 24; - *lp |= ((LONG) *buffer++) << 16; - *lp |= ((LONG) *buffer++) << 8; - *lp++ |= (LONG) *buffer++; - } - SHSTransform(shsInfo->digest, shsInfo->data); - count -= SHS_DATASIZE; - } - - if (count > 0) { - lp = shsInfo->data; - while (count > 4) { - *lp = ((LONG) *buffer++) << 24; - *lp |= ((LONG) *buffer++) << 16; - *lp |= ((LONG) *buffer++) << 8; - *lp++ |= (LONG) *buffer++; - count -= 4; - } - *lp = 0; - switch (count % 4) { - case 0: - *lp |= ((LONG) buffer[3]); - case 3: - *lp |= ((LONG) buffer[2]) << 8; - case 2: - *lp |= ((LONG) buffer[1]) << 16; - case 1: - *lp |= ((LONG) buffer[0]) << 24; - } - } -} - -/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern - 1 0* (64-bit count of bits processed, MSB-first) */ - -void shsFinal(shsInfo) - SHS_INFO *shsInfo; -{ - int count; - LONG *lp; - BYTE *dataPtr; - - /* Compute number of bytes mod 64 */ - count = (int) shsInfo->countLo; - count = (count >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - lp = shsInfo->data + count / 4; - switch (count % 4) { - case 3: - *lp++ |= (LONG) 0x80; - break; - case 2: - *lp++ |= (LONG) 0x80 << 8; - break; - case 1: - *lp++ |= (LONG) 0x80 << 16; - break; - case 0: - *lp++ = (LONG) 0x80 << 24; - } - - if (lp > shsInfo->data + 14) { - /* Pad out to 64 bytes if not enough room for length words */ - *lp = 0; - SHSTransform(shsInfo->digest, shsInfo->data); - lp = shsInfo->data; - } - /* Pad out to 56 bytes */ - while (lp < shsInfo->data + 14) - *lp++ = 0; - /* Append length in bits and transform */ - *lp++ = shsInfo->countHi; - *lp++ = shsInfo->countLo; - SHSTransform(shsInfo->digest, shsInfo->data); -} diff --git a/src/lib/crypto/sha/shs.h b/src/lib/crypto/sha/shs.h deleted file mode 100644 index 01acddb82..000000000 --- a/src/lib/crypto/sha/shs.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _SHS_DEFINED - -#include - -#define _SHS_DEFINED - -/* Some useful types */ - -typedef krb5_octet BYTE; - -/* Old DOS/Windows compilers are case-insensitive */ -#if !defined(_MSDOS) && !defined(_WIN32) -typedef krb5_ui_4 LONG; -#endif - - -/* Define the following to use the updated SHS implementation */ -#define NEW_SHS /**/ - -/* The SHS block size and message digest sizes, in bytes */ - -#define SHS_DATASIZE 64 -#define SHS_DIGESTSIZE 20 - -/* The structure for storing SHS info */ - -typedef struct { - LONG digest[ 5 ]; /* Message digest */ - LONG countLo, countHi; /* 64-bit bit count */ - LONG data[ 16 ]; /* SHS data buffer */ - } SHS_INFO; - -/* Message digest functions (shs.c) */ -void shsInit - KRB5_PROTOTYPE((SHS_INFO *shsInfo)); -void shsUpdate - KRB5_PROTOTYPE((SHS_INFO *shsInfo, BYTE *buffer, int count)); -void shsFinal - KRB5_PROTOTYPE((SHS_INFO *shsInfo)); - - -/* Keyed Message digest functions (hmac_sha.c) */ -krb5_error_code hmac_sha - KRB5_PROTOTYPE((krb5_octet *text, - int text_len, - krb5_octet *key, - int key_len, - krb5_octet *digest)); - - -#define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE -#define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE - - -extern krb5_checksum_entry - nist_sha_cksumtable_entry, - hmac_sha_cksumtable_entry; - -#endif /* _SHS_DEFINED */ diff --git a/src/lib/crypto/sha/t_shs.c b/src/lib/crypto/sha/t_shs.c deleted file mode 100644 index da55992ec..000000000 --- a/src/lib/crypto/sha/t_shs.c +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -* * -* SHS Test Code * -* * -****************************************************************************/ - -#include -#include -#include -#include "shs.h" - -/* Test the SHS implementation */ - -#ifdef NEW_SHS - -static LONG shsTestResults[][ 5 ] = { - { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, }, - { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, }, - { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, } - }; - -#else - -static LONG shsTestResults[][ 5 ] = { - { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L }, - { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L }, - { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L } - }; -#endif /* NEW_SHS */ - -static int compareSHSresults(shsInfo, shsTestLevel) -SHS_INFO *shsInfo; -int shsTestLevel; -{ - int i, fail = 0; - - /* Compare the returned digest and required values */ - for( i = 0; i < 5; i++ ) - if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] ) - fail = 1; - if (fail) { - printf("\nExpected: "); - for (i = 0; i < 5; i++) { - printf("%8.8lx ", shsTestResults[shsTestLevel][i]); - } - printf("\nGot: "); - for (i = 0; i < 5; i++) { - printf("%8.8lx ", shsInfo->digest[i]); - } - printf("\n"); - return( -1 ); - } - return( 0 ); -} - -main() -{ - SHS_INFO shsInfo; - unsigned int i; - time_t secondCount; - BYTE data[ 200 ]; - - /* Make sure we've got the endianness set right. If the machine is - big-endian (up to 64 bits) the following value will be signed, - otherwise it will be unsigned. Unfortunately we can't test for odd - things like middle-endianness without knowing the size of the data - types */ - - /* Test SHS against values given in SHS standards document */ - printf( "Running SHS test 1 ... " ); - shsInit( &shsInfo ); - shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 0 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 1 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" ); -#else - puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" ); -#endif /* NEW_SHS */ - - printf( "Running SHS test 2 ... " ); - shsInit( &shsInfo ); - shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 1 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 2 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" ); -#else - puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" ); -#endif /* NEW_SHS */ - - printf( "Running SHS test 3 ... " ); - shsInit( &shsInfo ); - for( i = 0; i < 15625; i++ ) - shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 2 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 3 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" ); -#else - puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" ); -#endif /* NEW_SHS */ - -#if 0 - printf( "\nTesting speed for 100MB data... " ); - shsInit( &shsInfo ); - secondCount = time( NULL ); - for( i = 0; i < 500000U; i++ ) - shsUpdate( &shsInfo, data, 200 ); - secondCount = time( NULL ) - secondCount; - printf( "done. Time = %ld seconds, %ld kbytes/second.\n", \ - secondCount, 100500L / secondCount ); -#endif - - puts( "\nAll SHS tests passed" ); - exit( 0 ); -} diff --git a/src/lib/crypto/string_to_cksumtype.c b/src/lib/crypto/string_to_cksumtype.c new file mode 100644 index 000000000..fe46e8a9b --- /dev/null +++ b/src/lib/crypto/string_to_cksumtype.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_string_to_cksumtype(string, cksumtypep) + char FAR * string; + krb5_cksumtype FAR * cksumtypep; +{ + int i; + + for (i=0; ikeysize))(&keybytes, &keylength); + + if ((key->contents = (krb5_octet *) malloc(keylength)) == NULL) + return(ENOMEM); + + key->magic = KV5M_KEYBLOCK; + key->enctype = enctype; + key->length = keylength; + + if (ret = ((*(krb5_enctypes_list[i].str2key))(enc, string, salt, key))) { + memset(key->contents, 0, keylength); + free(key->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/t_nfold.c b/src/lib/crypto/t_nfold.c new file mode 100644 index 000000000..2693318e1 --- /dev/null +++ b/src/lib/crypto/t_nfold.c @@ -0,0 +1,76 @@ +/* + * lib/crypto/t_nfold.c + * + * Copyright 1988, 1990 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * + * Program to test the correctness of nfold implementation. + * + * exit returns 0 ==> success + * -1 ==> error + */ + +#include +#include + +#include "k5-int.h" + +unsigned char *nfold_in[] = { + "basch", + "eichin", + "sommerfeld", + "MASSACHVSETTS INSTITVTE OF TECHNOLOGY" }; + +unsigned char nfold_192[4][24] = { + { 0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde, 0x2d, + 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31, 0x64, 0x3f }, + { 0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b, 0x1b, 0x43, + 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0, 0xd2, 0xdc, 0xca }, + { 0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4, 0xe7, 0x11, + 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5, 0xde, 0xf7, 0x5c }, + { 0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82, 0xb3, 0x08, + 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9, 0x54, 0x0c, 0x1b } +}; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + unsigned char cipher_text[64]; + int i, j; + + printf("N-fold\n"); + for (i=0; ichecksum_type) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + /* if there's actually a verify function, call it */ + + indata.length = cksum->length; + indata.data = cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash && + krb5_cksumtypes_list[i].keyhash->verify) + return((*(krb5_cksumtypes_list[i].keyhash->verify))(key, 0, data, + &indata, valid)); + + /* otherwise, make the checksum again, and compare */ + + if (ret = krb5_c_checksum_length(context, cksum->checksum_type, &hashsize)) + return(ret); + + if (cksum->length != hashsize) + return(KRB5_BAD_MSIZE); + + computed.length = hashsize; + + if (ret = krb5_c_make_checksum(context, cksum->checksum_type, key, usage, + data, &computed)) { + free(computed.contents); + return(ret); + } + + *valid = (memcmp(computed.contents, cksum->contents, hashsize) == 0); + + free(computed.contents); + + return(0); +} diff --git a/src/lib/des425/ChangeLog b/src/lib/des425/ChangeLog index ce04691e9..4eeef1028 100644 --- a/src/lib/des425/ChangeLog +++ b/src/lib/des425/ChangeLog @@ -1,6 +1,12 @@ +1998-10-27 Marc Horowitz + + * random_key.c, new_rnd_key.c: make the v4 compat random key code + use the krb5 crypto interface, instead of the des implementation + internals. + Wed Apr 15 18:03:43 1998 Tom Yu - * Makefile.in (SHLIB_EXPDEPS): + * Makefile.in (SHLIB_EXPDEPS): (SHLIB_EXPLIBS): Rename libcrypto -> libk5crypto. Tue Mar 3 08:59:03 1998 Ezra Peisach diff --git a/src/lib/des425/Makefile.in b/src/lib/des425/Makefile.in index 541a516e6..e96e03f99 100644 --- a/src/lib/des425/Makefile.in +++ b/src/lib/des425/Makefile.in @@ -14,7 +14,7 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP=@KRB5_RUN_ENV@ LIB=des425 -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 RELDIR=des425 # Depends on libk5crypto and libkrb5 @@ -27,7 +27,6 @@ SHLIB_RDIRS=$(KRB5_LIBDIR) STOBJLISTS=OBJS.ST STLIBOBJS=cksum.o \ - des.o \ enc_dec.o \ key_parity.o \ key_sched.o \ @@ -44,7 +43,6 @@ STLIBOBJS=cksum.o \ OBJS= cksum.$(OBJEXT) \ - des.$(OBJEXT) \ enc_dec.$(OBJEXT) \ key_parity.$(OBJEXT) \ key_sched.$(OBJEXT) \ @@ -60,7 +58,6 @@ OBJS= cksum.$(OBJEXT) \ k4_glue.$(OBJEXT) SRCS= $(srcdir)/cksum.c \ - $(srcdir)/des.c \ $(srcdir)/enc_dec.c \ $(srcdir)/key_parity.c \ $(srcdir)/key_sched.c \ diff --git a/src/lib/des425/new_rnd_key.c b/src/lib/des425/new_rnd_key.c index 943b9e03b..4dd2e4be7 100644 --- a/src/lib/des425/new_rnd_key.c +++ b/src/lib/des425/new_rnd_key.c @@ -23,35 +23,34 @@ * */ - -#include "des.h" - -krb5_pointer des425_random_state = 0; - /* - * des_new_random_key: create a random des key - * - * Requires: des_set_random_number_generater_seed must be at called least - * once before this routine is called. - * - * Notes: the returned key has correct parity and is guarenteed not - * to be a weak des key. Des_generate_random_block is used to - * provide the random bits. + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. */ -KRB5_DLLIMP int KRB5_CALLCONV -des_new_random_key(key) - mit_des_cblock key; -{ - krb5_keyblock * keyblock; - krb5_error_code kret; - kret = mit_des_random_key(NULL, des425_random_state, &keyblock); - if (kret) return kret; - - memcpy(key, keyblock->contents, sizeof(mit_des_cblock)); - krb5_free_keyblock(NULL, keyblock); - return 0; -} + +#include "des.h" /* * des_init_random_number_generator: @@ -71,67 +70,38 @@ void des_init_random_number_generator(key) mit_des_cblock key; { - krb5_keyblock keyblock; - krb5_encrypt_block eblock; - - krb5_use_enctype(NULL, &eblock, ENCTYPE_DES_CBC_CRC); + krb5_data seed; - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *)key; + seed.length = sizeof(key); + seed.data = key; - if (des425_random_state) - mit_des_finish_random_key(&eblock, &des425_random_state); - mit_des_init_random_key(&eblock, &keyblock, &des425_random_state); + if (krb5_c_random_seed(/* XXX */ 0, &seed)) + /* XXX */ abort(); } /* - * This module implements a random number generator faculty such that the next - * number in any random number stream is very hard to predict without knowing - * the seed for that stream even given the preceeding random numbers. - */ - -/* - * des_set_random_generator_seed: this routine is used to select a random - * number stream. The stream that results is - * totally determined by the passed in key. - * (I.e., calling this routine again with the - * same key allows repeating a sequence of - * random numbers) + * des_new_random_key: create a random des key + * + * Requires: des_set_random_number_generater_seed must be at called least + * once before this routine is called. * - * Requires: key is a valid des key. I.e., has correct parity and is not a - * weak des key. + * Notes: the returned key has correct parity and is guarenteed not + * to be a weak des key. Des_generate_random_block is used to + * provide the random bits. */ -KRB5_DLLIMP void KRB5_CALLCONV -des_set_random_generator_seed(key) +KRB5_DLLIMP int KRB5_CALLCONV +des_new_random_key(key) mit_des_cblock key; { - krb5_data seed; + krb5_keyblock keyblock; + krb5_error_code kret; - seed.length = sizeof(mit_des_cblock); - seed.data = (krb5_pointer) key; + kret = krb5_c_make_random_key(/* XXX */ 0, ENCTYPE_DES_CBC_CRC, &keyblock); + if (kret) return kret; + + memcpy(key, keyblock.contents, sizeof(mit_des_cblock)); + krb5_free_keyblock_contents(/* XXX */ 0, &keyblock); - if (!des425_random_state) - des_init_random_number_generator(key); - mit_des_set_random_generator_seed(&seed, des425_random_state); + return 0; } - -/* - * des_set_sequence_number: this routine is used to set the sequence number - * of the current random number stream. This routine - * may be used to "seek" within the current random - * number stream. - * - * Note that des_set_random_generator_seed resets the sequence number to 0. - */ -void -des_set_sequence_number(new_sequence_number) - mit_des_cblock new_sequence_number; -{ - krb5_data sequence; - - sequence.length = sizeof(new_sequence_number); - sequence.data = (char FAR *)new_sequence_number; - mit_des_set_random_sequence_number(&sequence, des425_random_state); -} diff --git a/src/lib/des425/random_key.c b/src/lib/des425/random_key.c index 04399c1f0..fde324dec 100644 --- a/src/lib/des425/random_key.c +++ b/src/lib/des425/random_key.c @@ -23,39 +23,48 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ #include "des.h" -extern krb5_pointer des425_random_state; - /* random_key */ int des_random_key(key) mit_des_cblock *key; { - krb5_encrypt_block eblock; krb5_keyblock keyblock; - krb5_keyblock *new_key; krb5_error_code kret; - mit_des_cblock nullkey; - - krb5_use_enctype(NULL, &eblock, ENCTYPE_DES_CBC_CRC); - - memset(nullkey, 0, sizeof(mit_des_cblock)); - mit_des_fixup_key_parity(*key); - - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *)nullkey; - if (! des425_random_state) - mit_des_init_random_key(&eblock, &keyblock, &des425_random_state); + if (kret = krb5_c_make_random_key(/* XXX */ 0, ENCTYPE_DES_CBC_CRC, + &keyblock)) + return(kret); - kret = mit_des_random_key(NULL, des425_random_state, &new_key); - if (kret) return kret; + memcpy(key, keyblock.contents, sizeof(mit_des_cblock)); - memcpy(key, new_key->contents, sizeof(mit_des_cblock)); - krb5_free_keyblock(NULL, new_key); return(0); } diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in index 6835596f7..843207133 100644 --- a/src/lib/gssapi/Makefile.in +++ b/src/lib/gssapi/Makefile.in @@ -9,7 +9,7 @@ LOCAL_SUBDIRS= generic krb5 MAC_SUBDIRS = generic krb5 LIB=gssapi_krb5 -LIBMAJOR=1 +LIBMAJOR=2 LIBMINOR=1 STOBJLISTS=generic/OBJS.ST krb5/OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog index 74f13a4a3..601ca76f6 100644 --- a/src/lib/gssapi/generic/ChangeLog +++ b/src/lib/gssapi/generic/ChangeLog @@ -1,3 +1,8 @@ +1998-10-27 Marc Horowitz + + * gssapi.hin: define GSS_S_DUPLICATE_ELEMENT, GSS_S_NAME_NOT_MN, + and GSS_S_GAP_TOKEN as per gss v2 c bindings + 1998-06-08 Theodore Ts'o * oid_ops.c (generic_gss_release_oid): Recognize our own "self" diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin index d00e19ab9..a30b79431 100644 --- a/src/lib/gssapi/generic/gssapi.hin +++ b/src/lib/gssapi/generic/gssapi.hin @@ -307,11 +307,10 @@ typedef int gss_cred_usage_t; #define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET) #define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET) #define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET) -/* - * XXX new functions. Check to get official error number assigments? - */ #define GSS_S_DUPLICATE_ELEMENT \ (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NAME_NOT_MN \ + (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET) /* * Supplementary info bits: @@ -320,9 +319,6 @@ typedef int gss_cred_usage_t; #define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) #define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) #define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) -/* - * XXX not in the cbindings yet. remove this comment when it is - */ #define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) diff --git a/src/lib/gssapi/generic/gssapi_err_generic.et b/src/lib/gssapi/generic/gssapi_err_generic.et index ddeed4227..99ba45fe3 100644 --- a/src/lib/gssapi/generic/gssapi_err_generic.et +++ b/src/lib/gssapi/generic/gssapi_err_generic.et @@ -40,4 +40,7 @@ error_code G_BAD_HOSTNAME, "Hostname in SERVICE-NAME string could not be canonic error_code G_WRONG_MECH, "Mechanism is incorrect" error_code G_BAD_TOK_HEADER, "Token header is malformed or corrupt" error_code G_BAD_DIRECTION, "Packet was replayed in wrong direction" +error_code G_TOK_TRUNC, "Token is missing data" +error_code G_REFLECT, "Token was reflected" +error_code G_WRONG_TOKID, "Received token ID does not match expected token ID" end diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c index 627b5011b..9e186a153 100644 --- a/src/lib/gssapi/generic/util_token.c +++ b/src/lib/gssapi/generic/util_token.c @@ -205,9 +205,12 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize) if ((toksize-=2) < 0) return(G_BAD_TOK_HEADER); + if (ret) + return(ret); + if ((*buf++ != ((tok_type>>8)&0xff)) || - (*buf++ != (tok_type&0xff))) - return(G_BAD_TOK_HEADER); + (*buf++ != (tok_type&0xff))) + return(G_WRONG_TOKID); if (!ret) { *buf_in = buf; diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index a94aeb72d..e12dfdb2b 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,42 @@ +1998-10-27 Marc Horowitz + + * Makefile.in, accept_sec_context.c, acquire_cred.c, canon_name.c, + delete_sec_context.c, disp_status.c, gssapiP_krb5.h, + gssapi_err_krb5.et, gssapi_krb5.c, gssapi_krb5.h, + init_sec_context.c, inq_cred.c, inq_names.c, k5seal.c, k5unseal.c, + rel_oid.c, ser_sctx.c, util_cksum.c, util_crypt.c, util_seed.c, + util_seqnum.c, wrap_size_limit.c: convert to new crypto api. + Implement new krb5 v2 gssapi mechanism. + + * add_cred.c, util_ctxsetup.c: New files needed to implement the + krb5 v2 mech. + +Mon Sep 21 00:32:28 1998 Tom Yu + + * accept_sec_context.c (krb5_gss_accept_sec_context): Free authdat + even on success to avoid a memory leak. + + * util_cksum.c (kg_checksum_channel_bindings): Fix memory leak by + not allocating cksum->contents unless we have to return a + zero-filled one. + + * k5unseal.c (kg_unseal_v1): Fix memorly leak by not allocating + md5cksum.contents. + + * k5seal.c (make_seal_token_v1): Fix memory leak by not allocating + md5cksum.contents. + + * accept_sec_context.c (krb5_gss_accept_sec_context): Only free + ap_req.data if it was allocated by kg2_parse_token(), otherwise we + lose very badly trying to free the middle of a potentially + malloc()'ed block, possibly coredumping. + +Thu Sep 3 19:35:44 1998 Tom Yu + + * accept_sec_context.c (krb5_gss_accept_sec_context): Fix typo; + bash the enctype in ctx->subkey->enctype rather than just + "enctype", which nothing checks. + Fri Jul 24 21:13:53 1998 Tom Yu * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix to round down diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in index 5b74b81d9..00b575c34 100644 --- a/src/lib/gssapi/krb5/Makefile.in +++ b/src/lib/gssapi/krb5/Makefile.in @@ -18,6 +18,7 @@ gssapi_err_krb5.c: gssapi_err_krb5.et SRCS = \ $(srcdir)/accept_sec_context.c \ $(srcdir)/acquire_cred.c \ + $(srcdir)/add_cred.c \ $(srcdir)/canon_name.c \ $(srcdir)/compare_name.c \ $(srcdir)/context_time.c \ @@ -50,6 +51,7 @@ SRCS = \ $(srcdir)/unseal.c \ $(srcdir)/util_cksum.c \ $(srcdir)/util_crypt.c \ + $(srcdir)/util_ctxsetup.c \ $(srcdir)/util_seed.c \ $(srcdir)/util_seqnum.c \ $(srcdir)/val_cred.c \ @@ -63,6 +65,7 @@ SRCS = \ OBJS = \ accept_sec_context.$(OBJEXT) \ acquire_cred.$(OBJEXT) \ + add_cred.$(OBJEXT) \ canon_name.$(OBJEXT) \ compare_name.$(OBJEXT) \ context_time.$(OBJEXT) \ @@ -95,6 +98,7 @@ OBJS = \ unseal.$(OBJEXT) \ util_cksum.$(OBJEXT) \ util_crypt.$(OBJEXT) \ + util_ctxsetup.$(OBJEXT) \ util_seed.$(OBJEXT) \ util_seqnum.$(OBJEXT) \ val_cred.$(OBJEXT) \ @@ -108,6 +112,7 @@ OBJS = \ STLIBOBJS = \ accept_sec_context.o \ acquire_cred.o \ + add_cred.o \ canon_name.o \ compare_name.o \ context_time.o \ @@ -140,6 +145,7 @@ STLIBOBJS = \ unseal.o \ util_cksum.o \ util_crypt.o \ + util_ctxsetup.o \ util_seed.o \ util_seqnum.o \ val_cred.o \ diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index ee204d3e0..90e988ae0 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "gssapiP_krb5.h" #include @@ -58,9 +84,8 @@ rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, /* Decode, decrypt and store the forwarded creds in the local ccache. */ static krb5_error_code -rd_and_store_for_creds(context, auth_context, inbuf, out_cred) +rd_and_store_for_creds(context, inbuf, out_cred) krb5_context context; - krb5_auth_context auth_context; krb5_data *inbuf; krb5_gss_cred_id_t *out_cred; { @@ -69,10 +94,16 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred) krb5_ccache ccache; krb5_gss_cred_id_t cred = NULL; extern krb5_cc_ops krb5_mcc_ops; + krb5_auth_context auth_context = NULL; - if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) + if ((retval = krb5_auth_con_init(context, &auth_context))) return(retval); + krb5_auth_con_setflags(context, auth_context, 0); + + if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) + goto cleanup; + /* Lots of kludging going on here... Some day the ccache interface will be rewritten though */ @@ -91,47 +122,51 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred) /* generate a delegated credential handle */ if (out_cred) { - /* allocate memory for a cred_t... */ - if (!(cred = - (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) { - retval = ENOMEM; /* out of memory? */ - goto cleanup; - } + /* allocate memory for a cred_t... */ + if (!(cred = + (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) { + retval = ENOMEM; /* out of memory? */ + goto cleanup; + } - /* zero it out... */ - memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); + /* zero it out... */ + memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); - /* copy the client principle into it... */ - if ((retval = - krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) { - retval = ENOMEM; /* out of memory? */ - xfree(cred); /* clean up memory on failure */ - cred = NULL; - goto cleanup; - } - - cred->usage = GSS_C_INITIATE; /* we can't accept with this */ - /* cred->princ already set */ - cred->actual_mechs = gss_mech_set_krb5_both; /* both mechs work */ - cred->prerfc_mech = cred->rfc_mech = 1; /* Ibid. */ - cred->keytab = NULL; /* no keytab associated with this... */ - cred->ccache = ccache; /* but there is a credential cache */ - cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ + /* copy the client principle into it... */ + if ((retval = + krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) { + retval = ENOMEM; /* out of memory? */ + xfree(cred); /* clean up memory on failure */ + cred = NULL; + goto cleanup; + } + + cred->usage = GSS_C_INITIATE; /* we can't accept with this */ + /* cred->princ already set */ + cred->prerfc_mech = 1; /* this cred will work with all three mechs */ + cred->rfc_mech = 1; + cred->rfcv2_mech = 1; + cred->keytab = NULL; /* no keytab associated with this... */ + cred->ccache = ccache; /* but there is a credential cache */ + cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ } /* If there were errors, there might have been a memory leak - if (!cred) - if ((retval = krb5_cc_close(context, ccache))) - goto cleanup; - */ + if (!cred) + if ((retval = krb5_cc_close(context, ccache))) + goto cleanup; + */ cleanup: krb5_free_tgt_creds(context, creds); if (!cred && ccache) - (void)krb5_cc_close(context, ccache); + (void)krb5_cc_close(context, ccache); if (out_cred) - *out_cred = cred; /* return credential */ + *out_cred = cred; /* return credential */ + + if (auth_context) + krb5_auth_con_free(context, auth_context); return retval; } @@ -158,16 +193,17 @@ krb5_gss_accept_sec_context(minor_status, context_handle, unsigned char *ptr, *ptr2; char *sptr; long tmp; + size_t md5len; int bigend; krb5_gss_cred_id_t cred = 0; - krb5_data ap_req; + krb5_data ap_rep, ap_req, mic; int i; krb5_error_code code; krb5_address addr, *paddr; krb5_authenticator *authdat = 0; - krb5_checksum md5; + krb5_checksum reqcksum; krb5_principal name = NULL; - int gss_flags = 0; + krb5_ui_4 gss_flags = 0; int decode_req_message = 0; krb5_gss_ctx_id_rec *ctx = 0; krb5_enctype enctype; @@ -177,14 +213,18 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; int option_id; - krb5_data option; - krb5_auth_context auth_context_cred = NULL; + krb5_data option, cksumdata; const gss_OID_desc *mech_used = NULL; OM_uint32 major_status = GSS_S_FAILURE; krb5_error krb_error_data; krb5_data scratch; gss_cred_id_t cred_handle = NULL; krb5_gss_cred_id_t deleg_cred = NULL; + int token_length; + int gsskrb5_vers; + int nctypes; + krb5_cksumtype *ctypes; + struct kg2_option fwcred; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -196,7 +236,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle, output_token->length = 0; output_token->value = NULL; token.value = 0; - md5.contents = 0; + reqcksum.contents = 0; + mic.data = 0; + ap_req.data = 0; + ap_rep.data = 0; + cksumdata.data = 0; if (mech_type) *mech_type = GSS_C_NULL_OID; @@ -217,18 +261,19 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* handle default cred handle */ if (verifier_cred_handle == GSS_C_NO_CREDENTIAL) { - major_status = krb5_gss_acquire_cred(&code, GSS_C_NO_NAME, - GSS_C_INDEFINITE, GSS_C_NO_OID_SET, - GSS_C_ACCEPT, &cred_handle, - NULL, NULL); - if (major_status != GSS_S_COMPLETE) - goto fail; - } else - cred_handle = verifier_cred_handle; + major_status = krb5_gss_acquire_cred(&code, GSS_C_NO_NAME, + GSS_C_INDEFINITE, GSS_C_NO_OID_SET, + GSS_C_ACCEPT, &cred_handle, + NULL, NULL); + if (major_status != GSS_S_COMPLETE) + goto fail; + } else { + cred_handle = verifier_cred_handle; + } - major_status = krb5_gss_validate_cred(minor_status, verifier_cred_handle); + major_status = krb5_gss_validate_cred(&code, verifier_cred_handle); if (GSS_ERROR(major_status)) - goto fail; + goto fail; cred = (krb5_gss_cred_id_t) cred_handle; @@ -236,9 +281,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if ((cred->usage != GSS_C_ACCEPT) && (cred->usage != GSS_C_BOTH)) { - code = 0; - major_status = GSS_S_NO_CRED; - goto fail; + code = 0; + major_status = GSS_S_NO_CRED; + goto fail; } /* verify the token's integrity, and leave the token in ap_req. @@ -246,60 +291,92 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ptr = (unsigned char *) input_token->value; - if ((err = g_verify_token_header((gss_OID) gss_mech_krb5, &(ap_req.length), - &ptr, KG_TOK_CTX_AP_REQ, - input_token->length))) { - /* - * Previous versions of this library used the old mech_id - * and some broken behavior (wrong IV on checksum - * encryption). We support the old mech_id for - * compatibility, and use it to decide when to use the - * old behavior. - */ - if (err != G_WRONG_MECH || - (code = g_verify_token_header((gss_OID) gss_mech_krb5_old, - &(ap_req.length), - &ptr, KG_TOK_CTX_AP_REQ, - input_token->length))) { - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } else { -#if 0 /* Don't restrict mechanisms when accepting contexts */ - if (! cred->prerfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } -#endif - mech_used = gss_mech_krb5_old; - } + if (!(code = g_verify_token_header((gss_OID) gss_mech_krb5, + &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length))) { + if (! cred->rfc_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5; + gsskrb5_vers = 1000; + } else if ((code == G_WRONG_MECH) && + !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old, + &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length))) { + /* + * Previous versions of this library used the old mech_id + * and some broken behavior (wrong IV on checksum + * encryption). We support the old mech_id for + * compatibility, and use it to decide when to use the + * old behavior. + */ + if (! cred->prerfc_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5_old; + gsskrb5_vers = 1000; + } else if ((code == G_WRONG_MECH) && + !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2, + &token_length, + &ptr, KG2_TOK_INITIAL, + input_token->length))) { + if (! cred->rfcv2_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5_v2; + gsskrb5_vers = 2000; } else { -#if 0 /* Don't restrict mechanisms when accepting contexts */ - if (! cred->rfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } -#endif - mech_used = gss_mech_krb5; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; } - sptr = (char *) ptr; - TREAD_STR(sptr, ap_req.data, ap_req.length); - decode_req_message = 1; + if (gsskrb5_vers == 2000) { + /* gss krb5 v2 */ + + fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION; + fwcred.data = NULL; + + if (GSS_ERROR(major_status = + kg2_parse_token(&code, ptr, token_length, + &gss_flags, &nctypes, &ctypes, + delegated_cred_handle?1:0, + &fwcred, &ap_req, NULL))) { + goto fail; + } + + gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; + + gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; + if there's a delegation, we'll + set it below */ + } else { + /* gss krb5 v1 */ + + sptr = (char *) ptr; + TREAD_STR(sptr, ap_req.data, ap_req.length); + decode_req_message = 1; + } /* construct the sender_addr */ if ((input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) && (input_chan_bindings->initiator_addrtype == GSS_C_AF_INET)) { - /* XXX is this right? */ - addr.addrtype = ADDRTYPE_INET; - addr.length = input_chan_bindings->initiator_address.length; - addr.contents = input_chan_bindings->initiator_address.value; + /* XXX is this right? */ + addr.addrtype = ADDRTYPE_INET; + addr.length = input_chan_bindings->initiator_address.length; + addr.contents = input_chan_bindings->initiator_address.value; - paddr = &addr; + paddr = &addr; } else { - paddr = NULL; + paddr = NULL; } /* decode the AP_REQ message */ @@ -307,13 +384,18 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* decode the message */ if ((code = krb5_auth_con_init(context, &auth_context))) { - *minor_status = code; - return(GSS_S_FAILURE); + major_status = GSS_S_FAILURE; + goto fail; } if ((code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) { - *minor_status = code; - return(GSS_S_FAILURE); + major_status = GSS_S_FAILURE; + goto fail; } + if ((code = krb5_auth_con_setaddrs(context, auth_context, NULL, paddr))) { + major_status = GSS_S_FAILURE; + goto fail; + } + if ((code = krb5_rd_req(context, &auth_context, &ap_req, cred->princ, cred->keytab, NULL, &ticket))) { major_status = GSS_S_FAILURE; @@ -328,137 +410,142 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if ((authdat->authenticator->subkey == NULL) || (authdat->ticket->enc_part2 == NULL)) { code = KG_NO_SUBKEY; + major_status = GSS_S_FAILURE; goto fail; } #endif - /* verify that the checksum is correct */ + if (gsskrb5_vers == 2000) { + bigend = 1; + } else { + /* gss krb5 v1 */ - /* - The checksum may be either exactly 24 bytes, in which case - no options are specified, or greater than 24 bytes, in which case - one or more options are specified. Currently, the only valid - option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ). - */ - - if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) || - (authdat->checksum->length < 24)) { - code = 0; - major_status = GSS_S_BAD_BINDINGS; + /* stash this now, for later. */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, + &md5len)) { + major_status = GSS_S_FAILURE; goto fail; - } + } - /* - "Be liberal in what you accept, and - conservative in what you send" - -- rfc1123 + /* verify that the checksum is correct */ - This code will let this acceptor interoperate with an initiator - using little-endian or big-endian integer encoding. - */ + /* + The checksum may be either exactly 24 bytes, in which case + no options are specified, or greater than 24 bytes, in which case + one or more options are specified. Currently, the only valid + option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ). + */ + + if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) || + (authdat->checksum->length < 24)) { + code = 0; + major_status = GSS_S_BAD_BINDINGS; + goto fail; + } - ptr = (unsigned char *) authdat->checksum->contents; - bigend = 0; + /* + "Be liberal in what you accept, and + conservative in what you send" + -- rfc1123 - TREAD_INT(ptr, tmp, bigend); + This code will let this acceptor interoperate with an initiator + using little-endian or big-endian integer encoding. + */ - if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { ptr = (unsigned char *) authdat->checksum->contents; - bigend = 1; + bigend = 0; TREAD_INT(ptr, tmp, bigend); - if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { - major_status = GSS_S_FAILURE; - code = KG_BAD_LENGTH; - goto fail; + if (tmp != md5len) { + ptr = (unsigned char *) authdat->checksum->contents; + bigend = 1; + + TREAD_INT(ptr, tmp, bigend); + + if (tmp != md5len) { + code = KG_BAD_LENGTH; + major_status = GSS_S_FAILURE; + goto fail; + } } - } - /* at this point, bigend is set according to the initiator's byte order */ + /* at this point, bigend is set according to the initiator's + byte order */ - if ((code = kg_checksum_channel_bindings(context, input_chan_bindings, &md5, - bigend))) { - major_status = GSS_S_BAD_BINDINGS; - goto fail; - } + if ((code = kg_checksum_channel_bindings(context, input_chan_bindings, + &reqcksum, bigend))) { + major_status = GSS_S_BAD_BINDINGS; + goto fail; + } - TREAD_STR(ptr, ptr2, md5.length); - if (memcmp(ptr2, md5.contents, md5.length) != 0) { + TREAD_STR(ptr, ptr2, reqcksum.length); + if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) { code = 0; major_status = GSS_S_BAD_BINDINGS; goto fail; - } - - xfree(md5.contents); - md5.contents = 0; - - TREAD_INT(ptr, gss_flags, bigend); - gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; if there's - a delegation, we'll set it below */ - decode_req_message = 0; - - /* if the checksum length > 24, there are options to process */ + } - if(authdat->checksum->length > 24) { + xfree(reqcksum.contents); + reqcksum.contents = 0; - i = authdat->checksum->length - 24; + TREAD_INT(ptr, gss_flags, bigend); + gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; if + there's a delegation, we'll set + it below */ + decode_req_message = 0; - while(i>0) { + /* if the checksum length > 24, there are options to process */ - TREAD_INT16(ptr, option_id, bigend); + if(authdat->checksum->length > 24) { - switch(option_id) { + i = authdat->checksum->length - 24; - case KRB5_GSS_FOR_CREDS_OPTION: + while(i>0) { - TREAD_INT16(ptr, option.length, bigend); + TREAD_INT16(ptr, option_id, bigend); - /* have to use ptr2, since option.data is wrong type and - macro uses ptr as both lvalue and rvalue */ + switch(option_id) { - TREAD_STR(ptr, ptr2, bigend); - option.data = (char FAR *) ptr2; + case KRB5_GSS_FOR_CREDS_OPTION: - /* get a temporary auth_context structure for the - call to rd_and_store_for_creds() and clear its flags */ + TREAD_INT16(ptr, option.length, bigend); - if ((code = krb5_auth_con_init(context, - &auth_context_cred))) { - major_status = GSS_S_FAILURE; - goto fail; - } + /* have to use ptr2, since option.data is wrong type and + macro uses ptr as both lvalue and rvalue */ - krb5_auth_con_setflags(context, auth_context_cred, 0); + TREAD_STR(ptr, ptr2, bigend); + option.data = (char FAR *) ptr2; - /* store the delegated credential */ + /* store the delegated credential */ - rd_and_store_for_creds(context, auth_context_cred, - &option, - (delegated_cred_handle) ? - &deleg_cred : NULL); + if (code = rd_and_store_for_creds(context, &option, + (delegated_cred_handle) ? + &deleg_cred : NULL)) { + major_status = GSS_S_FAILURE; + goto fail; + } - i -= option.length + 4; + i -= option.length + 4; - krb5_auth_con_free(context, auth_context_cred); + gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ - gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ + break; - break; + /* default: */ + /* unknown options aren't an error */ - /* default: */ - /* unknown options aren't an error */ + } /* switch */ + } /* while */ + } /* if */ + } - } /* switch */ - } /* while */ - } /* if */ - /* create the ctx struct and start filling it in */ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) == NULL) { - major_status = GSS_S_FAILURE; code = ENOMEM; + major_status = GSS_S_FAILURE; goto fail; } @@ -469,83 +556,177 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ctx->gss_flags = KG_IMPLFLAGS(gss_flags); ctx->seed_init = 0; ctx->big_endian = bigend; - - major_status = GSS_S_FAILURE; + ctx->gsskrb5_version = gsskrb5_vers; /* Intern the ctx pointer so that delete_sec_context works */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { - code = G_VALIDATE_FAILED; - xfree(ctx); - ctx = 0; - goto fail; + xfree(ctx); + ctx = 0; + + code = G_VALIDATE_FAILED; + major_status = GSS_S_FAILURE; + goto fail; } - - if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) - goto fail; - if ((code = krb5_copy_principal(context, authdat->client, &ctx->there))) - goto fail; + if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) { + major_status = GSS_S_FAILURE; + goto fail; + } - /* done with authdat */ - krb5_free_authenticator(context, authdat); - authdat = 0; + if ((code = krb5_copy_principal(context, authdat->client, &ctx->there))) { + major_status = GSS_S_FAILURE; + goto fail; + } if ((code = krb5_auth_con_getremotesubkey(context, auth_context, - &ctx->subkey))) - goto fail; + &ctx->subkey))) { + major_status = GSS_S_FAILURE; + goto fail; + } /* use the session key if the subkey isn't present */ if (ctx->subkey == NULL) { if ((code = krb5_auth_con_getkey(context, auth_context, - &ctx->subkey))) - goto fail; + &ctx->subkey))) { + major_status = GSS_S_FAILURE; + goto fail; + } } if (ctx->subkey == NULL) { /* this isn't a very good error, but it's not clear to me this can actually happen */ + major_status = GSS_S_FAILURE; code = KRB5KDC_ERR_NULL_KEY; goto fail; } - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; + if (gsskrb5_vers == 2000) { + int cblen; + krb5_boolean valid; + + /* intersect the token ctypes with the local ctypes */ + + if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype, + &ctx->nctypes, &ctx->ctypes)) + goto fail; + + if (nctypes == 0) { + code = KRB5_CRYPTO_INTERNAL; + goto fail; + } + + kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + + if (nctypes == 0) { + code = KG_NO_CTYPES; + goto fail; + } + + /* process the delegated cred, if any */ + + if (fwcred.data) { + krb5_data option; + + option.length = fwcred.length; + option.data = fwcred.data; + + if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) { + major_status = GSS_S_FAILURE; + goto fail; + } + + gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ + } + + /* construct the checksum buffer */ + + cblen = 4*5; + if (input_chan_bindings) + cblen += (input_chan_bindings->initiator_address.length+ + input_chan_bindings->acceptor_address.length+ + input_chan_bindings->application_data.length); + + cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2)); + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + + ptr2 = cksumdata.data; + + if (input_chan_bindings) { + TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1); + TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1); + TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1); + TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1); + TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1); + } else { + memset(ptr2, 0, cblen); + ptr2 += cblen; + } + + memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2))); + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, + &cksumdata, authdat->checksum, + &valid)) { + major_status = GSS_S_FAILURE; + goto fail; + } + + free(cksumdata.data); + cksumdata.data = 0; + + if (!valid) { + code = 0; + major_status = GSS_S_BAD_SIG; + goto fail; + } + } else { + /* gss krb5 v1 */ + + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; #if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; #endif - default: - code = KRB5_BAD_ENCTYPE; - goto fail; - } - - /* fill in the encryption descriptors */ + default: + code = KRB5_BAD_ENCTYPE; + goto fail; + } - krb5_use_enctype(context, &ctx->enc.eblock, enctype); - ctx->enc.processed = 0; + /* fill in the encryption descriptors */ - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { + major_status = GSS_S_FAILURE; goto fail; + } - for (i=0; ienc.key->length; i++) - /*SUPPRESS 113*/ - ctx->enc.key->contents[i] ^= 0xf0; + for (i=0; ienc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, enctype); - ctx->seq.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { + major_status = GSS_S_FAILURE; goto fail; + } + } ctx->endtime = ticket->enc_part2->times.endtime; ctx->krb_flags = ticket->enc_part2->flags; @@ -554,13 +735,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_auth_con_getremoteseqnumber(context, auth_context, &ctx->seq_recv); - if ((code = krb5_timeofday(context, &now))) - goto fail; + if ((code = krb5_timeofday(context, &now))) { + major_status = GSS_S_FAILURE; + goto fail; + } if (ctx->endtime < now) { - code = 0; - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; + code = 0; + major_status = GSS_S_CREDENTIALS_EXPIRED; + goto fail; } g_order_init(&(ctx->seqstate), ctx->seq_recv, @@ -573,40 +756,156 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* generate an AP_REP if necessary */ if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) { - krb5_data ap_rep; - unsigned char * ptr; - if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) - goto fail; - - krb5_auth_con_getlocalseqnumber(context, auth_context, &ctx->seq_send); - token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) == NULL) { - code = ENOMEM; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, ap_rep.length, - &ptr, KG_TOK_CTX_AP_REP); - - TWRITE_STR(ptr, ap_rep.data, ap_rep.length); - xfree(ap_rep.data); + unsigned char * ptr; + if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) { + major_status = GSS_S_FAILURE; + goto fail; + } + + krb5_auth_con_getlocalseqnumber(context, auth_context, + &ctx->seq_send); + + /* the reply token hasn't been sent yet, but that's ok. */ + ctx->established = 1; + + if (ctx->gsskrb5_version == 2000) { + krb5_ui_4 tok_flags; + + tok_flags = + (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0; + + cksumdata.length = 8 + 4*ctx->nctypes + 4; + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + + /* construct the token fields */ + + ptr = cksumdata.data; + + ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff; + ptr[1] = KG2_TOK_RESPONSE & 0xff; + + ptr[2] = (tok_flags >> 24) & 0xff; + ptr[3] = (tok_flags >> 16) & 0xff; + ptr[4] = (tok_flags >> 8) & 0xff; + ptr[5] = tok_flags & 0xff; + + ptr[6] = (ctx->nctypes >> 8) & 0xff; + ptr[7] = ctx->nctypes & 0xff; + + ptr += 8; + + for (i=0; inctypes; i++) { + ptr[i] = (ctx->ctypes[i] >> 24) & 0xff; + ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff; + ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff; + ptr[i+3] = ctx->ctypes[i] & 0xff; + + ptr += 4; + } + + memset(ptr, 0, 4); + + /* make the MIC token */ + + { + gss_buffer_desc text, token; + + text.length = cksumdata.length; + text.value = cksumdata.data; + + /* ctx->seq_send must be set before this call */ + + if (GSS_ERROR(major_status = + krb5_gss_get_mic(&code, ctx, + GSS_C_QOP_DEFAULT, + &text, &token))) + goto fail; + + mic.length = token.length; + mic.data = token.value; + } + + token.length = g_token_size((gss_OID) mech_used, + (cksumdata.length-2)+4+ap_rep.length+ + mic.length); + + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, + (cksumdata.length-2)+4+ap_rep.length+mic.length, + &ptr, KG2_TOK_RESPONSE); + + memcpy(ptr, cksumdata.data+2, cksumdata.length-2); + ptr += cksumdata.length-2; + + ptr[0] = (ap_rep.length >> 8) & 0xff; + ptr[1] = ap_rep.length & 0xff; + memcpy(ptr+2, ap_rep.data, ap_rep.length); + + ptr += (2+ap_rep.length); + + ptr[0] = (mic.length >> 8) & 0xff; + ptr[1] = mic.length & 0xff; + memcpy(ptr+2, mic.data, mic.length); + + ptr += (2+mic.length); + + free(cksumdata.data); + cksumdata.data = 0; + + /* gss krb5 v2 */ + } else { + /* gss krb5 v1 */ + + token.length = g_token_size((gss_OID) mech_used, ap_rep.length); + + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + major_status = GSS_S_FAILURE; + code = ENOMEM; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); + + TWRITE_STR(ptr, ap_rep.data, ap_rep.length); + xfree(ap_rep.data); + + ctx->established = 1; + + } } else { - token.length = 0; - token.value = NULL; - ctx->seq_send = ctx->seq_recv; + token.length = 0; + token.value = NULL; + ctx->seq_send = ctx->seq_recv; + + ctx->established = 1; } /* set the return arguments */ if (src_name) { - if ((code = krb5_copy_principal(context, ctx->there, &name))) - goto fail; - /* intern the src_name */ - if (! kg_save_name((gss_name_t) name)) { - code = G_VALIDATE_FAILED; - goto fail; - } + if ((code = krb5_copy_principal(context, ctx->there, &name))) { + major_status = GSS_S_FAILURE; + goto fail; + } + /* intern the src_name */ + if (! kg_save_name((gss_name_t) name)) { + code = G_VALIDATE_FAILED; + major_status = GSS_S_FAILURE; + goto fail; + } } if (mech_type) @@ -618,7 +917,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (ret_flags) *ret_flags = ctx->gss_flags; - ctx->established = 1; *context_handle = ctx; *output_token = token; @@ -626,39 +924,54 @@ krb5_gss_accept_sec_context(minor_status, context_handle, *src_name = (gss_name_t) name; if (delegated_cred_handle && deleg_cred) { - if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) { - code = G_VALIDATE_FAILED; - goto fail; - } + if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) { + major_status = GSS_S_FAILURE; + code = G_VALIDATE_FAILED; + goto fail; + } - *delegated_cred_handle = (gss_cred_id_t) deleg_cred; + *delegated_cred_handle = (gss_cred_id_t) deleg_cred; } /* finally! */ *minor_status = 0; - return(GSS_S_COMPLETE); + major_status = GSS_S_COMPLETE; -fail: + fail: + if (ctypes) + free(ctypes); if (authdat) - krb5_free_authenticator(context, authdat); + krb5_free_authenticator(context, authdat); + if (reqcksum.contents) + xfree(reqcksum.contents); + if (ap_rep.data) + xfree(ap_rep.data); + if (mic.data) + xfree(mic.data); + if (cksumdata.data) + xfree(cksumdata.data); + + if (!GSS_ERROR(major_status)) + return(major_status); + + /* from here on is the real "fail" code */ + if (ctx) - (void) krb5_gss_delete_sec_context(minor_status, - (gss_ctx_id_t *) &ctx, NULL); + (void) krb5_gss_delete_sec_context(minor_status, + (gss_ctx_id_t *) &ctx, NULL); + if (deleg_cred) { /* free memory associated with the deleg credential */ + if (deleg_cred->ccache) + (void)krb5_cc_close(context, deleg_cred->ccache); + if (deleg_cred->princ) + krb5_free_principal(context, deleg_cred->princ); + xfree(deleg_cred); + } if (token.value) - xfree(token.value); + xfree(token.value); if (name) { - (void) kg_delete_name((gss_name_t) name); - krb5_free_principal(context, name); - } - if (md5.contents) - xfree(md5.contents); - if (deleg_cred) { /* free memory associated with the deleg credential */ - if (deleg_cred->ccache) - (void)krb5_cc_close(context, deleg_cred->ccache); - if (deleg_cred->princ) - krb5_free_principal(context, deleg_cred->princ); - xfree(deleg_cred); + (void) kg_delete_name((gss_name_t) name); + krb5_free_principal(context, name); } *minor_status = code; @@ -670,48 +983,75 @@ fail: * decode the authenticator to read out the gss_flags field. */ if (decode_req_message) { - krb5_ap_req * request; + krb5_ap_req * request; - if (decode_krb5_ap_req(&ap_req, &request)) - return (major_status); - if (request->ap_options & AP_OPTS_MUTUAL_REQUIRED) - gss_flags |= GSS_C_MUTUAL_FLAG; - krb5_free_ap_req(context, request); + if (decode_krb5_ap_req(&ap_req, &request)) + return (major_status); + if (request->ap_options & AP_OPTS_MUTUAL_REQUIRED) + gss_flags |= GSS_C_MUTUAL_FLAG; + krb5_free_ap_req(context, request); } if (cred && (gss_flags & GSS_C_MUTUAL_FLAG)) { - /* - * The client is expecting a response, so we can send an - * error token back - */ - memset(&krb_error_data, 0, sizeof(krb_error_data)); - - code -= ERROR_TABLE_BASE_krb5; - if (code < 0 || code > 128) - code = 60 /* KRB_ERR_GENERIC */; - - krb_error_data.error = code; - (void) krb5_us_timeofday(context, &krb_error_data.stime, - &krb_error_data.susec); - krb_error_data.server = cred->princ; + int tmsglen, toktype; + + /* + * The client is expecting a response, so we can send an + * error token back + */ + memset(&krb_error_data, 0, sizeof(krb_error_data)); + + code -= ERROR_TABLE_BASE_krb5; + if (code < 0 || code > 128) + code = 60 /* KRB_ERR_GENERIC */; + + krb_error_data.error = code; + (void) krb5_us_timeofday(context, &krb_error_data.stime, + &krb_error_data.susec); + krb_error_data.server = cred->princ; - code = krb5_mk_error(context, &krb_error_data, &scratch); - if (code) - return (major_status); + code = krb5_mk_error(context, &krb_error_data, &scratch); + if (code) + return (major_status); + + if (gsskrb5_vers == 2000) { + tmsglen = 12+scratch.length; + toktype = KG2_TOK_RESPONSE; + } else { + tmsglen = scratch.length; + toktype = KG_TOK_CTX_ERROR; + } - token.length = g_token_size((gss_OID) mech_used, scratch.length); - token.value = (unsigned char *) xmalloc(token.length); - if (!token.value) - return (major_status); + token.length = g_token_size((gss_OID) mech_used, tmsglen); + token.value = (unsigned char *) xmalloc(token.length); + if (!token.value) + return (major_status); - ptr = token.value; - g_make_token_header((gss_OID) mech_used, scratch.length, - &ptr, KG_TOK_CTX_ERROR); + ptr = token.value; + g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); + + if (gsskrb5_vers == 2000) { + krb5_ui_4 flags; + + flags = KG2_RESP_FLAG_ERROR; + + ptr[0] = (flags << 24) & 0xff; + ptr[1] = (flags << 16) & 0xff; + ptr[2] = (flags << 8) & 0xff; + ptr[3] = flags & 0xff; + + memset(ptr+4, 0, 6); + + ptr[10] = (scratch.length << 8) & 0xff; + ptr[11] = scratch.length & 0xff; + + ptr += 12; + } - TWRITE_STR(ptr, scratch.data, scratch.length); - xfree(scratch.data); + TWRITE_STR(ptr, scratch.data, scratch.length); + xfree(scratch.data); - *output_token = token; + *output_token = token; } if (!verifier_cred_handle && cred_handle) { krb5_gss_release_cred(&code, cred_handle); diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 1ca1bf31a..f968b7d4f 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" #ifdef HAVE_STRING_H #include @@ -248,8 +274,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, size_t i; krb5_gss_cred_id_t cred; gss_OID_set ret_mechs; - const gss_OID_set_desc FAR * valid_mechs; - int req_old, req_new; + int req_old, req_new, req_v2; OM_uint32 ret; krb5_error_code code; @@ -277,27 +302,24 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, contains krb5 */ if (desired_mechs == GSS_C_NULL_OID_SET) { - valid_mechs = gss_mech_set_krb5_both; req_old = 1; req_new = 1; + req_v2 = 1; } else { req_old = 0; req_new = 0; + req_v2 = 0; for (i=0; icount; i++) { if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) req_new++; + if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i]))) + req_v2++; } - if (req_old && req_new) { - valid_mechs = gss_mech_set_krb5_both; - } else if (req_old) { - valid_mechs = gss_mech_set_krb5_old; - } else if (req_new) { - valid_mechs = gss_mech_set_krb5; - } else { + if (!req_old && !req_new && !req_v2) { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -314,9 +336,9 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, cred->usage = cred_usage; cred->princ = NULL; - cred->actual_mechs = valid_mechs; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; + cred->rfcv2_mech = req_v2; cred->keytab = NULL; cred->ccache = NULL; @@ -407,17 +429,30 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, /* create mechs */ if (actual_mechs) { - if (! g_copy_OID_set(cred->actual_mechs, &ret_mechs)) { - if (cred->ccache) - (void)krb5_cc_close(context, cred->ccache); - if (cred->keytab) - (void)krb5_kt_close(context, cred->keytab); - if (cred->princ) - krb5_free_principal(context, cred->princ); - xfree(cred); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, + &ret_mechs)) || + (cred->prerfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_old, + &ret_mechs))) || + (cred->rfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5, + &ret_mechs))) || + (cred->rfcv2_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_v2, + &ret_mechs)))) { + if (cred->ccache) + (void)krb5_cc_close(context, cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(context, cred->keytab); + if (cred->princ) + krb5_free_principal(context, cred->princ); + xfree(cred); + /* *minor_status set above */ + return(ret); + } } /* intern the credential handle */ @@ -445,39 +480,3 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, return(GSS_S_COMPLETE); } - -/* V2 interface */ -OM_uint32 -krb5_gss_add_cred(minor_status, input_cred_handle, - desired_name, desired_mech, cred_usage, - initiator_time_req, acceptor_time_req, - output_cred_handle, actual_mechs, - initiator_time_rec, acceptor_time_rec) - OM_uint32 *minor_status; - gss_cred_id_t input_cred_handle; - gss_name_t desired_name; - gss_OID desired_mech; - gss_cred_usage_t cred_usage; - OM_uint32 initiator_time_req; - OM_uint32 acceptor_time_req; - gss_cred_id_t *output_cred_handle; - gss_OID_set *actual_mechs; - OM_uint32 *initiator_time_rec; - OM_uint32 *acceptor_time_rec; -{ - /* - * This does not apply to our single-mechanism implementation. Decide - * if the correct error is BAD_MECH or DUPLICATE_ELEMENT. - */ - - /* verify that the requested mechanism is the default, or - is krb5 */ - - if ((desired_mech != GSS_C_NULL_OID) && - (g_OID_equal(desired_mech, gss_mech_krb5))) - return(GSS_S_BAD_MECH); - - *minor_status = 0; - return(GSS_S_DUPLICATE_ELEMENT); -} - diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c new file mode 100644 index 000000000..2a6fdb47b --- /dev/null +++ b/src/lib/gssapi/krb5/add_cred.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "gssapiP_krb5.h" +#ifdef HAVE_STRING_H +#include +#else +#include +#endif + +/* + * $Id$ + */ + +/* V2 interface */ +OM_uint32 +krb5_gss_add_cred(minor_status, input_cred_handle, + desired_name, desired_mech, cred_usage, + initiator_time_req, acceptor_time_req, + output_cred_handle, actual_mechs, + initiator_time_rec, acceptor_time_rec) + OM_uint32 *minor_status; + gss_cred_id_t input_cred_handle; + gss_name_t desired_name; + gss_OID desired_mech; + gss_cred_usage_t cred_usage; + OM_uint32 initiator_time_req; + OM_uint32 acceptor_time_req; + gss_cred_id_t *output_cred_handle; + gss_OID_set *actual_mechs; + OM_uint32 *initiator_time_rec; + OM_uint32 *acceptor_time_rec; +{ + krb5_context context; + OM_uint32 major_status, lifetime; + krb5_gss_cred_id_t cred; + krb5_error_code code; + + /* this is pretty simple, since there's not really any difference + between the underlying mechanisms. The main hair is in copying + a mechanism if requested. */ + + /* check if the desired_mech is bogus */ + + if (!g_OID_equal(desired_mech, gss_mech_krb5_v2) && + !g_OID_equal(desired_mech, gss_mech_krb5) && + !g_OID_equal(desired_mech, gss_mech_krb5_old)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + + /* check if the desired_mech is bogus */ + + if ((cred_usage != GSS_C_INITIATE) && + (cred_usage != GSS_C_ACCEPT) && + (cred_usage != GSS_C_BOTH)) { + *minor_status = (OM_uint32) G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + /* since the default credential includes all the mechanisms, + return an error for that case. */ + + /*SUPPRESS 29*/ + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return(GSS_S_DUPLICATE_ELEMENT); + } + + /* verify the credential */ + if (GSS_ERROR(major_status = + krb5_gss_validate_cred(minor_status, input_cred_handle))) + return(major_status); + + cred = (krb5_gss_cred_id_t) input_cred_handle; + + /* check if the cred_usage is equal or "less" than the passed-in cred + if copying */ + + if (!((cred->usage == cred_usage) || + ((cred->usage == GSS_C_BOTH) && + (output_cred_handle != NULL)))) { + *minor_status = (OM_uint32) G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + /* check that desired_mech isn't already in the credential */ + + if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) || + (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) || + (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) { + *minor_status = 0; + return(GSS_S_DUPLICATE_ELEMENT); + } + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + + /* verify the desired_name */ + + /*SUPPRESS 29*/ + if ((desired_name != (gss_name_t) NULL) && + (! kg_validate_name(desired_name))) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + /* make sure the desired_name is the same as the existing one */ + + if (desired_name && + !krb5_principal_compare(context, (krb5_principal) desired_name, + cred->princ)) { + *minor_status = 0; + return(GSS_S_BAD_NAME); + } + + /* copy the cred if necessary */ + + if (output_cred_handle) { + /* make a copy */ + krb5_gss_cred_id_t new_cred; + char *kttype, ktboth[1024]; + char *cctype, *ccname, ccboth[1024]; + + if ((new_cred = + (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) + == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + memset(new_cred, 0, sizeof(krb5_gss_cred_id_rec)); + + new_cred->usage = cred_usage; + new_cred->prerfc_mech = cred->prerfc_mech; + new_cred->rfc_mech = cred->rfc_mech; + new_cred->rfcv2_mech = cred->rfcv2_mech; + new_cred->tgt_expire = cred->tgt_expire; + + if (code = krb5_copy_principal(context, cred->princ, + &new_cred->princ)) { + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (cred->keytab) { + kttype = krb5_kt_get_type(context, cred->keytab); + if ((strlen(kttype)+2) > sizeof(ktboth)) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + strcpy(ktboth, kttype); + strcat(ktboth, ":"); + + if (code = krb5_kt_get_name(context, cred->keytab, + ktboth+strlen(ktboth), + sizeof(ktboth)-strlen(ktboth))) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = krb5_kt_resolve(context, ktboth, &new_cred->keytab)) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->keytab = NULL; + } + + if (cred->rcache) { + /* Open the replay cache for this principal. */ + if ((code = krb5_get_server_rcache(context, + krb5_princ_component(context, cred->princ, 0), + &new_cred->rcache))) { + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->rcache = NULL; + } + + if (cred->ccache) { + cctype = krb5_cc_get_type(context, cred->ccache); + ccname = krb5_cc_get_name(context, cred->ccache); + + if ((strlen(cctype)+strlen(ccname)+2) > sizeof(ccboth)) { + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + strcpy(ccboth, cctype); + strcat(ccboth, ":"); + strcat(ccboth, ccname); + + if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) { + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->ccache = NULL; + } + + /* intern the credential handle */ + + if (! kg_save_cred_id((gss_cred_id_t) new_cred)) { + if (new_cred->ccache) + krb5_cc_close(context, new_cred->ccache); + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* modify new_cred */ + + cred = new_cred; + } + + /* set the flag for the new mechanism */ + + if (g_OID_equal(desired_mech, gss_mech_krb5_old)) + cred->prerfc_mech = 1; + else if (g_OID_equal(desired_mech, gss_mech_krb5)) + cred->rfc_mech = 1; + else if (g_OID_equal(desired_mech, gss_mech_krb5_v2)) + cred->rfcv2_mech = 1; + + /* set the outputs */ + + if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status, cred, + NULL, &lifetime, + NULL, actual_mechs))) { + OM_uint32 dummy; + + if (output_cred_handle) + (void) krb5_gss_release_cred(&dummy, (gss_cred_id_t *) &cred); + + return(major_status); + } + + if (initiator_time_rec) + *initiator_time_rec = lifetime; + if (acceptor_time_rec) + *acceptor_time_rec = lifetime; + + if (output_cred_handle) + *output_cred_handle = cred; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/canon_name.c b/src/lib/gssapi/krb5/canon_name.c index 652745c7b..688366e1f 100644 --- a/src/lib/gssapi/krb5/canon_name.c +++ b/src/lib/gssapi/krb5/canon_name.c @@ -31,13 +31,12 @@ OM_uint32 krb5_gss_canonicalize_name(OM_uint32 *minor_status, const gss_OID mech_type, gss_name_t *output_name) { - if ((mech_type == GSS_C_NULL_OID) || - !g_OID_equal(mech_type, gss_mech_krb5)) { - if (minor_status) - *minor_status = 0; - return(GSS_S_BAD_MECH); - } - - return gss_duplicate_name(minor_status, input_name, - output_name); + if (!g_OID_equal(gss_mech_krb5_v2, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_old, mech_type)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + + return(gss_duplicate_name(minor_status, input_name, output_name)); } diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index 16964995a..28c235890 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -80,15 +80,11 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) if (ctx->seqstate) g_order_free(&(ctx->seqstate)); - if (ctx->enc.processed) - krb5_finish_key(context, &ctx->enc.eblock); - if (ctx->enc.key) - krb5_free_keyblock(context, ctx->enc.key); + if (ctx->enc) + krb5_free_keyblock(context, ctx->enc); - if (ctx->seq.processed) - krb5_finish_key(context, &ctx->seq.eblock); - if (ctx->seq.key) - krb5_free_keyblock(context, ctx->seq.key); + if (ctx->seq) + krb5_free_keyblock(context, ctx->seq); if (ctx->here) krb5_free_principal(context, ctx->here); @@ -105,6 +101,9 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) if (ctx->mech_used) gss_release_oid(minor_status, &ctx->mech_used); + if (ctx->ctypes) + xfree(ctx->ctypes); + /* Zero out context */ memset(ctx, 0, sizeof(*ctx)); xfree(ctx); diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c index 4dc13843c..3a6ba7b1a 100644 --- a/src/lib/gssapi/krb5/disp_status.c +++ b/src/lib/gssapi/krb5/disp_status.c @@ -49,10 +49,12 @@ krb5_gss_display_status(minor_status, status_value, status_type, return(GSS_S_FAILURE); if ((mech_type != GSS_C_NULL_OID) && - (! g_OID_equal(gss_mech_krb5, mech_type))) { - *minor_status = 0; - return(GSS_S_BAD_MECH); - } + !g_OID_equal(gss_mech_krb5_v2, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_old, mech_type)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } if (status_type == GSS_C_GSS_CODE) { return(g_display_major_status(minor_status, status_value, diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 11b7c50f4..bcbde3894 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -68,8 +68,17 @@ ((x) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \ GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))) +#define KG2_TOK_INITIAL 0x0101 +#define KG2_TOK_RESPONSE 0x0202 +#define KG2_TOK_MIC 0x0303 +#define KG2_TOK_WRAP_INTEG 0x0404 +#define KG2_TOK_WRAP_PRIV 0x0505 + #define KRB5_GSS_FOR_CREDS_OPTION 1 +#define KG2_RESP_FLAG_ERROR 0x0001 +#define KG2_RESP_FLAG_DELEG_OK 0x0002 + /** internal types **/ typedef krb5_principal krb5_gss_name_t; @@ -78,25 +87,19 @@ typedef struct _krb5_gss_cred_id_rec { /* name/type of credential */ gss_cred_usage_t usage; krb5_principal princ; /* this is not interned as a gss_name_t */ - const gss_OID_set_desc *actual_mechs; - int prerfc_mech; /* these are a cache of the set above */ + int prerfc_mech; int rfc_mech; + int rfcv2_mech; /* keytab (accept) data */ krb5_keytab keytab; + krb5_rcache rcache; /* ccache (init) data */ krb5_ccache ccache; krb5_timestamp tgt_expire; - krb5_rcache rcache; } krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; -typedef struct _krb5_gss_enc_desc { - int processed; - krb5_keyblock *key; - krb5_encrypt_block eblock; -} krb5_gss_enc_desc; - typedef struct _krb5_gss_ctx_id_rec { int initiate; /* nonzero if initiating, zero if accepting */ OM_uint32 gss_flags; @@ -108,21 +111,35 @@ typedef struct _krb5_gss_ctx_id_rec { int signalg; int cksum_size; int sealalg; - krb5_gss_enc_desc enc; - krb5_gss_enc_desc seq; + krb5_keyblock *enc; + krb5_keyblock *seq; krb5_timestamp endtime; krb5_flags krb_flags; - krb5_int32 seq_send; - krb5_int32 seq_recv; + /* XXX these used to be signed. the old spec is inspecific, and + the new spec specifies unsigned. I don't believe that the change + affects the wire encoding. */ + krb5_ui_4 seq_send; + krb5_ui_4 seq_recv; void *seqstate; int established; int big_endian; krb5_auth_context auth_context; gss_OID_desc *mech_used; + int gsskrb5_version; + int nctypes; + krb5_cksumtype *ctypes; } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; extern void *kg_vdb; +struct kg2_option { + int option_id; /* set by caller */ + int length; /* filled in by parser */ + unsigned char *data; /* filled in by parser. points inside + passed-in token, so nothing needs to + be freed */ +}; + /* helper macros */ #define kg_save_name(name) g_save_name(&kg_vdb,name) @@ -151,12 +168,12 @@ krb5_error_code kg_checksum_channel_bindings int bigend)); krb5_error_code kg_make_seq_num PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, int direction, krb5_int32 seqnum, unsigned char *cksum, unsigned char *buf)); krb5_error_code kg_get_seq_num PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, unsigned char *cksum, unsigned char *buf, int *direction, krb5_int32 *seqnum)); @@ -164,19 +181,20 @@ krb5_error_code kg_make_seed PROTOTYPE((krb5_context context, krb5_keyblock *key, unsigned char *seed)); -int kg_confounder_size PROTOTYPE((krb5_gss_enc_desc *ed)); +int kg_confounder_size PROTOTYPE((krb5_context context, krb5_keyblock *key)); -krb5_error_code kg_make_confounder PROTOTYPE((krb5_gss_enc_desc *ed, - unsigned char *buf)); +krb5_error_code kg_make_confounder PROTOTYPE((krb5_context context, + krb5_keyblock *key, unsigned char *buf)); -int kg_encrypt_size PROTOTYPE((krb5_gss_enc_desc *ed, int n)); +int kg_encrypt_size PROTOTYPE((krb5_context context, + krb5_keyblock *key, int n)); krb5_error_code kg_encrypt PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); krb5_error_code kg_decrypt PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); OM_uint32 kg_seal PROTOTYPE((krb5_context context, @@ -223,6 +241,23 @@ krb5_error_code kg_ctx_internalize PROTOTYPE((krb5_context kcontext, OM_uint32 kg_get_context PROTOTYPE((OM_uint32 *minor_status, krb5_context *context)); +OM_uint32 +kg2_parse_token PROTOTYPE((OM_uint32 *minor_status, + unsigned char *ptr, + int length, + krb5_ui_4 *flags, + int *nctypes, /* OUT */ + krb5_cksumtype **ctypes, /* OUT */ + int noptions, + struct kg2_option *options, /* INOUT */ + krb5_data *kmsg, + krb5_data *mic)); + +void kg2_intersect_ctypes PROTOTYPE((int *nc1, + krb5_cksumtype *c1, + int nc2, + const krb5_cksumtype *c2)); + /** declarations of internal name mechanism functions **/ OM_uint32 krb5_gss_acquire_cred diff --git a/src/lib/gssapi/krb5/gssapi_err_krb5.et b/src/lib/gssapi/krb5/gssapi_err_krb5.et index 54a126518..3c9be6351 100644 --- a/src/lib/gssapi/krb5/gssapi_err_krb5.et +++ b/src/lib/gssapi/krb5/gssapi_err_krb5.et @@ -35,4 +35,5 @@ error_code KG_CRED, "Bad magic number for krb5_gss_cred_id_t" error_code KG_ENC_DESC, "Bad magic number for krb5_gss_enc_desc" error_code KG_BAD_SEQ, "Sequence number in token is corrupt" error_code KG_EMPTY_CCACHE, "Credential cache is empty" +error_code KG_NO_CTYPES, "Acceptor and Initiator share no checksum types" end diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index c0942c39a..aaa47ea06 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* * $Id$ */ @@ -43,6 +69,9 @@ * The OID of the proposed standard krb5 mechanism is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) * krb5(2) = 1.2.840.113554.1.2.2 + * The OID of the proposed standard krb5 v2 mechanism is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5v2(3) = 1.2.840.113554.1.2.3 * */ @@ -58,8 +87,13 @@ const gss_OID_desc krb5_gss_oid_array[] = { {5, "\053\005\001\005\002"}, /* this is the official, rfc-specified OID */ {9, "\052\206\110\206\367\022\001\002\002"}, + /* these two are name type OID's */ {10, "\052\206\110\206\367\022\001\002\002\001"}, {10, "\052\206\110\206\367\022\001\002\002\002"}, + /* this is the v2 assigned OID */ + {9, "\052\206\110\206\367\022\001\002\003"}, + /* this is the official, rfc-specified OID again */ + {9, "\052\206\110\206\367\022\001\002\002"}, { 0, 0 } }; @@ -67,16 +101,21 @@ const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+0; const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+1; const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+2; const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+3; +const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+4; static const gss_OID_set_desc oidsets[] = { {1, (gss_OID) krb5_gss_oid_array+0}, {1, (gss_OID) krb5_gss_oid_array+1}, {2, (gss_OID) krb5_gss_oid_array+0}, + {1, (gss_OID) krb5_gss_oid_array+4}, + {2, (gss_OID) krb5_gss_oid_array+4}, }; const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+0; const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+1; const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; +const gss_OID_set_desc * const gss_mech_set_krb5_v2 = oidsets+3; +const gss_OID_set_desc * const gss_mech_set_krb5_v1v2 = oidsets+4; void *kg_vdb = NULL; diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h index 63ac530f3..e4eccbb42 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.h +++ b/src/lib/gssapi/krb5/gssapi_krb5.h @@ -32,9 +32,12 @@ extern const gss_OID_desc * const gss_mech_krb5; extern const gss_OID_desc * const gss_mech_krb5_old; +extern const gss_OID_desc * const gss_mech_krb5_v2; extern const gss_OID_set_desc * const gss_mech_set_krb5; extern const gss_OID_set_desc * const gss_mech_set_krb5_old; extern const gss_OID_set_desc * const gss_mech_set_krb5_both; +extern const gss_OID_set_desc * const gss_mech_set_krb5_v2; +extern const gss_OID_set_desc * const gss_mech_set_krb5_v1v2; extern const gss_OID_desc * const gss_nt_krb5_name; extern const gss_OID_desc * const gss_nt_krb5_principal; diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 50855b58c..4ff2085b4 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" #include #include @@ -33,8 +59,257 @@ int krb5_gss_dbg_client_expcreds = 0; static krb5_error_code -make_ap_req(context, auth_context, cred, server, now, endtime, chan_bindings, - req_flags, krb_flags, mech_type, token) +make_ap_req_v2(context, auth_context, cred, server, now, endtime, + chan_bindings, req_flags, krb_flags, mech_type, + ret_nctypes, ret_ctypes, token) + krb5_context context; + krb5_auth_context * auth_context; + krb5_gss_cred_id_t cred; + krb5_principal server; + krb5_timestamp now; + krb5_timestamp *endtime; + gss_channel_bindings_t chan_bindings; + OM_uint32 *req_flags; + krb5_flags *krb_flags; + gss_OID mech_type; + int *ret_nctypes; + krb5_cksumtype **ret_ctypes; + gss_buffer_t token; +{ + krb5_flags mk_req_flags = 0; + krb5_int32 con_flags; + krb5_error_code code; + krb5_creds in_creds, *out_creds = 0; + krb5_data credmsg, cksumdata, ap_req; + int i, tlen, cblen, nctypes; + krb5_cksumtype *ctypes; + unsigned char *t, *ptr; + + credmsg.data = 0; + cksumdata.data = 0; + ap_req.data = 0; + ctypes = 0; + + /* this probably isn't necessary */ + if (*auth_context) + krb5_auth_con_free(context, *auth_context); + + *auth_context = 0; + + /* create the option data if necessary */ + + if (*req_flags & GSS_C_DELEG_FLAG) { + /* first get KRB_CRED message, so we know its length */ + + /* clear the time check flag that was set in krb5_auth_con_init() */ + krb5_auth_con_getflags(context, *auth_context, &con_flags); + krb5_auth_con_setflags(context, *auth_context, + con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); + + code = krb5_fwd_tgt_creds(context, *auth_context, 0, + cred->princ, server, cred->ccache, 1, + &credmsg); + + /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */ + krb5_auth_con_setflags(context, *auth_context, con_flags); + + if (code) { + /* don't fail here; just don't accept/do the delegation + request */ + *req_flags &= ~GSS_C_DELEG_FLAG; + } else { + if (credmsg.length > KRB5_INT16_MAX) { + krb5_free_data_contents(context, &credmsg); + return(KRB5KRB_ERR_FIELD_TOOLONG); + } + } + } else { + credmsg.length = 0; + } + + /* + * Get the credential, for the session key etype + */ + + memset((char *) &in_creds, 0, sizeof(krb5_creds)); + + if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client))) + goto cleanup; + if ((code = krb5_copy_principal(context, server, &in_creds.server))) + goto cleanup; + in_creds.times.endtime = *endtime; + + if ((code = krb5_get_credentials(context, 0, cred->ccache, + &in_creds, &out_creds))) + goto cleanup; + + /* + * Enforce a stricter limit (without timeskew forgiveness at the + * boundaries) because accept_sec_context code is also similarly + * non-forgiving. + */ + if (!krb5_gss_dbg_client_expcreds && out_creds->times.endtime < now) { + code = KRB5KRB_AP_ERR_TKT_EXPIRED; + goto cleanup; + } + + /* construct the list of compatible cksum types */ + + if (code = krb5_c_keyed_checksum_types(context, + out_creds->keyblock.enctype, + &nctypes, &ctypes)) + goto cleanup; + + if (nctypes == 0) { + code = KRB5_CRYPTO_INTERNAL; + goto cleanup; + } + + /* construct the checksum fields */ + + cblen = 4*5; + if (chan_bindings) + cblen += (chan_bindings->initiator_address.length+ + chan_bindings->acceptor_address.length+ + chan_bindings->application_data.length); + + cksumdata.length = cblen + 8 + 4*nctypes + 4; + if (credmsg.length) + cksumdata.length += 4 + credmsg.length; + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) + goto cleanup; + + /* helper macros. This code currently depends on a long being 32 + bits, and htonl dtrt. */ + + ptr = cksumdata.data; + + if (chan_bindings) { + TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1); + TWRITE_BUF(ptr, chan_bindings->initiator_address, 1); + TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1); + TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1); + TWRITE_BUF(ptr, chan_bindings->application_data, 1); + } else { + memset(ptr, 0, cblen); + ptr += cblen; + } + + /* construct the token fields */ + + ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff; + ptr[1] = KG2_TOK_INITIAL & 0xff; + + ptr[2] = (*req_flags >> 24) & 0xff; + ptr[3] = (*req_flags >> 16) & 0xff; + ptr[4] = (*req_flags >> 8) & 0xff; + ptr[5] = *req_flags & 0xff; + + ptr[6] = (nctypes >> 8) & 0xff; + ptr[7] = nctypes & 0xff; + + ptr += 8; + + for (i=0; i> 24) & 0xff; + ptr[1] = (ctypes[i] >> 16) & 0xff; + ptr[2] = (ctypes[i] >> 8) & 0xff; + ptr[3] = ctypes[i] & 0xff; + + ptr += 4; + } + + if (credmsg.length) { + ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff; + ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff; + + ptr[2] = (credmsg.length >> 8) & 0xff; + ptr[3] = credmsg.length & 0xff; + + ptr += 4; + + memcpy(ptr, credmsg.data, credmsg.length); + + ptr += credmsg.length; + } + + memset(ptr, 0, 4); + + /* call mk_req. subkey and ap_req need to be used or destroyed */ + + mk_req_flags = AP_OPTS_USE_SUBKEY; + + if (*req_flags & GSS_C_MUTUAL_FLAG) + mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; + + if ((code = krb5_mk_req_extended(context, auth_context, mk_req_flags, + &cksumdata, out_creds, &ap_req))) + goto cleanup; + + /* store the interesting stuff from creds and authent */ + *endtime = out_creds->times.endtime; + *krb_flags = out_creds->ticket_flags; + + /* build up the token */ + + /* allocate space for the token */ + tlen = g_token_size((gss_OID) mech_type, + (cksumdata.length-(2+cblen))+2+ap_req.length); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { + code = ENOMEM; + goto cleanup; + } + + ptr = t; + + g_make_token_header((gss_OID) mech_type, + (cksumdata.length-(2+cblen))+2+ap_req.length, + &ptr, KG2_TOK_INITIAL); + + /* skip over the channel bindings and the token id */ + memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2)); + ptr += cksumdata.length-(cblen+2); + ptr[0] = (ap_req.length >> 8) & 0xff; + ptr[1] = ap_req.length & 0xff; + ptr += 2; + memcpy(ptr, ap_req.data, ap_req.length); + + /* pass allocated data back */ + + *ret_nctypes = nctypes; + *ret_ctypes = ctypes; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (code) { + if (*auth_context) + krb5_auth_con_free(context, *auth_context); + if (ctypes) + krb5_free_cksumtypes(context, ctypes); + } + + if (out_creds) + krb5_free_creds(context, out_creds); + krb5_free_cred_contents(context, &in_creds); + if (credmsg.data) + free(credmsg.data); + if (ap_req.data) + free(ap_req.data); + if (cksumdata.data) + free(cksumdata.data); + + return(code); +} + +static krb5_error_code +make_ap_req_v1(context, auth_context, cred, server, now, endtime, + chan_bindings, req_flags, krb_flags, mech_type, token) krb5_context context; krb5_auth_context * auth_context; krb5_gss_cred_id_t cred; @@ -142,15 +417,16 @@ make_ap_req(context, auth_context, cred, server, now, endtime, chan_bindings, /* fill in the necessary fields in creds */ memset((char *) &in_creds, 0, sizeof(krb5_creds)); + if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client))) goto cleanup; if ((code = krb5_copy_principal(context, server, &in_creds.server))) goto cleanup; - in_creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; in_creds.times.endtime = *endtime; + in_creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* - * Get the credential..., I don't know in 0 is a good value for the + * Get the credential..., I don't know if 0 is a good value for the * kdcoptions */ if ((code = krb5_get_credentials(context, 0, cred->ccache, @@ -222,10 +498,6 @@ cleanup: return (code); } -#define IS_KRB_ERROR(dat)\ - ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\ - (dat)->data[0] == 0x5e)) - OM_uint32 krb5_gss_init_sec_context(minor_status, claimant_cred_handle, context_handle, target_name, mech_type, @@ -251,10 +523,11 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, krb5_error_code code; krb5_gss_ctx_id_rec *ctx; krb5_timestamp now; - krb5_enctype enctype; gss_buffer_desc token; - int i; - int err; + int gsskrb5_vers; + int i, err; + krb5_ui_4 resp_flags, field_length, opt_id; + OM_uint32 major_status, dummy; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -289,15 +562,33 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, err = 0; if (mech_type == GSS_C_NULL_OID) { - mech_type = cred->rfc_mech?gss_mech_krb5:gss_mech_krb5_old; + if (cred->rfcv2_mech) { + mech_type = gss_mech_krb5_v2; + gsskrb5_vers = 2000; + } else if (cred->rfc_mech) { + mech_type = gss_mech_krb5; + gsskrb5_vers = 1000; + } else if (cred->prerfc_mech) { + mech_type = gss_mech_krb5_old; + gsskrb5_vers = 1000; + } else { + err = 1; + } + } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) { + if (!cred->rfcv2_mech) + err = 1; + gsskrb5_vers = 2000; } else if (g_OID_equal(mech_type, gss_mech_krb5)) { if (!cred->rfc_mech) err = 1; + gsskrb5_vers = 1000; } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { if (!cred->prerfc_mech) err = 1; - } else + gsskrb5_vers = 1000; + } else { err = 1; + } if (err) { *minor_status = 0; @@ -351,6 +642,9 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ ctx->seqstate = 0; + ctx->gsskrb5_version = gsskrb5_vers; + ctx->nctypes = 0; + ctx->ctypes = 0; if ((code = krb5_timeofday(context, &now))) { free(ctx); @@ -377,63 +671,94 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, return(GSS_S_FAILURE); } - if ((code = make_ap_req(context, &(ctx->auth_context), cred, - ctx->there, now, &ctx->endtime, - input_chan_bindings, - &ctx->gss_flags, &ctx->krb_flags, mech_type, - &token))) { - krb5_free_principal(context, ctx->here); - krb5_free_principal(context, ctx->there); - xfree(ctx); - *minor_status = code; - - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - return GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - return GSS_S_CREDENTIALS_EXPIRED; - return(GSS_S_FAILURE); - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &ctx->seq_send); - krb5_auth_con_getlocalsubkey(context, ctx->auth_context, &ctx->subkey); - - /* fill in the encryption descriptors */ - - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; + if (ctx->gsskrb5_version == 2000) { + /* gsskrb5 v2 */ + + ctx->gss_flags & ~GSS_C_DELEG_FLAG; + + if ((code = make_ap_req_v2(context, &(ctx->auth_context), cred, + ctx->there, now, &ctx->endtime, + input_chan_bindings, + &ctx->gss_flags, &ctx->krb_flags, + mech_type, &ctx->nctypes, &ctx->ctypes, + &token))) { + krb5_free_principal(context, ctx->here); + krb5_free_principal(context, ctx->there); + xfree(ctx); + *minor_status = code; + + if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || + (code == KG_EMPTY_CCACHE)) + return GSS_S_NO_CRED; + if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) + return GSS_S_CREDENTIALS_EXPIRED; + return(GSS_S_FAILURE); + } + + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, + &ctx->seq_send); + krb5_auth_con_getlocalsubkey(context, ctx->auth_context, + &ctx->subkey); + } else { + /* gsskrb5 v1 */ + + if ((code = make_ap_req_v1(context, &(ctx->auth_context), cred, + ctx->there, now, &ctx->endtime, + input_chan_bindings, + &ctx->gss_flags, &ctx->krb_flags, + mech_type, + &token))) { + krb5_free_principal(context, ctx->here); + krb5_free_principal(context, ctx->there); + xfree(ctx); + *minor_status = code; + + if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || + (code == KG_EMPTY_CCACHE)) + return GSS_S_NO_CRED; + if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) + return GSS_S_CREDENTIALS_EXPIRED; + return(GSS_S_FAILURE); + } + + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, + &ctx->seq_send); + krb5_auth_con_getlocalsubkey(context, ctx->auth_context, + &ctx->subkey); + + /* fill in the encryption descriptors */ + + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; #if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; #endif - default: - return GSS_S_FAILURE; - } + default: + return GSS_S_FAILURE; + } - /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ + /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ - krb5_use_enctype(context, &ctx->enc.eblock, enctype); - ctx->enc.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) - return(code); - for (i=0; ienc.key->length; i++) - /*SUPPRESS 113*/ - ctx->enc.key->contents[i] ^= 0xf0; + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) + return(code); + for (i=0; ienc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, enctype); - ctx->seq.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) - return(code); + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) + return(code); + } /* at this point, the context is constructed and valid, hence, releaseable */ @@ -493,7 +818,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, } else { unsigned char *ptr; char *sptr; - krb5_data ap_rep; + krb5_data ap_rep, mic; krb5_ap_rep_enc_part *ap_rep_data; krb5_error *krb_error; @@ -512,11 +837,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, if ((ctx->established) || (((gss_cred_id_t) cred) != claimant_cred_handle) || ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) { - (void)krb5_gss_delete_sec_context(minor_status, - context_handle, NULL); - /* XXX this minor status is wrong if an arg was changed */ - *minor_status = KG_CONTEXT_ESTABLISHED; - return(GSS_S_FAILURE); + code = KG_CONTEXT_ESTABLISHED; + goto fail; } if (! krb5_principal_compare(context, ctx->there, @@ -538,47 +860,106 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ptr = (unsigned char *) input_token->value; - if ((err = g_verify_token_header((gss_OID) mech_type, &(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length))) { + if (ctx->gsskrb5_version == 2000) { + int token_length; + int nctypes; + krb5_cksumtype *ctypes; + + /* gsskrb5 v2 */ + + if ((err = g_verify_token_header((gss_OID) mech_type, + &token_length, + &ptr, KG2_TOK_RESPONSE, + input_token->length))) { + (void)krb5_gss_delete_sec_context(minor_status, + context_handle, NULL); + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if (GSS_ERROR(major_status = + kg2_parse_token(minor_status, ptr, token_length, + &resp_flags, &nctypes, &ctypes, + 0, NULL, &ap_rep, &mic))) { + free(ctypes); + (void)krb5_gss_delete_sec_context(&dummy, context_handle, NULL); + return(major_status); + } + + kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + + free(ctypes); + + if (ctx->nctypes == 0) { + code = KG_NO_CTYPES; + goto fail; + } + + if (resp_flags & KG2_RESP_FLAG_ERROR) { + if (code = krb5_rd_error(context, &ap_rep, &krb_error)) + goto fail; + + if (krb_error->error) + code = krb_error->error + ERROR_TABLE_BASE_krb5; + else + code = 0; + + krb5_free_error(context, krb_error); + + goto fail; + } + + if (resp_flags & KG2_RESP_FLAG_DELEG_OK) + ctx->gss_flags |= GSS_C_DELEG_FLAG; + + /* drop through to ap_rep handling */ + } else { + /* gsskrb5 v1 */ + + if ((err = g_verify_token_header((gss_OID) mech_type, + &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length))) { if (g_verify_token_header((gss_OID) mech_type, &(ap_rep.length), &ptr, KG_TOK_CTX_ERROR, input_token->length) == 0) { - /* Handle a KRB_ERROR message from the server */ + /* Handle a KRB_ERROR message from the server */ - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); - code = krb5_rd_error(context, &ap_rep, &krb_error); - if (code) - goto fail; - if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; - else - code = 0; - krb5_free_error(context, krb_error); + code = krb5_rd_error(context, &ap_rep, &krb_error); + if (code) goto fail; + if (krb_error->error) + code = krb_error->error + ERROR_TABLE_BASE_krb5; + else + code = 0; + krb5_free_error(context, krb_error); + goto fail; } else { - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); } - } + } - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + } /* decode the ap_rep */ - if ((code = krb5_rd_rep(context,ctx->auth_context,&ap_rep, + if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, &ap_rep_data))) { - /* - * XXX A hack for backwards compatiblity. - * To be removed in 1999 -- proven - */ - krb5_auth_con_setuseruserkey(context,ctx->auth_context,ctx->subkey); - if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, - &ap_rep_data))) - goto fail; + /* + * XXX A hack for backwards compatiblity. + * To be removed in 1999 -- proven + */ + krb5_auth_con_setuseruserkey(context, ctx->auth_context, + ctx->subkey); + if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, + &ap_rep_data))) + goto fail; } /* store away the sequence number */ @@ -593,6 +974,25 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, /* set established */ ctx->established = 1; + if (ctx->gsskrb5_version == 2000) { + gss_buffer_desc mic_data, mic_token; + + /* start with the token id */ + mic_data.value = ptr-2; + /* end before the ap-rep length */ + mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2)); + + mic_token.length = mic.length; + mic_token.value = mic.data; + + if (GSS_ERROR(major_status = + krb5_gss_verify_mic(minor_status, *context_handle, + &mic_data, &mic_token, NULL))) { + (void)krb5_gss_delete_sec_context(&dummy, context_handle, NULL); + return(major_status); + } + } + /* set returns */ if (time_rec) { @@ -602,7 +1002,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, } if (ret_flags) - *ret_flags = KG_IMPLFLAGS(req_flags); + *ret_flags = ctx->gss_flags; if (actual_mech_type) *actual_mech_type = mech_type; @@ -616,8 +1016,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, return(GSS_S_COMPLETE); fail: - (void)krb5_gss_delete_sec_context(minor_status, - (gss_ctx_id_t) ctx, NULL); + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *minor_status = code; return(GSS_S_FAILURE); } diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index ee5d436c1..c800012c8 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" OM_uint32 @@ -39,6 +65,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, krb5_deltat lifetime; krb5_principal ret_name; gss_OID_set mechs; + OM_uint32 ret; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -84,12 +111,26 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, } } - if (mechanisms) - if (! g_copy_OID_set(cred->actual_mechs, &mechs)) { - krb5_free_principal(context, ret_name); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + if (mechanisms) { + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, + &mechs)) || + (cred->prerfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_old, + &mechs))) || + (cred->rfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5, + &mechs))) || + (cred->rfcv2_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_v2, + &mechs)))) { + krb5_free_principal(context, ret_name); + /* *minor_status set above */ + return(ret); + } + } if (name) { if (! kg_save_name((gss_name_t) ret_name)) { @@ -139,7 +180,9 @@ krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, * We only know how to handle our own creds. */ if ((mech_type != GSS_C_NULL_OID) && - !g_OID_equal(gss_mech_krb5, mech_type)) { + !g_OID_equal(gss_mech_krb5_old, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_v2, mech_type)) { *minor_status = 0; return(GSS_S_NO_CRED); } diff --git a/src/lib/gssapi/krb5/inq_names.c b/src/lib/gssapi/krb5/inq_names.c index 9c5f47450..01a199430 100644 --- a/src/lib/gssapi/krb5/inq_names.c +++ b/src/lib/gssapi/krb5/inq_names.c @@ -43,10 +43,11 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) * We only know how to handle our own mechanism. */ if ((mechanism != GSS_C_NULL_OID) && + !g_OID_equal(gss_mech_krb5_v2, mechanism) && !g_OID_equal(gss_mech_krb5, mechanism) && !g_OID_equal(gss_mech_krb5_old, mechanism)) { *minor_status = 0; - return(GSS_S_FAILURE); + return(GSS_S_BAD_MECH); } /* We're okay. Create an empty OID set */ diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index c174bb7cb..e1877b71f 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -20,15 +20,269 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" static krb5_error_code -make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, - signalg, cksum_size, sealalg, encrypt, toktype, - bigend, oid) +make_priv_token_v2 PROTOTYPE((krb5_context context, + krb5_keyblock *subkey, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + gss_OID oid)); + +static krb5_error_code +make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid) krb5_context context; - krb5_gss_enc_desc *enc_ed; - krb5_gss_enc_desc *seq_ed; + krb5_keyblock *subkey; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + gss_OID oid; +{ + krb5_data plain; + krb5_enc_data cipher; + krb5_error_code code; + size_t enclen; + int tlen; + unsigned char *t, *ptr; + + plain.data = 0; + cipher.ciphertext.data = 0; + t = 0; + + plain.length = 7+text->length; + if ((plain.data = (void *) malloc(plain.length)) == NULL) { + code = ENOMEM; + goto cleanup; + } + + plain.data[0] = (*seqnum >> 24) & 0xff; + plain.data[1] = (*seqnum >> 16) & 0xff; + plain.data[2] = (*seqnum >> 8) & 0xff; + plain.data[3] = *seqnum & 0xff; + + plain.data[4] = direction?0:0xff; + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_encrypt_length(context, subkey->enctype, + plain.length, &enclen)) + goto cleanup; + + tlen = g_token_size((gss_OID) oid, 2+enclen); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); + + ptr = t; + + g_make_token_header((gss_OID) oid, 2+enclen, &ptr, + KG2_TOK_WRAP_PRIV); + + ptr[0] = (enclen >> 8) & 0xff; + ptr[1] = enclen & 0xff; + + cipher.ciphertext.length = enclen; + cipher.ciphertext.data = ptr+2; + + if (code = krb5_c_encrypt(context, subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, + 0, &plain, &cipher)) + goto cleanup; + + /* that's it. return the token */ + + (*seqnum)++; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (plain.data) + free(plain.data); + if (code) { + if (t) + free(t); + } + + return(code); +} + +static krb5_error_code +make_integ_token_v2 PROTOTYPE((krb5_context context, + krb5_keyblock *subkey, + krb5_cksumtype ctype, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + int toktype, + gss_OID oid)); + +static krb5_error_code +make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, + toktype, oid) + krb5_context context; + krb5_keyblock *subkey; + krb5_cksumtype ctype; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + int toktype; + gss_OID oid; +{ + krb5_error_code code; + int tmp, tlen; + unsigned char *t, *ptr; + krb5_data plain; + krb5_checksum cksum; + + plain.data = 0; + t = 0; + cksum.contents = 0; + + /* assemble the checksum buffer and compute the checksum */ + + plain.length = 7+text->length; + + if ((plain.data = (char *) malloc(plain.length)) == NULL) + goto cleanup; + + plain.data[0] = (*seqnum >> 24) & 0xff; + plain.data[1] = (*seqnum >> 16) & 0xff; + plain.data[2] = (*seqnum >> 8) & 0xff; + plain.data[3] = *seqnum & 0xff; + + plain.data[4] = direction?0:0xff; + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_make_checksum(context, ctype, subkey, + (toktype == KG2_TOK_WRAP_INTEG)? + KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG: + KRB5_KEYUSAGE_GSS_TOK_MIC, + &plain, &cksum)) + goto cleanup; + + /* assemble the token itself */ + + if (toktype == KG2_TOK_WRAP_INTEG) + tmp = 4+(7+text->length)+2+cksum.length; + else + tmp = 4+(5)+2+cksum.length; + + tlen = g_token_size((gss_OID) oid, tmp); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); + + ptr = t; + + g_make_token_header((gss_OID) oid, tmp, &ptr, toktype); + + ptr[0] = (ctype >> 24) & 0xff; + ptr[1] = (ctype >> 16) & 0xff; + ptr[2] = (ctype >> 8) & 0xff; + ptr[3] = ctype & 0xff; + + ptr += 4; + + if (toktype == KG2_TOK_WRAP_INTEG) { + memcpy(ptr, plain.data, 7+text->length); + ptr += 7+text->length; + } else { + memcpy(ptr, plain.data, 5); + ptr += 5; + } + + ptr[0] = (cksum.length >> 8) & 0xff; + ptr[1] = cksum.length & 0xff; + ptr += 2; + + memcpy(ptr, cksum.contents, cksum.length); + + /* that's it. return the token */ + + (*seqnum)++; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (plain.data) + free(plain.data); + if (cksum.contents) + krb5_free_checksum_contents(context, &cksum); + if (code) { + if (t) + free(t); + } + + return(code); +} + +static krb5_error_code +make_seal_token_v1 PROTOTYPE((krb5_context context, + krb5_keyblock *enc, + krb5_keyblock *seq, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + int signalg, + int cksum_size, + int sealalg, + int encrypt, + int toktype, + int bigend, + gss_OID oid)); + +static krb5_error_code +make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, + signalg, cksum_size, sealalg, encrypt, toktype, + bigend, oid) + krb5_context context; + krb5_keyblock *enc; + krb5_keyblock *seq; krb5_int32 *seqnum; int direction; gss_buffer_t text; @@ -42,7 +296,9 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, gss_OID oid; { krb5_error_code code; + size_t sumlen; char *data_ptr; + krb5_data plaind; krb5_checksum md5cksum; krb5_checksum cksum; int conflen=0, tmsglen, tlen; @@ -54,7 +310,7 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, if (bigend && !encrypt) { tmsglen = text->length; } else { - conflen = kg_confounder_size(enc_ed); + conflen = kg_confounder_size(context, enc); /* XXX knows that des block size is 8 */ tmsglen = (conflen+text->length+8)&(~7); } @@ -96,27 +352,24 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* pad the plaintext, encrypt if needed, and stick it in the token */ - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { - return(ENOMEM); - } - + md5cksum.length = sumlen; if (toktype == KG_TOK_SEAL_MSG) { unsigned char *plain; unsigned char pad; if (!bigend || encrypt) { if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } - if ((code = kg_make_confounder(enc_ed, plain))) { + if ((code = kg_make_confounder(context, enc, plain))) { xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); } @@ -133,12 +386,11 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, } if (encrypt) { - if ((code = kg_encrypt(context, enc_ed, NULL, (krb5_pointer) plain, + if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain, (krb5_pointer) (ptr+cksum_size+14), tmsglen))) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); } @@ -156,7 +408,6 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } @@ -165,15 +416,15 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, (void) memcpy(data_ptr+8, text->value, text->length); else (void) memcpy(data_ptr+8, plain, tmsglen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, - 8 + (bigend ? text->length : tmsglen), - 0, 0, &md5cksum); + plaind.length = 8 + (bigend ? text->length : tmsglen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + 0, 0, &plaind, &md5cksum); xfree(data_ptr); if (code) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); memcpy(ptr+14+cksum_size, plain, tmsglen); @@ -185,18 +436,17 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* compute the checksum */ if (! (data_ptr = (char *) xmalloc(8 + text->length))) { - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } (void) memcpy(data_ptr, ptr-2, 8); (void) memcpy(data_ptr+8, text->value, text->length); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, - 8 + text->length, - 0, 0, &md5cksum); + plaind.length = 8 + text->length; + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); xfree(t); return(code); } @@ -214,16 +464,19 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, DES encryption the long way, and keep the last block as the MAC */ + /* XXX not converted to new api since it's inside an #if 0 */ + /* initialize the the cksum and allocate the contents buffer */ cksum.checksum_type = CKSUMTYPE_DESCBC; cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) return(ENOMEM); + /* XXX not converted to new api since it's inside an #if 0 */ if (code = krb5_calculate_checksum(context, cksum.checksum_type, md5cksum.contents, 16, - seq_ed->key->contents, - seq_ed->key->length, + seq->contents, + seq->length, &cksum)) { xfree(cksum.contents); xfree(md5cksum.contents); @@ -235,9 +488,9 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, xfree(cksum.contents); #else - if ((code = kg_encrypt(context, seq_ed, + if ((code = kg_encrypt(context, seq, (g_OID_equal(oid, gss_mech_krb5_old) ? - seq_ed->key->contents : NULL), + seq->contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { xfree(md5cksum.contents); xfree(t); @@ -257,7 +510,7 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* create the seq_num */ - if ((code = kg_make_seq_num(context, seq_ed, direction?0:0xff, *seqnum, + if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, ptr+14, ptr+6))) { xfree(t); return(code); @@ -320,17 +573,42 @@ kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, return(GSS_S_FAILURE); } - if ((code = make_seal_token(context, &ctx->enc, &ctx->seq, - &ctx->seq_send, ctx->initiate, - input_message_buffer, output_message_buffer, - ctx->signalg, ctx->cksum_size, ctx->sealalg, - conf_req_flag, toktype, ctx->big_endian, - ctx->mech_used))) { + if (ctx->gsskrb5_version == 2000) { + if (toktype == KG_TOK_WRAP_MSG) { + if (conf_req_flag) + toktype = KG2_TOK_WRAP_PRIV; + else + toktype = KG2_TOK_WRAP_INTEG; + } else { + toktype = KG2_TOK_MIC; + } + + if (conf_req_flag) { + code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send, + ctx->initiate, input_message_buffer, + output_message_buffer, ctx->mech_used); + } else { + code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0], + &ctx->seq_send, ctx->initiate, + input_message_buffer, + output_message_buffer, toktype, + ctx->mech_used); + } + } else { + code = make_seal_token_v1(context, ctx->enc, ctx->seq, + &ctx->seq_send, ctx->initiate, + input_message_buffer, output_message_buffer, + ctx->signalg, ctx->cksum_size, ctx->sealalg, + conf_req_flag, toktype, ctx->big_endian, + ctx->mech_used); + } + + if (code) { *minor_status = code; return(GSS_S_FAILURE); } - if ((toktype == KG_TOK_SEAL_MSG) && conf_state) + if (conf_state) *conf_state = conf_req_flag; *minor_status = 0; diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 041cae06a..c32e3255d 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" #include @@ -27,34 +53,417 @@ * $Id$ */ +static OM_uint32 +kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, + text, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t text; + gss_qop_t *qop_state; +{ + size_t cksumlen; + krb5_error_code code; + krb5_data plain; + krb5_cksumtype tctype; + krb5_ui_4 tseqnum; + int tdirection; + krb5_checksum cksum; + krb5_boolean ckvalid; + krb5_timestamp now; + OM_uint32 retval; + + plain.data = 0; + cksum.contents = 0; + + /* verify the header */ + + if (bodysize < 11) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + /* allocate the checksum buffer */ + + plain.length = 7+text->length; + + if ((plain.data = (char *) malloc(plain.length)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + /* suck out the body parts from the token */ + + tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + + memcpy(plain.data, ptr, 5); + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + cksum.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 11; + + if (cksum.length != bodysize) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cksum.contents = ptr; + cksum.checksum_type = tctype; + + /* finish assembling the checksum buffer and compute the checksum */ + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_MIC, + &plain, &cksum, &ckvalid)) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (!ckvalid) { + free(plain.data); + *minor_status = 0; + return(GSS_S_BAD_SIG); + } + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + free(plain.data); + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + free(plain.data); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + retval = g_order_check(&(ctx->seqstate), tseqnum); + + free(plain.data); + + if (retval) { + *minor_status = 0; + return(retval); + } + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +static OM_uint32 +kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t output; + gss_qop_t *qop_state; +{ + krb5_error_code code; + OM_uint32 retval; + krb5_ui_4 tseqnum; + int tdirection; + int tmsglen; + unsigned char *tmsg; + krb5_data plain; + krb5_checksum tcksum; + krb5_boolean ckvalid; + krb5_timestamp now; + + output->length = 0; + output->value = NULL; + + /* read the body parts out of the message */ + + if (bodysize < 11) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + + plain.data = ptr; + + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + tmsglen = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 11; + + if (bodysize < tmsglen) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tmsg = ptr; + ptr += tmsglen; + bodysize -= tmsglen; + + plain.length = ((char*)ptr) - ((char *)plain.data); + + tcksum.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 2; + + if (bodysize != tcksum.length) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tcksum.contents = ptr; + + /* verify the MIC */ + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG, + &plain, &tcksum, &ckvalid)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (!ckvalid) { + *minor_status = 0; + return(GSS_S_BAD_SIG); + } + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { + *minor_status = 0; + return(retval); + } + + if ((output->value = (void *) malloc(tmsglen)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(output->value, tmsg, tmsglen); + output->length = tmsglen; + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +static OM_uint32 +kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t output; + gss_qop_t *qop_state; +{ + krb5_error_code code; + OM_uint32 retval; + krb5_enc_data cipher; + krb5_data plain; + krb5_ui_4 tseqnum; + int tdirection; + int tmsglen; + unsigned char *tmsg; + krb5_timestamp now; + + output->length = 0; + output->value = NULL; + + /* read the body parts out of the message */ + + if (bodysize < 2) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cipher.ciphertext.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 2; + + if (bodysize != cipher.ciphertext.length) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cipher.ciphertext.data = ptr; + cipher.enctype = ENCTYPE_UNKNOWN; + + plain.length = cipher.ciphertext.length; + if ((plain.data = (char *) malloc(plain.length)) == NULL) { + *minor_status = 0; + return(GSS_S_FAILURE); + } + + /* decrypt (and implicitly verify) the encrypted data */ + + if (code = krb5_c_decrypt(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, + 0, &cipher, &plain)) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* parse out the encrypted fields */ + + ptr = plain.data; + bodysize = plain.length; + + if (bodysize < 7) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + tmsglen = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 7; + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + free(plain.data); + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + free(plain.data); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { + free(plain.data); + *minor_status = 0; + return(retval); + } + + /* now copy out the data. can't do a strict equality check here, + since the output could be padded. */ + + if (bodysize < tmsglen) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tmsg = ptr; + + if ((output->value = (void *) malloc(tmsglen)) == NULL) { + free(plain.data); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(output->value, tmsg, tmsglen); + output->length = tmsglen; + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + free(plain.data); + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX - conf_state is only valid if SEAL. - */ + conf_state is only valid if SEAL. */ OM_uint32 -kg_unseal(context, minor_status, context_handle, input_token_buffer, - message_buffer, conf_state, qop_state, toktype) +kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, + conf_state, qop_state, toktype) krb5_context context; OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_token_buffer; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; gss_buffer_t message_buffer; int *conf_state; int *qop_state; int toktype; { - krb5_gss_ctx_id_rec *ctx; krb5_error_code code; - int bodysize; int tmsglen; int conflen = 0; int signalg; int sealalg; gss_buffer_desc token; - unsigned char *ptr; krb5_checksum cksum; krb5_checksum desmac; krb5_checksum md5cksum; + krb5_data plaind; char *data_ptr; krb5_timestamp now; unsigned char *plain; @@ -64,38 +473,13 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, int direction; krb5_int32 seqnum; OM_uint32 retval; + size_t sumlen; if (toktype == KG_TOK_SEAL_MSG) { message_buffer->length = 0; message_buffer->value = NULL; } - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - /* parse the token, leave the data in message_buffer, setting conf_state */ - - /* verify the header */ - - ptr = (unsigned char *) input_token_buffer->value; - - if ((err = g_verify_token_header((gss_OID) ctx->mech_used, &bodysize, - &ptr, toktype, - input_token_buffer->length))) { - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); - } - /* get the sign and seal algorithms */ signalg = ptr[0] + (ptr[1]<<8); @@ -159,7 +543,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, return(GSS_S_FAILURE); } - if ((code = kg_decrypt(context, &ctx->enc, NULL, + if ((code = kg_decrypt(context, ctx->enc, NULL, ptr+14+cksum_len, plain, tmsglen))) { xfree(plain); *minor_status = code; @@ -174,7 +558,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, if ((sealalg == 0xffff) && ctx->big_endian) { token.length = tmsglen; } else { - conflen = kg_confounder_size(&ctx->enc); + conflen = kg_confounder_size(context, ctx->enc); token.length = tmsglen - conflen - plain[tmsglen-1]; } @@ -200,15 +584,12 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, /* compute the checksum of the message */ - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { - if (sealalg != 0xffff) - xfree(plain); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + md5cksum.length = sumlen; switch (signalg) { case 0: @@ -219,7 +600,6 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, if (! (data_ptr = (void *) xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { - xfree(md5cksum.contents); if (sealalg != 0xffff) xfree(plain); if (toktype == KG_TOK_SEAL_MSG) @@ -235,14 +615,13 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, else (void) memcpy(data_ptr+8, plain, plainlen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, - data_ptr, 8 + - (ctx->big_endian ? token.length : - plainlen), 0, 0, &md5cksum); + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); *minor_status = code; @@ -264,6 +643,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, return(GSS_S_FAILURE); } + /* XXX not converted to new api since it's inside an #if 0 */ if (code = krb5_calculate_checksum(context, cksum.checksum_type, md5cksum.contents, 16, ctx->seq.key->contents, @@ -281,9 +661,9 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, xfree(cksum.contents); #else - if ((code = kg_encrypt(context, &ctx->seq, + if ((code = kg_encrypt(context, ctx->seq, (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq.key->contents : NULL), + ctx->seq->contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { xfree(md5cksum.contents); if (toktype == KG_TOK_SEAL_MSG) @@ -333,15 +713,15 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, else (void) memcpy(data_ptr+8+sizeof(ctx->seed), plain, plainlen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, - data_ptr, 8 + sizeof(ctx->seed) + - (ctx->big_endian ? token.length : - plainlen), 0, 0, &md5cksum); - + plaind.length = 8 + sizeof(ctx->seed) + + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + xfree(md5cksum.contents); + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); if (sealalg == 0) xfree(plain); if (toktype == KG_TOK_SEAL_MSG) @@ -394,7 +774,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, /* do sequencing checks */ - if ((code = kg_get_seq_num(context, &(ctx->seq), ptr+14, ptr+6, &direction, + if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, &seqnum))) { if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); @@ -417,3 +797,88 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, *minor_status = 0; return(retval); } + +/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX + conf_state is only valid if SEAL. */ + +OM_uint32 +kg_unseal(context, minor_status, context_handle, input_token_buffer, + message_buffer, conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_token_buffer; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; +{ + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + int err; + OM_uint32 retval; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } + + /* parse the token, leave the data in message_buffer, setting conf_state */ + + /* verify the header */ + + ptr = (unsigned char *) input_token_buffer->value; + + if (ctx->gsskrb5_version == 2000) { + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, KG2_TOK_MIC, + input_token_buffer->length))) { + return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, + message_buffer, qop_state)); + } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, + KG2_TOK_WRAP_INTEG, + input_token_buffer->length))) { + if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status, + ctx, ptr, bodysize, + message_buffer, qop_state))) + return(retval); + + if (conf_state) + *conf_state = 0; + return(GSS_S_COMPLETE); + } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, + KG2_TOK_WRAP_PRIV, + input_token_buffer->length))) { + if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status, + ctx, ptr, bodysize, + message_buffer, qop_state))) + return(retval); + + if (conf_state) + *conf_state = 1; + return(GSS_S_COMPLETE); + } + } else { + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, toktype, + input_token_buffer->length))) { + return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, + message_buffer, conf_state, qop_state, + toktype)); + } + } + + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); +} diff --git a/src/lib/gssapi/krb5/rel_oid.c b/src/lib/gssapi/krb5/rel_oid.c index f35727e3f..afb2171b8 100644 --- a/src/lib/gssapi/krb5/rel_oid.c +++ b/src/lib/gssapi/krb5/rel_oid.c @@ -63,7 +63,8 @@ krb5_gss_internal_release_oid(minor_status, oid) * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize. */ - if ((*oid != gss_mech_krb5) && + if ((*oid != gss_mech_krb5_v2) && + (*oid != gss_mech_krb5) && (*oid != gss_mech_krb5_old) && (*oid != gss_nt_krb5_name) && (*oid != gss_nt_krb5_principal)) { diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 36e70d742..36a16d426 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -40,192 +40,6 @@ * still be done. --marc */ -/* - * Determine the size required for this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_size(kcontext, arg, sizep) - krb5_context kcontext; - krb5_pointer arg; - size_t *sizep; -{ - krb5_error_code kret; - krb5_gss_enc_desc *edescp; - size_t required; - - /* - * krb5_gss_cred_id_t requires: - * krb5_int32 for KG_ENC_DESC - * krb5_int32 for processed. - * krb5_int32 for trailer. - */ - kret = EINVAL; - if ((edescp = (krb5_gss_enc_desc *) arg)) { - required = 3*sizeof(krb5_int32); - if (edescp->key) - kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) edescp->key, - &required); - else - kret = 0; - - /* - * We need to use size_opaque here because we're not sure as to the - * ancestry of this eblock, and we can't be sure that the magic number - * is set in it, so we ASSuME that it's ok. - */ - if (!kret) - kret = krb5_size_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer) &edescp->eblock, - &required); - - if (!kret) - *sizep += required; - } - return(kret); -} - -/* - * Externalize this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_externalize(kcontext, arg, buffer, lenremain) - krb5_context kcontext; - krb5_pointer arg; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_enc_desc *enc_desc; - size_t required; - krb5_octet *bp; - size_t remain; - - required = 0; - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - if ((enc_desc = (krb5_gss_enc_desc *) arg)) { - kret = ENOMEM; - if (!kg_enc_desc_size(kcontext, arg, &required) && - (required <= remain)) { - /* Our identifier */ - (void) krb5_ser_pack_int32(KG_ENC_DESC, &bp, &remain); - - /* Now static data */ - (void) krb5_ser_pack_int32((krb5_int32) enc_desc->processed, - &bp, &remain); - - /* Now pack up dynamic data */ - if (enc_desc->key) - kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) enc_desc->key, - &bp, &remain); - else - kret = 0; - - if (!kret) - kret = krb5_externalize_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer)&enc_desc->eblock, - &bp, &remain); - if (!kret) { - (void) krb5_ser_pack_int32(KG_ENC_DESC, &bp, &remain); - *buffer = bp; - *lenremain = remain; - } - } - } - return(kret); -} - -/* - * Internalize this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_internalize(kcontext, argp, buffer, lenremain) - krb5_context kcontext; - krb5_pointer *argp; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_enc_desc *edescp; - krb5_int32 ibuf; - krb5_octet *bp; - krb5_encrypt_block *eblockp; - size_t remain; - - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - /* Read our magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - ibuf = 0; - if (ibuf == KG_ENC_DESC) { - kret = ENOMEM; - - /* Get an enc_desc */ - if ((remain >= (2*sizeof(krb5_int32))) && - (edescp = (krb5_gss_enc_desc *) - xmalloc(sizeof(krb5_gss_enc_desc)))) { - memset(edescp, 0, sizeof(krb5_gss_enc_desc)); - - /* Get the static data */ - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - edescp->processed = (int) ibuf; - - /* edescp->key */ - if ((kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &edescp->key, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - - /* edescp->eblock */ - if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer *) &eblockp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - /* Successful, copy in allocated eblock to our structure */ - memcpy(&edescp->eblock, eblockp, sizeof(edescp->eblock)); - krb5_xfree(eblockp); - } - - /* trailer */ - if (!kret && - !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && - (ibuf == KG_ENC_DESC)) { - *buffer = bp; - *lenremain = remain; - *argp = (krb5_pointer) edescp; - } - else { - if (!kret && (ibuf != KG_ENC_DESC)) - kret = EINVAL; - if (edescp->eblock.key) - krb5_free_keyblock(kcontext, edescp->eblock.key); - if (edescp->eblock.priv && edescp->eblock.priv_size) - krb5_xfree(edescp->eblock.priv); - if (edescp->key) - krb5_free_keyblock(kcontext, edescp->key); - xfree(edescp); - } - } - } - return(kret); -} - static krb5_error_code kg_oid_externalize(kcontext, arg, buffer, lenremain) krb5_context kcontext; @@ -416,12 +230,15 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for seq_recv. * krb5_int32 for established. * krb5_int32 for big_endian. + * krb5_int32 for gsskrb5_version. + * krb5_int32 for nctypes. * krb5_int32 for trailer. */ kret = EINVAL; if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { - required = 14*sizeof(krb5_int32); + required = 16*sizeof(krb5_int32); required += sizeof(ctx->seed); + required += ctx->nctypes*sizeof(krb5_int32); kret = 0; if (!kret && ctx->here) @@ -442,14 +259,16 @@ kg_ctx_size(kcontext, arg, sizep) (krb5_pointer) ctx->subkey, &required); - if (!kret) - kret = kg_enc_desc_size(kcontext, - (krb5_pointer) &ctx->enc, + if (!kret && ctx->enc) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->enc, &required); - if (!kret) - kret = kg_enc_desc_size(kcontext, - (krb5_pointer) &ctx->seq, + if (!kret && ctx->seq) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->seq, &required); if (!kret) @@ -486,6 +305,7 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) size_t required; krb5_octet *bp; size_t remain; + int i; required = 0; bp = *buffer; @@ -526,6 +346,10 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes, + &bp, &remain); /* Now dynamic data */ kret = 0; @@ -552,14 +376,16 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) (krb5_pointer) ctx->subkey, &bp, &remain); - if (!kret) - kret = kg_enc_desc_externalize(kcontext, - (krb5_pointer) &ctx->enc, + if (!kret && ctx->enc) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->enc, &bp, &remain); - if (!kret) - kret = kg_enc_desc_externalize(kcontext, - (krb5_pointer) &ctx->seq, + if (!kret && ctx->seq) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->seq, &bp, &remain); if (!kret && ctx->seqstate) @@ -571,6 +397,13 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) KV5M_AUTH_CONTEXT, (krb5_pointer) ctx->auth_context, &bp, &remain); + + for (i=0; inctypes; i++) { + if (!kret) { + kret = krb5_ser_pack_int32((krb5_int32) ctx->ctypes[i], + &bp, &remain); + } + } if (!kret) { (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); @@ -597,7 +430,7 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) krb5_int32 ibuf; krb5_octet *bp; size_t remain; - krb5_gss_enc_desc *edp; + int i; bp = *buffer; remain = *lenremain; @@ -640,6 +473,10 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) ctx->established = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->big_endian = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->gsskrb5_version = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->nctypes = (int) ibuf; if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, &remain))) { @@ -670,29 +507,21 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) if (kret == EINVAL) kret = 0; } - if (!kret) { - if ((kret = kg_enc_desc_internalize(kcontext, - (krb5_pointer *) &edp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - memcpy(&ctx->enc, edp, sizeof(ctx->enc)); - xfree(edp); - } + if (!kret && + (kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) &ctx->enc, + &bp, &remain))) { + if (kret == EINVAL) + kret = 0; } - if (!kret) { - if ((kret = kg_enc_desc_internalize(kcontext, - (krb5_pointer *) &edp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - memcpy(&ctx->seq, edp, sizeof(ctx->seq)); - xfree(edp); - } + if (!kret && + (kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) &ctx->seq, + &bp, &remain))) { + if (kret == EINVAL) + kret = 0; } if (!kret) { @@ -708,6 +537,22 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (krb5_pointer *) &ctx->auth_context, &bp, &remain); + if (!kret) { + if (ctx->nctypes) { + if ((ctx->ctypes = (krb5_cksumtype *) + malloc(ctx->nctypes*sizeof(krb5_cksumtype))) == NULL){ + kret = ENOMEM; + } + + for (i=0; inctypes; i++) { + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->ctypes[i] = (krb5_cksumtype) ibuf; + } + } + } + } + /* Get trailer */ if (!kret && !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && @@ -719,18 +564,10 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) else { if (!kret && (ibuf != KG_CONTEXT)) kret = EINVAL; - if (ctx->seq.eblock.key) - krb5_free_keyblock(kcontext, ctx->seq.eblock.key); - if (ctx->seq.eblock.priv && ctx->seq.eblock.priv_size) - krb5_xfree(ctx->seq.eblock.priv); - if (ctx->seq.key) - krb5_free_keyblock(kcontext, ctx->seq.key); - if (ctx->enc.eblock.key) - krb5_free_keyblock(kcontext, ctx->enc.eblock.key); - if (ctx->enc.eblock.priv && ctx->enc.eblock.priv_size) - krb5_xfree(ctx->enc.eblock.priv); - if (ctx->enc.key) - krb5_free_keyblock(kcontext, ctx->enc.key); + if (ctx->seq) + krb5_free_keyblock(kcontext, ctx->seq); + if (ctx->enc) + krb5_free_keyblock(kcontext, ctx->enc); if (ctx->subkey) krb5_free_keyblock(kcontext, ctx->subkey); if (ctx->there) diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index 68561f10b..10e6b657f 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -36,20 +36,25 @@ kg_checksum_channel_bindings(context, cb, cksum, bigend) { int len; char *buf, *ptr; + size_t sumlen; + krb5_data plaind; krb5_error_code code; - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + cksum->checksum_type = CKSUMTYPE_RSA_MD5; - cksum->length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { - return(ENOMEM); - } + cksum->length = sumlen; /* generate a buffer full of zeros if no cb specified */ if (cb == GSS_C_NO_CHANNEL_BINDINGS) { - memset(cksum->contents, '\0', cksum->length); - return(0); + if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { + return(ENOMEM); + } + memset(cksum->contents, '\0', cksum->length); + return(0); } /* create the buffer to checksum into */ @@ -75,9 +80,11 @@ kg_checksum_channel_bindings(context, cb, cksum, bigend) /* checksum the data */ - if (code = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5, - buf, len, NULL, 0, cksum)) { - xfree(cksum->contents); + plaind.length = len; + plaind.data = buf; + + if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, + &plaind, cksum)) { xfree(buf); return(code); } diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 1684377ad..93d46946c 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "gssapiP_krb5.h" #include @@ -31,103 +57,126 @@ static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; int -kg_confounder_size(ed) - krb5_gss_enc_desc *ed; +kg_confounder_size(context, key) + krb5_context context; + krb5_keyblock *key; { - /* XXX Abstraction violation!!! */ + krb5_error_code code; + size_t blocksize; + + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(-1); /* XXX */ - return(ed->eblock.crypto_entry->block_length); + return(blocksize); } krb5_error_code -kg_make_confounder(ed, buf) - krb5_gss_enc_desc *ed; +kg_make_confounder(context, key, buf) + krb5_context context; + krb5_keyblock *key; unsigned char *buf; { - /* XXX Abstraction violation!!! */ + krb5_error_code code; + size_t blocksize; + krb5_data random; + + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); - return(krb5_random_confounder(ed->eblock.crypto_entry->block_length, buf)); + random.length = blocksize; + random.data = buf; + + return(krb5_c_random_make_octets(context, &random)); } int -kg_encrypt_size(ed, n) - krb5_gss_enc_desc *ed; +kg_encrypt_size(context, key, n) + krb5_context context; + krb5_keyblock *key; int n; { - return(krb5_encrypt_size(n, ed->eblock.crypto_entry)); + krb5_error_code code; + size_t enclen; + + if (code = krb5_c_encrypt_length(context, key->enctype, n, &enclen)) + return(-1); /* XXX */ + + return(enclen); } krb5_error_code -kg_encrypt(context, ed, iv, in, out, length) +kg_encrypt(context, key, iv, in, out, length) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; krb5_pointer iv; krb5_pointer in; krb5_pointer out; int length; { krb5_error_code code; - krb5_pointer tmp; - - if (! ed->processed) { - if (code = krb5_process_key(context, &ed->eblock, ed->key)) - return(code); - ed->processed = 1; + size_t blocksize; + krb5_data ivd, *pivd, inputd; + krb5_enc_data outputd; + + if (iv) { + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); + + ivd.length = blocksize; + ivd.data = iv; + pivd = &ivd; + } else { + pivd = NULL; } - /* this is lame. the krb5 encryption interfaces no longer allow - you to encrypt in place. perhaps this should be fixed, but - dealing here is easier for now --marc */ - - if ((tmp = (krb5_pointer) xmalloc(length)) == NULL) - return(ENOMEM); + inputd.length = length; + inputd.data = in; - memcpy(tmp, in, length); + outputd.ciphertext.length = length; + outputd.ciphertext.data = out; - code = krb5_encrypt(context, tmp, out, length, &ed->eblock, - iv?iv:(krb5_pointer)zeros); - - xfree(tmp); - - if (code) - return(code); - - return(0); + return(krb5_c_encrypt(context, key, + /* XXX this routine is only used for the old + bare-des stuff which doesn't use the + key usage */ 0, pivd, &inputd, &outputd)); } /* length is the length of the cleartext. */ krb5_error_code -kg_decrypt(context, ed, iv, in, out, length) +kg_decrypt(context, key, iv, in, out, length) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; krb5_pointer iv; krb5_pointer in; krb5_pointer out; int length; { krb5_error_code code; - int elen; - char *buf; - - if (! ed->processed) { - if (code = krb5_process_key(context, &ed->eblock, ed->key)) - return(code); - ed->processed = 1; + size_t blocksize, enclen; + krb5_data ivd, *pivd, outputd; + krb5_enc_data inputd; + + if (iv) { + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); + + ivd.length = blocksize; + ivd.data = iv; + pivd = &ivd; + } else { + pivd = NULL; } - elen = krb5_encrypt_size(length, ed->eblock.crypto_entry); - if ((buf = (char *) xmalloc(elen)) == NULL) - return(ENOMEM); - - if (code = krb5_decrypt(context, in, buf, elen, &ed->eblock, - iv?iv:(krb5_pointer)zeros)) { - xfree(buf); - return(code); - } + inputd.enctype = ENCTYPE_UNKNOWN; + inputd.ciphertext.length = length; + inputd.ciphertext.data = in; - memcpy(out, buf, length); - xfree(buf); + outputd.length = length; + outputd.data = out; - return(0); + return(krb5_c_decrypt(context, key, + /* XXX this routine is only used for the old + bare-des stuff which doesn't use the + key usage */ 0, pivd, &inputd, &outputd)); } diff --git a/src/lib/gssapi/krb5/util_ctxsetup.c b/src/lib/gssapi/krb5/util_ctxsetup.c new file mode 100644 index 000000000..0add6bf73 --- /dev/null +++ b/src/lib/gssapi/krb5/util_ctxsetup.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "gssapiP_krb5.h" + +/* from the token, flags is stored directly. nctypes/ctypes is + allocated and returns the length and list of ctypes in the token. + noptions/options lists all the options which the caller cares + about. Those which are present in the token are filled in; the + order and length are not changed. If an error is returned, the + option list is in an indeterminate state. */ + +OM_uint32 +kg2_parse_token(minor_status, ptr, token_length, flags, nctypes, ctypes, + noptions, options, kmsg, mic) + OM_uint32 *minor_status; + unsigned char *ptr; + int token_length; + krb5_ui_4 *flags; + int *nctypes; /* OUT */ + krb5_cksumtype **ctypes; /* OUT */ + int noptions; + struct kg2_option *options; /* INOUT */ + krb5_data *kmsg; + krb5_data *mic; +{ + int field_length, i; + int opt_id; + + *ctypes = 0; + + /* read the flags */ + + if (token_length < 4) + goto defective; + *flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; + ptr += 4; + token_length -= 4; + + /* read out the token list */ + + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + *nctypes = field_length; + + if (*nctypes == 0) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if ((*ctypes = (krb5_cksumtype *) + malloc((*nctypes) * sizeof(krb5_cksumtype))) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + for (i=0; ilength = field_length; + kmsg->data = ptr; + + ptr += field_length; + token_length -= field_length; + + /* if there's anything left, assume it's a mic. the mic isn't + necessarily present */ + + if (mic && token_length) { + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + if (token_length < field_length) + goto defective; + + mic->length = field_length; + mic->data = ptr; + + ptr += field_length; + token_length -= field_length; + } else if (mic) { + mic->length = 0; + mic->data = ptr; + } + + if (token_length) + goto defective; + + return(GSS_S_COMPLETE); + +defective: + if (*ctypes) + free(*ctypes); + + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); +} + +/* nc1/c1 will be modified to contain the intersection of the + two lists. */ + +void +kg2_intersect_ctypes(nc1, c1, nc2, c2) + int *nc1; + krb5_cksumtype *c1; + int nc2; + const krb5_cksumtype *c2; +{ + int i, j, count; + krb5_cksumtype tmp; + + count = 0; + + for (i=0; i<*nc1; i++) { + /* first, check to make sure that c1[i] isn't a duplicate in c1 */ + for (j=0; jlength; i++) - ed.key->contents[i] = key->contents[key->length - 1 - i]; + for (i=0; ilength; i++) + tmpkey->contents[i] = key->contents[key->length - 1 - i]; - krb5_use_enctype(context, &ed.eblock, ENCTYPE_DES_CBC_RAW); - ed.processed = 0; + code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16); - code = kg_encrypt(context, &ed, NULL, zeros, seed, 16); - - krb5_finish_key(context, &ed.eblock); - krb5_free_keyblock(context, ed.key); + krb5_free_keyblock(context, tmpkey); return(code); } diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index ed9293f77..e14b2f3fe 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -27,9 +27,9 @@ */ krb5_error_code -kg_make_seq_num(context, ed, direction, seqnum, cksum, buf) +kg_make_seq_num(context, key, direction, seqnum, cksum, buf) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; int direction; krb5_int32 seqnum; unsigned char *cksum; @@ -47,12 +47,12 @@ kg_make_seq_num(context, ed, direction, seqnum, cksum, buf) plain[6] = direction; plain[7] = direction; - return(kg_encrypt(context, ed, cksum, plain, buf, 8)); + return(kg_encrypt(context, key, cksum, plain, buf, 8)); } -krb5_error_code kg_get_seq_num(context, ed, cksum, buf, direction, seqnum) +krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; unsigned char *cksum; unsigned char *buf; int *direction; @@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, ed, cksum, buf, direction, seqnum) krb5_error_code code; unsigned char plain[8]; - if (code = kg_decrypt(context, ed, cksum, buf, plain, 8)) + if (code = kg_decrypt(context, key, cksum, buf, plain, 8)) return(code); if ((plain[4] != plain[5]) || diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index f2366d16e..745949260 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "gssapiP_krb5.h" /* @@ -39,8 +65,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, { krb5_context context; krb5_gss_ctx_id_rec *ctx; - OM_uint32 cfsize; - OM_uint32 ohlen; + krb5_error_code code; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -63,19 +88,86 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, return(GSS_S_NO_CONTEXT); } - /* Calculate the token size and subtract that from the output size */ - cfsize = (conf_req_flag) ? kg_confounder_size(&ctx->enc) : 0; - ohlen = g_token_size((gss_OID) ctx->mech_used, - (unsigned int) cfsize + ctx->cksum_size + 14); + if (ctx->gsskrb5_version == 2000) { + if (conf_req_flag) { + /* this is pretty gross. take the max output, and call + krb5_c_encrypt_length to see how much overhead is added + on. subtract that much, and see if it fits in the + requested space. If not, start subtracting 1 until it + does. This doesn't necessarily give us the optimal + packing, but I think that's ok (I could start adding 1 + until I went over, but that seems like it's not worth + the effort). This is probably O(blocksize), but that's + never going to be large. */ + + OM_uint32 headerlen, plainlen; + size_t enclen; + + headerlen = g_token_size((gss_OID) ctx->mech_used, 2); + plainlen = req_output_size - headerlen; + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + plainlen -= plainlen - (enclen - plainlen); + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } - if (ohlen < req_output_size) + while (headerlen + enclen > req_output_size) { + plainlen--; + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + /* subtract off the fixed size inside the encrypted part */ + + plainlen -= 7; + + *max_input_size = plainlen; + } else { + size_t cksumlen; + OM_uint32 headerlen; + + if (code = krb5_c_checksum_length(context, ctx->ctypes[0], + &cksumlen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen); + + *max_input_size = req_output_size - headerlen; + } + } else { + OM_uint32 cfsize; + OM_uint32 ohlen; + + /* Calculate the token size and subtract that from the output size */ + cfsize = (conf_req_flag) ? kg_confounder_size(context, ctx->enc) : 0; + ohlen = g_token_size((gss_OID) ctx->mech_used, + (unsigned int) cfsize + ctx->cksum_size + 14); + + if (ohlen < req_output_size) /* * Cannot have trailer length that will cause us to pad over * our length */ *max_input_size = (req_output_size - ohlen - 1) & (~7); - else + else *max_input_size = 0; + } + *minor_status = 0; return(GSS_S_COMPLETE); } diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index ae8bb7e1b..64dc648d6 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,14 @@ +Thu Aug 13 17:21:06 1998 Tom Yu + + * alt_prof.c (krb5_read_realm_params): Fix to check + "supported_enctypes" if "kdc_supported_enctypes" isn't there. + +Wed Aug 12 20:19:08 1998 Tom Yu + + * alt_prof.c (krb5_read_realm_params): Use + "kdc_supported_enctypes" instead of "supported_enctypes" so that + the KDC and the kadmind will use different enctype lists. + Wed Jul 8 04:48:50 1998 Geoffrey J. King * logger.c: Add the function krb5_klog_reopen() which closes diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index b2260d67a..934785322 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -866,8 +866,15 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp) } /* Get the value for the supported enctype/salttype matrix */ - hierarchy[2] = "supported_enctypes"; - if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { + /* XXX This is so that the kdc will search a different + enctype list than kadmind */ + hierarchy[2] = "kdc_supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + if (kret) { + hierarchy[2] = "supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + } + if (!kret) { krb5_string_to_keysalts(svalue, ", \t", /* Tuple separators */ ":.-", /* Key/salt separators */ diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index e1e761ce5..5f46d2185 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,12 @@ +1998-10-27 Marc Horowitz + + * client_init.c (_kadm5_init_any): try the krb5 v2 mechanism + first, and if that fails, try the krb5 v1 mech. + +Sun Jul 26 18:11:56 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:05:57 1998 Tom Yu * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in index 662bc7601..b125ea7a1 100644 --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in @@ -3,7 +3,7 @@ BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) CFLAGS = $(CCOPTS) $(DEFS) -I$(BUILDTOP)/include/kadm5 LIB=kadm5clnt -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index 11cd77c74..96c5907af 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -4,6 +4,32 @@ * $Header$ */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #if !defined(lint) && !defined(__CODECENTER__) static char *rcsid = "$Header$"; #endif @@ -444,12 +470,26 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, &minor_stat, gss_client_creds, gss_target, - GSS_C_NULL_OID, + gss_mech_krb5_v2, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + 0, + NULL, + NULL, + NULL); + + if (!handle->clnt->cl_auth) + handle->clnt->cl_auth = auth_gssapi_create(handle->clnt, + &gssstat, + &minor_stat, + gss_client_creds, + gss_target, + gss_mech_krb5, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, NULL, NULL, NULL); + (void) gss_release_name(&minor_stat, &gss_target); #endif /* ! INIT_TEST */ diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index 04011541b..67dbe3842 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,11 @@ +1998-10-27 Marc Horowitz + + * server_kdb.c, svr_principal.c: convert to new crypto api + +Sun Jul 26 18:09:55 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:06:14 1998 Tom Yu * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in index ff6552bd7..53e469863 100644 --- a/src/lib/kadm5/srv/Makefile.in +++ b/src/lib/kadm5/srv/Makefile.in @@ -6,7 +6,7 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(BUILDTOP)/include/kadm5 @HESIOD_DEFS@ ##DOSLIBNAME = libkadm5srv.lib LIB=kadm5srv -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index 1a900a380..2487f88e0 100644 --- a/src/lib/kadm5/srv/server_kdb.c +++ b/src/lib/kadm5/srv/server_kdb.c @@ -15,12 +15,10 @@ static char *rcsid = "$Header$"; #include "server_internal.h" krb5_principal master_princ; -krb5_encrypt_block master_encblock; krb5_keyblock master_keyblock; krb5_db_entry master_db; krb5_principal hist_princ; -krb5_encrypt_block hist_encblock; krb5_keyblock hist_key; krb5_db_entry hist_db; krb5_kvno hist_kvno; @@ -49,11 +47,8 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, master_keyblock.enctype = handle->params.enctype; - krb5_use_enctype(handle->context, &master_encblock, - master_keyblock.enctype); - if (ret = krb5_db_fetch_mkey(handle->context, master_princ, - &master_encblock, from_keyboard, + master_keyblock.enctype, from_keyboard, FALSE /* only prompt once */, handle->params.stash_file, NULL /* I'm not sure about this, @@ -65,21 +60,11 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, goto done; if ((ret = krb5_db_verify_master_key(handle->context, master_princ, - &master_keyblock, - &master_encblock))) { + &master_keyblock))) { krb5_db_fini(handle->context); return ret; } - /* the kdc gets the db mkvno here. The admin server never uses this - bit of information, so there's no reason to retrieve it. */ - - if ((ret = krb5_process_key(handle->context, &master_encblock, - &master_keyblock))) { - krb5_db_fini(handle->context); - goto done; - } - done: if (r == NULL) free(realm); @@ -190,16 +175,10 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r) &key_data)) goto done; - if (ret = krb5_dbekd_decrypt_key_data(handle->context, &master_encblock, + if (ret = krb5_dbekd_decrypt_key_data(handle->context, &master_keyblock, key_data, &hist_key, NULL)) goto done; - krb5_use_enctype(handle->context, &hist_encblock, hist_key.enctype); - - if ((ret = krb5_process_key(handle->context, &hist_encblock, - &hist_key)) != KSUCCESS) - goto done; - hist_kvno = key_data->key_data_kvno; done: diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index ee45723a4..9504556ff 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -22,8 +22,6 @@ static char *rcsid = "$Header$"; extern krb5_principal master_princ; extern krb5_principal hist_princ; -extern krb5_encrypt_block master_encblock; -extern krb5_encrypt_block hist_encblock; extern krb5_keyblock master_keyblock; extern krb5_keyblock hist_key; extern krb5_db_entry master_db; @@ -236,7 +234,7 @@ kadm5_create_principal(void *server_handle, /* initialize the keys */ - if (ret = krb5_dbe_cpw(handle->context, &master_encblock, + if (ret = krb5_dbe_cpw(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, password, @@ -816,20 +814,20 @@ done: * Arguments: * * context (r) the krb5 context - * histkey_encblock (r) the encblock that hist_key_data is + * hist_keyblock (r) the key that hist_key_data is * encrypted in * n_new_key_data (r) length of new_key_data * new_key_data (r) keys to check against - * pw_hist_data, encrypted in histkey_encblock + * pw_hist_data, encrypted in hist_keyblock * n_pw_hist_data (r) length of pw_hist_data * pw_hist_data (r) passwords to check new_key_data against * * Effects: * For each new_key in new_key_data: - * decrypt new_key with the master_encblock + * decrypt new_key with the master_keyblock * for each password in pw_hist_data: * for each hist_key in password: - * decrypt hist_key with histkey_encblock + * decrypt hist_key with hist_keyblock * compare the new_key and hist_key * * Returns krb5 errors, KADM5_PASS_RESUSE if a key in @@ -837,7 +835,7 @@ done: */ static kadm5_ret_t check_pw_reuse(krb5_context context, - krb5_encrypt_block *histkey_encblock, + krb5_keyblock *hist_keyblock, int n_new_key_data, krb5_key_data *new_key_data, int n_pw_hist_data, osa_pw_hist_ent *pw_hist_data) { @@ -847,7 +845,7 @@ check_pw_reuse(krb5_context context, for (x = 0; x < n_new_key_data; x++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &(new_key_data[x]), &newkey, NULL)) return(ret); @@ -855,7 +853,7 @@ check_pw_reuse(krb5_context context, for (z = 0; z < pw_hist_data[y].n_key_data; z++) { if (ret = krb5_dbekd_decrypt_key_data(context, - histkey_encblock, + hist_keyblock, &pw_hist_data[y].key_data[z], &histkey, NULL)) return(ret); @@ -894,8 +892,8 @@ check_pw_reuse(krb5_context context, * Effects: * * hist->key_data is allocated to store n_key_data key_datas. Each - * element of key_data is decrypted with master_encblock, re-encrypted - * in hist_encblock, and added to hist->key_data. hist->n_key_data is + * element of key_data is decrypted with master_keyblock, re-encrypted + * in hist_key, and added to hist->key_data. hist->n_key_data is * set to n_key_data. */ int create_history_entry(krb5_context context, int n_key_data, @@ -912,12 +910,12 @@ int create_history_entry(krb5_context context, int n_key_data, for (i = 0; i < n_key_data; i++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &key_data[i], &key, &salt)) return ret; if (ret = krb5_dbekd_encrypt_key_data(context, - &hist_encblock, + &hist_key, &key, &salt, key_data[i].key_data_kvno, &hist->key_data[i])) @@ -1052,7 +1050,7 @@ kadm5_chpass_principal(void *server_handle, KADM5_POLICY, &pol, principal))) goto done; - if (ret = krb5_dbe_cpw(handle->context, &master_encblock, + if (ret = krb5_dbe_cpw(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, password, 0 /* increment kvno */, &kdb)) @@ -1090,7 +1088,7 @@ kadm5_chpass_principal(void *server_handle, goto done; if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, 1, &hist)) goto done; @@ -1102,7 +1100,7 @@ kadm5_chpass_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1171,7 +1169,7 @@ kadm5_randkey_principal(void *server_handle, if ((ret = kdb_get_entry(handle, principal, &kdb, &adb))) return(ret); - if (ret = krb5_dbe_crk(handle->context, &master_encblock, + if (ret = krb5_dbe_crk(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, &kdb)) @@ -1213,7 +1211,7 @@ kadm5_randkey_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1316,7 +1314,7 @@ kadm5_setv4key_principal(void *server_handle, keysalt.data.data = NULL; if (ret = krb5_dbekd_encrypt_key_data(handle->context, - &master_encblock, + &master_keyblock, keyblock, &keysalt, kvno + 1, kdb.key_data)) { @@ -1361,7 +1359,7 @@ kadm5_setv4key_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1402,9 +1400,9 @@ kadm5_setkey_principal(void *server_handle, krb5_int32 now; kadm5_policy_ent_rec pol; krb5_key_data *key_data; - int i, kvno, ret, last_pwd, have_pol = 0; - int deskeys; + int i, j, kvno, ret, last_pwd, have_pol = 0; kadm5_server_handle_t handle = server_handle; + krb5_boolean similar; CHECK_HANDLE(server_handle); @@ -1415,14 +1413,16 @@ kadm5_setkey_principal(void *server_handle, principal, hist_princ)) == TRUE)) return KADM5_PROTECT_PRINCIPAL; - for (i = 0, deskeys = 0; i < n_keys; i++) { - if (keyblocks[i].enctype == ENCTYPE_DES_CBC_MD4 || - keyblocks[i].enctype == ENCTYPE_DES_CBC_MD5 || - keyblocks[i].enctype == ENCTYPE_DES_CBC_RAW || - keyblocks[i].enctype == ENCTYPE_DES_CBC_CRC) - deskeys++; - if (deskeys > 1) - return KADM5_SETKEY_DUP_ENCTYPES; + for (i = 0; i < n_keys; i++) { + for (j = i+1; j < n_keys; j++) { + if (ret = krb5_c_enctype_compare(handle->context, + keyblocks[i].enctype, + keyblocks[j].enctype, + &similar)) + return(ret); + if (similar) + return KADM5_SETKEY_DUP_ENCTYPES; + } } if ((ret = kdb_get_entry(handle, principal, &kdb, &adb))) @@ -1443,7 +1443,7 @@ kadm5_setkey_principal(void *server_handle, for (i = 0; i < n_keys; i++) { if (ret = krb5_dbekd_encrypt_key_data(handle->context, - &master_encblock, + &master_keyblock, &keyblocks[i], NULL, kvno + 1, &kdb.key_data[i])) @@ -1488,7 +1488,7 @@ kadm5_setkey_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1521,7 +1521,7 @@ done: /* * Allocate an array of n_key_data krb5_keyblocks, fill in each * element with the results of decrypting the nth key in key_data with - * master_encblock, and if n_keys is not NULL fill it in with the + * master_keyblock, and if n_keys is not NULL fill it in with the * number of keys decrypted. */ static int decrypt_key_data(krb5_context context, @@ -1538,7 +1538,7 @@ static int decrypt_key_data(krb5_context context, for (i = 0; i < n_key_data; i++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &key_data[i], &keys[i], NULL)) { @@ -1609,7 +1609,7 @@ kadm5_ret_t kadm5_decrypt_key(void *server_handle, return ret; if (ret = krb5_dbekd_decrypt_key_data(handle->context, - &master_encblock, key_data, + &master_keyblock, key_data, keyblock, keysalt)) return ret; diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index ec0b38457..e12270d5c 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,33 @@ +1998-10-27 Marc Horowitz + + * kdb_xdr.c, kdb_cpw.c: remove the special knowledge of ENCTYPE + string-to-key equivalances. the crypto api has a function for + this now. + + * decrypt_key.c, encrypt_key.c, fetch_mkey.c, kdb_cpw.c, + kdb_db2.c, kdb_db2.h, kdb_dbm.c, keytab.c, verify_mky.c: change or + remove all the places krb5_encrypt_block was used + (this is mostly relevant to kdb manipulations). It was usually + used to specify an enctype (which is now implied by the keyblock), + or to store or pass in a processed key (now the api just takes a + key directly, so these structures and functions do, too). The kdb + key manuipulation functions also need to be made to use the new + api. + +Fri Sep 25 19:42:10 1998 Tom Yu + + * kdb_xdr.c (krb5_dbe_search_enctype): Re-order booleans so that + similar doesn't get checked unless (ktype >= 0) to avoid it being + stack garbage. + +Sun Aug 16 16:52:10 1998 Sam Hartman + + * Makefile.in (SHLIB_EXPLIBS): Include $(LIBS) so building on AIX works + +Sun Jul 26 18:12:22 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): bump libmajor + 1998-05-06 Theodore Ts'o * t_kdb.c (main): POSIX states that getopt returns -1 diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in index 9ec4b23d4..c44b58631 100644 --- a/src/lib/kdb/Makefile.in +++ b/src/lib/kdb/Makefile.in @@ -7,14 +7,14 @@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) LIB=kdb5 -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 RELDIR=kdb # Depends on libk5crypto and libkrb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(TOPLIBD)/libkrb5$(SHLIBEXT) -SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto +SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto $(LIBS) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c index 2aa199ac7..0cfdbda8e 100644 --- a/src/lib/kdb/decrypt_key.c +++ b/src/lib/kdb/decrypt_key.c @@ -24,6 +24,32 @@ * krb5_kdb_encrypt_key(), krb5_kdb_decrypt_key functions */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" /* @@ -33,40 +59,53 @@ */ krb5_error_code -krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) +krb5_dbekd_decrypt_key_data(context, mkey, key_data, dbkey, keysalt) krb5_context context; - krb5_encrypt_block * eblock; + const krb5_keyblock * mkey; const krb5_key_data * key_data; - krb5_keyblock * keyblock; + krb5_keyblock * dbkey; krb5_keysalt * keysalt; { krb5_error_code retval = 0; krb5_int16 tmplen; krb5_octet * ptr; + krb5_enc_data cipher; + krb5_data plain; - keyblock->magic = KV5M_KEYBLOCK; - keyblock->enctype = key_data->key_data_type[0]; - - /* Decrypt key_data_contents */ - if ((keyblock->contents = (krb5_octet *)malloc(krb5_encrypt_size( - key_data->key_data_length[0] - 2, eblock->crypto_entry))) == NULL) - return ENOMEM; - - keyblock->length = 0; ptr = key_data->key_data_contents[0]; + if (ptr) { krb5_kdb_decode_int16(ptr, tmplen); ptr += 2; - keyblock->length = (int) tmplen; - if ((retval = krb5_decrypt(context, (krb5_pointer) ptr, - (krb5_pointer)keyblock->contents, - key_data->key_data_length[0] - 2, - eblock, 0))) { - krb5_xfree(keyblock->contents); - keyblock->contents = 0; - keyblock->length = 0; + + cipher.enctype = ENCTYPE_UNKNOWN; + cipher.ciphertext.length = key_data->key_data_length[0]-2; + cipher.ciphertext.data = ptr; + plain.length = key_data->key_data_length[0]-2; + if ((plain.data = (krb5_octet *) malloc(plain.length)) == NULL) + return(ENOMEM); + + if ((retval = krb5_c_decrypt(context, mkey, 0 /* XXX */, 0, + &cipher, &plain))) { + krb5_xfree(plain.data); return retval; } + + /* tmplen is the true length of the key. plain.data is the + plaintext data length, but it may be padded, since the + old-style etypes didn't store the real length. I can check + to make sure that there are enough bytes, but I can't do + any better than that. */ + + if (tmplen > plain.length) { + krb5_xfree(plain.data); + return(KRB5_CRYPTO_INTERNAL); + } + + dbkey->magic = KV5M_KEYBLOCK; + dbkey->enctype = key_data->key_data_type[0]; + dbkey->length = tmplen; + dbkey->contents = plain.data; } /* Decode salt data */ @@ -75,9 +114,11 @@ krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) keysalt->type = key_data->key_data_type[1]; if ((keysalt->data.length = key_data->key_data_length[1])) { if (!(keysalt->data.data=(char *)malloc(keysalt->data.length))){ - krb5_xfree(keyblock->contents); - keyblock->contents = 0; - keyblock->length = 0; + if (key_data->key_data_contents[0]) { + krb5_xfree(dbkey->contents); + dbkey->contents = 0; + dbkey->length = 0; + } return ENOMEM; } memcpy(keysalt->data.data, key_data->key_data_contents[1], @@ -90,5 +131,6 @@ krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) keysalt->data.length = 0; } } + return retval; } diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c index ea7d17ca7..7bcfe11eb 100644 --- a/src/lib/kdb/encrypt_key.c +++ b/src/lib/kdb/encrypt_key.c @@ -24,6 +24,32 @@ * krb5_kdb_encrypt_key(), krb5_kdb_decrypt_key functions */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" /* @@ -33,10 +59,10 @@ */ krb5_error_code -krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) +krb5_dbekd_encrypt_key_data(context, mkey, dbkey, keysalt, keyver, key_data) krb5_context context; - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; + const krb5_keyblock * mkey; + const krb5_keyblock * dbkey; const krb5_keysalt * keysalt; int keyver; krb5_key_data * key_data; @@ -44,8 +70,10 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) krb5_error_code retval; krb5_keyblock tmp; krb5_octet * ptr; - krb5_int16 len; + size_t len; int i; + krb5_data plain; + krb5_enc_data cipher; for (i = 0; i < key_data->key_data_ver; i++) if (key_data->key_data_contents[i]) @@ -58,39 +86,32 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) * The First element of the type/length/contents * fields is the key type/length/contents */ - key_data->key_data_type[0] = keyblock->enctype; - key_data->key_data_length[0] = krb5_encrypt_size(keyblock->length, - eblock->crypto_entry) + 2; + if ((retval = krb5_c_encrypt_length(context, mkey->enctype, dbkey->length, + &len))) + return(retval); - /* - * because of checksum space requirements imposed by the encryption - * interface, we need to copy the input key into a larger area. - */ - tmp.contents = (krb5_octet *)malloc(key_data->key_data_length[0] - 2); - len = tmp.length = keyblock->length; - if (tmp.contents == NULL) - return ENOMEM; + if ((ptr = (krb5_octet *) malloc(2 + len)) == NULL) + return(ENOMEM); - memcpy((char *)tmp.contents, (const char *)keyblock->contents, tmp.length); - key_data->key_data_contents[0] = ptr = (krb5_octet *)malloc( - key_data->key_data_length[0]); - if (key_data->key_data_contents[0] == NULL) { - krb5_xfree(tmp.contents); - return ENOMEM; - } + key_data->key_data_type[0] = dbkey->enctype; + key_data->key_data_length[0] = 2 + len; + key_data->key_data_contents[0] = ptr; - krb5_kdb_encode_int16(len, ptr); + krb5_kdb_encode_int16(dbkey->length, ptr); ptr += 2; - if ((retval = krb5_encrypt(context, (krb5_pointer) tmp.contents, - (krb5_pointer)(ptr), tmp.length, - eblock, 0))) { + + plain.length = dbkey->length; + plain.data = dbkey->contents; + + cipher.ciphertext.length = len; + cipher.ciphertext.data = ptr; + + if ((retval = krb5_c_encrypt(context, mkey, /* XXX */ 0, 0, + &plain, &cipher))) { krb5_xfree(key_data->key_data_contents[0]); - krb5_xfree(tmp.contents); return retval; } - krb5_xfree(tmp.contents); - /* After key comes the salt in necessary */ if (keysalt) { if (keysalt->type > 0) { @@ -108,5 +129,6 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) } } } + return retval; } diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c index 5eda4eae6..829e0283c 100644 --- a/src/lib/kdb/fetch_mkey.c +++ b/src/lib/kdb/fetch_mkey.c @@ -25,6 +25,32 @@ * Fetch a database master key from somewhere. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" /* these are available to other funcs, and the pointers may be reassigned */ @@ -52,10 +78,11 @@ char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; #endif krb5_error_code -krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, key) +krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile, + salt, key) krb5_context context; krb5_principal mname; - krb5_encrypt_block * eblock; + krb5_enctype etype; krb5_boolean fromkeyboard; krb5_boolean twice; char *keyfile; @@ -67,7 +94,6 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k krb5_data pwd; int size = sizeof(password); - if (fromkeyboard) { krb5_data scratch; @@ -83,8 +109,9 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k if (retval) return retval; } - retval = krb5_string_to_key(context, eblock, key, &pwd, - salt ? salt : &scratch); + retval = krb5_c_string_to_key(context, etype, &pwd, salt?salt:&scratch, + key); + if (!salt) krb5_xfree(scratch.data); memset(password, 0, sizeof(password)); /* erase it */ @@ -142,7 +169,8 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k key->contents = 0; } else retval = 0; - krb5_use_enctype(context, eblock, key->enctype); + + key->enctype = etype; errout: (void) fclose(kf); diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c index ec7419e1c..d68d784c1 100644 --- a/src/lib/kdb/kdb_cpw.c +++ b/src/lib/kdb/kdb_cpw.c @@ -22,6 +22,32 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include "krb5/adm.h" #include @@ -61,32 +87,23 @@ cleanup_key_data(context, count, data) free(data); } -/* - * Currently we can only generate random keys for preinitialized - * krb5_encrypt_block with a seed. This is bogus but currently - * necessary to insure that we don't generate two keys with the - * same data. - */ static krb5_error_code -add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) +add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; int kvno; { krb5_principal krbtgt_princ; - krb5_keyblock krbtgt_key, * key; - krb5_pointer krbtgt_seed; - krb5_encrypt_block krbtgt_eblock; + krb5_keyblock key; krb5_db_entry krbtgt_entry; krb5_key_data * krbtgt_kdata; - krb5_boolean more, found; + krb5_boolean more; int max_kvno, one, i, j; krb5_error_code retval; - memset(&krbtgt_key, 0, sizeof(krbtgt_key)); retval = krb5_build_principal_ext(context, &krbtgt_princ, db_entry->princ->realm.length, db_entry->princ->realm.data, @@ -119,17 +136,9 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) } for (i = 0; i < ks_tuple_count; i++) { - krb5_enctype new_enctype, old_enctype; + krb5_boolean similar; - switch (new_enctype = ks_tuple[i].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - new_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - found = 0; + similar = 0; /* * We could use krb5_keysalt_iterate to replace this loop, or use @@ -137,74 +146,44 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) * circular library dependencies. */ for (j = 0; j < i; j++) { - switch (old_enctype = ks_tuple[j].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - old_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - if (old_enctype == new_enctype) { - found = 1; + if ((retval = krb5_c_enctype_compare(context, + ks_tuple[i].ks_enctype, + ks_tuple[j].ks_enctype, + &similar))) + return(retval); + + if (similar) break; - } } - if (found) - continue; - if (retval = krb5_dbe_create_key_data(context, db_entry)) - goto add_key_rnd_err; - if (retval = krb5_dbe_find_enctype(context, &krbtgt_entry, - ks_tuple[i].ks_enctype, - -1, 0, &krbtgt_kdata)) - goto add_key_rnd_err; + if (similar) + continue; - /* Decrypt key */ - if (retval = krb5_dbekd_decrypt_key_data(context, master_eblock, - krbtgt_kdata,&krbtgt_key,NULL)) + if (retval = krb5_dbe_create_key_data(context, db_entry)) goto add_key_rnd_err; - /* Init key */ - krbtgt_key.enctype = ks_tuple[i].ks_enctype; - krb5_use_enctype(context, &krbtgt_eblock, ks_tuple[i].ks_enctype); - if (retval = krb5_process_key(context, &krbtgt_eblock, &krbtgt_key)) { - goto add_key_rnd_err; - } + /* there used to be code here to extract the old key, and derive + a new key from it. Now that there's a unified prng, that isn't + necessary. */ - /* Init random generator */ - if (retval = krb5_init_random_key(context, &krbtgt_eblock, - &krbtgt_key, &krbtgt_seed)) { - krb5_finish_key(context, &krbtgt_eblock); + /* make new key */ + if ((retval = krb5_c_make_random_key(context, ks_tuple[i].ks_enctype, + &key))) goto add_key_rnd_err; - } - if (retval = krb5_random_key(context,&krbtgt_eblock,krbtgt_seed,&key)) { - krb5_finish_random_key(context, &krbtgt_eblock, &krbtgt_seed); - krb5_finish_key(context, &krbtgt_eblock); - goto add_key_rnd_err; - } + retval = krb5_dbekd_encrypt_key_data(context, master_key, + &key, NULL, kvno, + &db_entry->key_data[db_entry->n_key_data-1]); - krb5_finish_random_key(context, &krbtgt_eblock, &krbtgt_seed); - krb5_finish_key(context, &krbtgt_eblock); + krb5_free_keyblock_contents(context, &key); - if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, - key, NULL, kvno, - &db_entry->key_data[db_entry->n_key_data-1])) { - krb5_free_keyblock(context, key); + if (retval) goto add_key_rnd_err; - } - - /* Finish random key */ - krb5_free_keyblock(context, key); } -add_key_rnd_err:; +add_key_rnd_err: krb5_db_free_principal(context, &krbtgt_entry, one); - if (krbtgt_key.contents && krbtgt_key.length) { - memset(krbtgt_key.contents, 0, krbtgt_key.length); - krb5_xfree(krbtgt_key.contents); - } + return(retval); } @@ -215,9 +194,9 @@ add_key_rnd_err:; * As a side effect all old keys are nuked. */ krb5_error_code -krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) +krb5_dbe_crk(context, master_key, ks_tuple, ks_tuple_count, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; @@ -237,7 +216,7 @@ krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) /* increment the kvno */ kvno++; - if (retval = add_key_rnd(context, master_eblock, ks_tuple, + if (retval = add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -255,9 +234,9 @@ krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) * As a side effect all old keys older than the max kvno are nuked. */ krb5_error_code -krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) +krb5_dbe_ark(context, master_key, ks_tuple, ks_tuple_count, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; @@ -278,7 +257,7 @@ krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) /* increment the kvno */ kvno++; - if (retval = add_key_rnd(context, master_eblock, ks_tuple, + if (retval = add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -307,10 +286,10 @@ krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) * If passwd is NULL the assumes that the caller wants a random password. */ static krb5_error_code -add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, +add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, kvno) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -318,7 +297,6 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, int kvno; { krb5_error_code retval; - krb5_encrypt_block key_eblock; krb5_keysalt key_salt; krb5_keyblock key; krb5_data pwd; @@ -328,40 +306,30 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, retval = 0; for (i = 0; i < ks_tuple_count; i++) { - krb5_enctype new_enctype, old_enctype; + krb5_boolean similar; + + similar = 0; - switch (new_enctype = ks_tuple[i].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - new_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } /* * We could use krb5_keysalt_iterate to replace this loop, or use * krb5_keysalt_is_present for the loop below, but we want to avoid * circular library dependencies. */ - for (found = j = 0; j < i; j++) { - if (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype) { - switch (old_enctype = ks_tuple[j].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - old_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - if (old_enctype == new_enctype) { - found = 1; - break; - } - } + for (j = 0; j < i; j++) { + if ((retval = krb5_c_enctype_compare(context, + ks_tuple[i].ks_enctype, + ks_tuple[j].ks_enctype, + &similar))) + return(retval); + + if (similar && + (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype)) + break; } - if (found) + + if (j < i) continue; - krb5_use_enctype(context, &key_eblock, ks_tuple[i].ks_enctype); + if (retval = krb5_dbe_create_key_data(context, db_entry)) return(retval); @@ -422,8 +390,9 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, pwd.data = passwd; pwd.length = strlen(passwd); - if (retval = krb5_string_to_key(context, &key_eblock, &key, &pwd, - &key_salt.data)) { + + if ((retval = krb5_c_string_to_key(context, ks_tuple[i].ks_enctype, + &pwd, &key_salt.data, &key))) { if (key_salt.data.data) free(key_salt.data.data); return(retval); @@ -433,7 +402,7 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, key_salt.data.length = krb5_princ_realm(context, db_entry->princ)->length; - if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, &key, + if (retval = krb5_dbekd_encrypt_key_data(context, master_key, &key, (const krb5_keysalt *)&key_salt, kvno, &db_entry->key_data[db_entry->n_key_data-1])) { if (key_salt.data.data) @@ -455,10 +424,10 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, * As a side effect all old keys are nuked. */ krb5_error_code -krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, +krb5_dbe_cpw(context, master_key, ks_tuple, ks_tuple_count, passwd, new_kvno, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -483,7 +452,7 @@ krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, if (new_kvno < old_kvno+1) new_kvno = old_kvno+1; - if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, + if (retval = add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, new_kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -501,9 +470,9 @@ krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, * As a side effect all old keys older than the max kvno are nuked. */ krb5_error_code -krb5_dbe_apw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry) +krb5_dbe_apw(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -526,7 +495,7 @@ krb5_dbe_apw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry) /* increment the kvno */ new_kvno = old_kvno+1; - if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, + if (retval = add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, new_kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; diff --git a/src/lib/kdb/kdb_db2.c b/src/lib/kdb/kdb_db2.c index 80c9213dd..ab4d07e23 100644 --- a/src/lib/kdb/kdb_db2.c +++ b/src/lib/kdb/kdb_db2.c @@ -22,6 +22,32 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #if HAVE_UNISTD_H #include #endif @@ -325,9 +351,9 @@ krb5_db2_db_close_database(context) * Set/Get the master key associated with the database */ krb5_error_code -krb5_db2_db_set_mkey(context, eblock) +krb5_db2_db_set_mkey(context, key) krb5_context context; - krb5_encrypt_block *eblock; + krb5_keyblock *key; { krb5_db2_context *db_ctx; @@ -335,14 +361,14 @@ krb5_db2_db_set_mkey(context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - db_ctx->db_master_key = eblock; + db_ctx->db_master_key = key; return 0; } krb5_error_code -krb5_db2_db_get_mkey(context, eblock) +krb5_db2_db_get_mkey(context, key) krb5_context context; - krb5_encrypt_block **eblock; + krb5_keyblock **key; { krb5_db2_context *db_ctx; @@ -350,7 +376,7 @@ krb5_db2_db_get_mkey(context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - *eblock = db_ctx->db_master_key; + *key = db_ctx->db_master_key; return 0; } diff --git a/src/lib/kdb/kdb_db2.h b/src/lib/kdb/kdb_db2.h index d17fde476..f2f01311e 100644 --- a/src/lib/kdb/kdb_db2.h +++ b/src/lib/kdb/kdb_db2.h @@ -58,7 +58,7 @@ typedef struct _krb5_db2_context { int db_locks_held; /* Number of times locked */ int db_lock_mode; /* Last lock mode, e.g. greatest*/ krb5_boolean db_nb_locks; /* [Non]Blocking lock modes */ - krb5_encrypt_block *db_master_key; /* Master key of database */ + krb5_keyblock *db_master_key; /* Master key of database */ } krb5_db2_context; #define KRB5_DB2_MAX_RETRY 5 diff --git a/src/lib/kdb/kdb_dbm.c b/src/lib/kdb/kdb_dbm.c index 1ae241dfa..7af32d720 100644 --- a/src/lib/kdb/kdb_dbm.c +++ b/src/lib/kdb/kdb_dbm.c @@ -330,10 +330,10 @@ krb5_dbm_db_close_database(context) * The should really reference the db_context */ krb5_error_code -krb5_dbm_db_set_mkey(context, db_context, eblock) +krb5_dbm_db_set_mkey(context, db_context, key) krb5_context context; krb5_db_context * db_context; - krb5_encrypt_block * eblock; + krb5_keyblock * key; { krb5_db_context *db_ctx; @@ -341,15 +341,15 @@ krb5_dbm_db_set_mkey(context, db_context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - db_ctx->db_master_key = eblock; + db_ctx->db_master_key = key; return 0; } krb5_error_code -krb5_dbm_db_get_mkey(context, db_context, eblock) +krb5_dbm_db_get_mkey(context, db_context, key) krb5_context context; krb5_db_context * db_context; - krb5_encrypt_block **eblock; + krb5_keyblock **key; { krb5_db_context *db_ctx; @@ -357,7 +357,7 @@ krb5_dbm_db_get_mkey(context, db_context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - *eblock = db_ctx->db_master_key; + *key = db_ctx->db_master_key; return 0; } diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c index 209e4f3ca..a26b7f79d 100644 --- a/src/lib/kdb/kdb_xdr.c +++ b/src/lib/kdb/kdb_xdr.c @@ -735,40 +735,27 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) } } - /* - * ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD4, ENCTYPE_DES_CBC_MD5, - * ENCTYPE_DES_CBC_RAW all use the same key. - */ - switch (ktype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - ktype = ENCTYPE_DES_CBC_CRC; - break; - default: - break; - } - maxkvno = -1; datap = (krb5_key_data *) NULL; for (i = *start; i < dbentp->n_key_data; i++) { - krb5_enctype db_ktype; - krb5_int32 db_stype; - - switch (db_ktype = dbentp->key_data[i].key_data_type[0]) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - db_ktype = ENCTYPE_DES_CBC_CRC; - default: - break; - } + krb5_boolean similar; + krb5_error_code ret; + krb5_int32 db_stype; + if (dbentp->key_data[i].key_data_ver > 1) { db_stype = dbentp->key_data[i].key_data_type[1]; } else { db_stype = KRB5_KDB_SALTTYPE_NORMAL; } - if (((db_ktype == (krb5_enctype) ktype) || (ktype < 0)) && + + if (ktype >= 0) { + if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, + dbentp->key_data[i].key_data_type[0], + &similar))) + return(ret); + } + + if (((ktype < 0) || similar) && ((db_stype == stype) || (stype < 0))) { if (kvno >= 0) { if (kvno == dbentp->key_data[i].key_data_kvno) { diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c index 9c184b514..63a7bf7c8 100644 --- a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -89,7 +89,7 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry) krb5_enctype enctype; krb5_keytab_entry * entry; { - krb5_encrypt_block * master_key; + krb5_keyblock * master_key; krb5_error_code kerror = 0; krb5_key_data * key_data; krb5_db_entry db_entry; diff --git a/src/lib/kdb/verify_mky.c b/src/lib/kdb/verify_mky.c index 121c72148..4bab17024 100644 --- a/src/lib/kdb/verify_mky.c +++ b/src/lib/kdb/verify_mky.c @@ -29,16 +29,13 @@ /* * Verify that the master key in *mkey matches the database entry * for mprinc. - * - * eblock points to an encrypt_block used for the realm in question. */ krb5_error_code -krb5_db_verify_master_key(context, mprinc, mkey, eblock) +krb5_db_verify_master_key(context, mprinc, mkey) krb5_context context; krb5_principal mprinc; krb5_keyblock *mkey; - krb5_encrypt_block *eblock; { krb5_error_code retval; krb5_db_entry master_entry; @@ -60,24 +57,18 @@ krb5_db_verify_master_key(context, mprinc, mkey, eblock) return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, eblock, mkey))) { - krb5_db_free_principal(context, &master_entry, nprinc); - return(retval); - } - if ((retval = krb5_dbekd_decrypt_key_data(context, eblock, + if ((retval = krb5_dbekd_decrypt_key_data(context, mkey, &master_entry.key_data[0], &tempkey, NULL))) { - (void) krb5_finish_key(context, eblock); krb5_db_free_principal(context, &master_entry, nprinc); return retval; } + if (mkey->length != tempkey.length || - memcmp((char *)mkey->contents, (char *)tempkey.contents,mkey->length)) { + memcmp((char *)mkey->contents, + (char *)tempkey.contents,mkey->length)) { retval = KRB5_KDB_BADMASTERKEY; - (void) krb5_finish_key(context, eblock); - } else - retval = krb5_finish_key(context, eblock); + } memset((char *)tempkey.contents, 0, tempkey.length); krb5_xfree(tempkey.contents); diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 54e185d2e..0162fc450 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,26 @@ +Wed Aug 12 18:32:44 1998 Tom Yu + + * rd_req.c (krb_set_key): Nuke the krb5_keyblock if it's set. + (krb_set_key_krb5): New function to set a static krb5_keyblock for + decryption purposes. + (krb_clear_key_krb5): New function to clear the static + krb5_keyblock if it's set. + (krb_rd_req): Call decomp_ticket or decomp_tkt_krb5 as appropriate + to the key type. + + * decomp_tkt.c (decomp_tkt_krb5): New wrapper to call + dcmp_tkt_int. + (decomp_ticket): Transform into wrapper to call dcmp_tkt_int. + (dcmp_tkt_int): New internal function; use a krb5_keyblock to + decrypt the ticket if present; else just use plain old C_Block. + + * cr_tkt.c (krb_create_ticket): Transform into a wrapper that + calls krb_cr_tkt_int. + (krb_cr_tkt_krb5): New wrapper to call krb_cr_tkt_int. + (krb_cr_tkt_int): New internal function that potentially uses a + krb5_keyblock to encrypt the ticket, or just a C_Block if the + krb5_keyblock is not set. + Mon Aug 10 17:51:59 1998 Matthew D Hancher * rd_svc_key.c (read_service_key): Don't call krb5_kt_close() if @@ -12,6 +35,14 @@ Fri Aug 7 11:04:03 1998 Tom Yu * tf_util.c (tf_init): Add call to getuid() to initialize me. +Thu Jul 30 13:13:30 1998 Sam Hartman + + * tf_util.c (tf_init): s/,/= so getuid() actually gets called + +Sun Jul 26 17:51:24 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): Bump libmajor + Thu Jul 9 19:35:01 1998 Matthew D Hancher * tf_util.c (tf_init): Fixed a potential race condition in the opening diff --git a/src/lib/krb4/Makefile.in b/src/lib/krb4/Makefile.in index f75a6327b..af2dca43c 100644 --- a/src/lib/krb4/Makefile.in +++ b/src/lib/krb4/Makefile.in @@ -8,7 +8,7 @@ DEFINES=-I$(srcdir)/../../include/kerberosIV ##DOS##OBJFILE=krb4.lst LIB=krb4 -LIBMAJOR=1 +LIBMAJOR=2 LIBMINOR=0 RELDIR=krb4 diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c index 39ed53859..a8224f879 100644 --- a/src/lib/krb4/cr_tkt.c +++ b/src/lib/krb4/cr_tkt.c @@ -13,7 +13,7 @@ #include "krb.h" #include "prot.h" #include - +#include /* * Create ticket takes as arguments information that should be in a * ticket, and the KTEXT object in which the ticket should be @@ -69,9 +69,53 @@ * <=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, k5key) + 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 */ +{ + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, NULL); +} -int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, - session, life, time_sec, sname, sinstance, key) +int +krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, k5key) + 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 */ + krb5_keyblock *k5key; /* NULL if not present */ +{ + C_Block key; + + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, k5key); +} + +static int +krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key, k5key) KTEXT tkt; /* Gets filled in by the ticket */ unsigned char flags; /* Various Kerberos flags */ char *pname; /* Principal's name */ @@ -84,6 +128,7 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, char *sname; /* Service Name */ char *sinstance; /* Instance Name */ C_Block key; /* Service's secret key */ + krb5_keyblock *k5key; /* NULL if not present */ { Key_schedule key_s; register char *data; /* running index into ticket */ @@ -124,10 +169,43 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, } #ifndef NOENCRYPTION - /* Encrypt the ticket in the services key */ - key_sched(key,key_s); - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *)key,1); + /* Encrypt the ticket in the services key */ + if (k5key != NULL) { + /* block locals */ + krb5_data in; + krb5_enc_data out; + krb5_error_code ret; + size_t enclen; + + in.length = tkt->length; + in.data = tkt->dat; + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt_length(NULL, k5key->enctype, + (size_t)in.length, &enclen); + if (ret) + return KFAILURE; + out.ciphertext.length = enclen; + out.ciphertext.data = malloc(enclen); + if (out.ciphertext.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt(NULL, k5key, KRB5_KEYUSAGE_KDC_REP_TICKET, + NULL, &in, &out); + if (ret) { + free(out.ciphertext.data); + return KFAILURE; + } else { + tkt->length = out.ciphertext.length; + memcpy(tkt->dat, out.ciphertext.data, out.ciphertext.length); + memset(out.ciphertext.data, 0, out.ciphertext.length); + free(out.ciphertext.data); + } + } else { + key_sched(key,key_s); + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *)key,1); + } #endif /* !NOENCRYPTION */ return 0; } diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c index 3c5952368..d4dfd4edc 100644 --- a/src/lib/krb4/decomp_tkt.c +++ b/src/lib/krb4/decomp_tkt.c @@ -13,6 +13,7 @@ #include "krb.h" #include "prot.h" #include +#include #ifdef KRB_CRYPT_DEBUG extern int krb_debug; @@ -64,6 +65,57 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, C_Block key; /* Service's secret key * (to decrypt the ticket) */ Key_schedule key_s; /* The precomputed key schedule */ +{ + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, + paddress, session, life, time_sec, sname, sinstance, + key, key_s, NULL); +} + +int +decomp_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, k5key) + 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 KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ +{ + C_Block key; /* placeholder; doesn't get used */ + Key_schedule key_s; /* placeholder; doesn't get used */ + + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key); +} + +static int +dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key) + 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 KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *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 */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ { static int tkt_swap_bytes; unsigned char *uptr; @@ -83,8 +135,37 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, memset(keybuf, 0, sizeof(keybuf)); /* Clear the buffer */ } #endif - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *) key,0); + if (k5key != NULL) { + /* block locals */ + krb5_enc_data in; + krb5_data out; + krb5_error_code ret; + + in.enctype = k5key->enctype; + in.kvno = 0; + in.ciphertext.length = tkt->length; + in.ciphertext.data = tkt->dat; + out.length = tkt->length; + out.data = malloc(tkt->length); + if (out.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX note the following assumes that context arg isn't used */ + ret = + krb5_c_decrypt(NULL, k5key, + KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &in, &out); + if (ret) { + free(out.data); + return KFAILURE; + } else { + memcpy(tkt->dat, out.data, out.length); + memset(out.data, 0, out.length); + free(out.data); + } + } else { + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *) key,0); + } #endif /* ! NOENCRYPTION */ #ifdef KRB_CRYPT_DEBUG if (krb_debug) { diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c index 79564e4f3..a78aadc88 100644 --- a/src/lib/krb4/rd_req.c +++ b/src/lib/krb4/rd_req.c @@ -32,6 +32,7 @@ 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 */ +static int krb5_key; /* whether krb5 key is used for decrypt */ /* * This file contains two functions. krb_set_key() takes a DES @@ -62,11 +63,18 @@ static char st_inst[INST_SZ]; /* server's instance */ * krb_rd_req(). */ +#include +static krb5_keyblock srv_k5key; + int krb_set_key(key,cvt) char *key; int cvt; { + if (krb5_key) + /* XXX assumes that context arg is ignored */ + krb5_free_keyblock_contents(NULL, &srv_k5key); + krb5_key = 0; #ifdef NOENCRYPTION memset(ky, 0, sizeof(ky)); return KSUCCESS; @@ -79,6 +87,25 @@ krb_set_key(key,cvt) #endif /* NOENCRYPTION */ } +int +krb_set_key_krb5(ctx, key) + krb5_context ctx; + krb5_keyblock *key; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 1; + return krb5_copy_keyblock_contents(ctx, key, &srv_k5key); +} + +void +krb_clear_key_krb5(ctx) + krb5_context ctx; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 0; +} /* * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or @@ -234,15 +261,25 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) /* 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)) { + if (!krb5_key) { + 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)) { #ifdef KRB_CRYPT_DEBUG - log("Can't decode ticket"); + log("Can't decode ticket"); #endif - return(RD_AP_UNDEC); + return(RD_AP_UNDEC); + } + } else { + if (decomp_tkt_krb5(tkt, &ad->k_flags, ad->pname, ad->pinst, + ad->prealm, &ad->address, ad->session, + &ad->life, &ad->time_sec, sname, iname, + srv_k5key)) { + return RD_AP_UNDEC; + } } + #ifdef KRB_CRYPT_DEBUG if (krb_ap_req_debug) { log("Ticket Contents."); diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c index b3eb0b43a..1c7aadd9f 100644 --- a/src/lib/krb4/tf_util.c +++ b/src/lib/krb4/tf_util.c @@ -182,7 +182,7 @@ int tf_init(tf_name, rw) int rw; { int wflag; - uid_t me, getuid(); + uid_t me= getuid(); struct stat stat_buf, stat_buffd; #ifdef TKT_SHMEM char shmidname[MAXPATHLEN]; diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog index f7922150e..f1e1e81f9 100644 --- a/src/lib/krb5/ChangeLog +++ b/src/lib/krb5/ChangeLog @@ -1,3 +1,11 @@ +Thu Jul 30 13:12:57 1998 Sam Hartman + + * configure.in: Test for sa_len so localaddr works on NetBSD. + +Sun Jul 26 17:46:47 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): bump to 2 + Wed Apr 15 18:07:20 1998 Tom Yu * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 4864a2f94..12ce18512 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -28,8 +28,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \ #SHLIB_LIBDIRS= @SHLIB_LIBDIRS@ LIB=krb5 -LIBMAJOR=1 -LIBMINOR=2 +LIBMAJOR=2 +LIBMINOR=1 STOBJLISTS= \ error_tables/OBJS.ST \ diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog index a42ad235c..ca3f679f5 100644 --- a/src/lib/krb5/asn.1/ChangeLog +++ b/src/lib/krb5/asn.1/ChangeLog @@ -1,3 +1,10 @@ +1998-10-27 Marc Horowitz + + * asn1buf.c (asn1buf_sync): interoperation testing against heimdal + revealed a bug. if extra fields are present in a SEQUENCE, they + are not ignored and skipped. This caused the decoder to get out + of sync. + Thu Jul 2 15:30:25 1998 Theodore Y. Ts'o * asn1_encode.c: Make the magic Macintosh EPOCH offset be 70 years diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index 30dad8b49..52ac387d5 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -93,7 +93,7 @@ void asn1buf_sync(buf, subbuf) asn1buf * buf; asn1buf * subbuf; { - buf->next = subbuf->next; + buf->next = subbuf->bound + 1; } asn1_error_code asn1buf_destroy(buf) diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog index 2a4d39551..71aa06dc8 100644 --- a/src/lib/krb5/ccache/ChangeLog +++ b/src/lib/krb5/ccache/ChangeLog @@ -7,6 +7,10 @@ Fri Aug 20 18:30:00 1998 Miro Jurisic * Added Frank's CCache API cache implementation and made it default on the Mac +Thu Jul 30 13:12:30 1998 Sam Hartman + + * ccbase.c: Enable memory ccache (merge adapted from Kerbnet) + 1998-05-27 Theodore Ts'o * Makefile.in: Add ccache/memory as a directory to be recursively diff --git a/src/lib/krb5/ccache/ccapi/Makefile.in b/src/lib/krb5/ccache/ccapi/Makefile.in deleted file mode 100644 index e47ded443..000000000 --- a/src/lib/krb5/ccache/ccapi/Makefile.in +++ /dev/null @@ -1,21 +0,0 @@ -thisconfigdir=./../.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) - -##DOS##BUILDTOP = ..\..\..\.. -##DOS##PREFIXDIR = ccache\file -##DOS##OBJFILE = file.lst -##WIN16##LIBNAME=..\..\krb5.lib - -STLIBOBJS = \ - stdcc.o \ - stdcc_util.o - -OBJS = stdcc.${OBJEXT} stdcc_util.${OBJEXT} - -SRCS = $(srcdir)/stdcc.c $(srcdir)/stdcc_util.c - -##DOS##LIBOBJS = $(OBJS) - -all-unix:: all-libobjs -clean-unix:: clean-libobjs diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c deleted file mode 100644 index 2b9007bf8..000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ /dev/null @@ -1,394 +0,0 @@ -/********************************************************** - * - * stdcc.c - additions to the Kerberos 5 library to support the memory credentical cache API - * - * Revision 1.1.1.1 - Frank Dabek July 1998 - * - **********************************************************/ - -#include "stdcc.h" -#include "string.h" - -//declare our global object wanna-be -//must be installed in ccdefops.c -krb5_cc_ops krb5_cc_stdcc_ops = { - 0, - "API", - krb5_stdcc_get_name, - krb5_stdcc_resolve, - krb5_stdcc_generate_new, - krb5_stdcc_initialize, - krb5_stdcc_destroy, - krb5_stdcc_close, - krb5_stdcc_store, - krb5_stdcc_retrieve, - krb5_stdcc_get_principal, - krb5_stdcc_start_seq_get, - krb5_stdcc_next_cred, - krb5_stdcc_end_seq_get, - krb5_stdcc_remove, - krb5_stdcc_set_flags, -}; - -// -- generate_new -------------------------------- -// - create a new cache with a unique name, corresponds to creating a named cache -// - iniitialize the API here if we have to. -krb5_error_code krb5_stdcc_generate_new - (krb5_context context, krb5_ccache *id ) - - { - - krb5_ccache newCache; - char name[kStringLiteralLen]; - cc_time_t time; - int err; - - //make sure the API has been intialized - if (gCntrlBlock == NULL) { - err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL); - if (err != CC_NOERROR) return err; - } - - //allocate the cache structure - newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); - if (newCache == NULL) return KRB5_CC_NOMEM; - - //create a unique name - cc_get_change_time(gCntrlBlock, &time); - sprintf(name, "gen_new_cache%d", time); - - //create the new cache - err = cc_create(gCntrlBlock, name, CC_CRED_V5, - name, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) ); - if (err != CC_NOERROR) return err; - - //setup some fields - newCache->ops = &krb5_cc_stdcc_ops; - newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)); - - //return a pointer to the new cache - *id = newCache; - - return CC_NOERROR; - } - -// -- resolve ------------------------------ -// -// - create a new cache with the name stored in residual -krb5_error_code krb5_stdcc_resolve - (krb5_context context, krb5_ccache *id , const char *residual ) { - - krb5_ccache newCache; - int err,pos; - char *cName; - - //make sure the API has been intialized - if (gCntrlBlock == NULL) { - err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL); - if (err != CC_NOERROR) return err; - } - - newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); - if (newCache == NULL) return KRB5_CC_NOMEM; - - newCache->ops = &krb5_cc_stdcc_ops; - newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)); - if (newCache->data == NULL) return KRB5_CC_NOMEM; - - cName = residual; - //attempt to find a cache by the same name before creating it - err = cc_open(gCntrlBlock, cName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache)); - //we didn't find it.. create it. - if (err) { - err = cc_create(gCntrlBlock, cName, CC_CRED_V5, cName, - 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) ); - if (err != CC_NOERROR) return err; //still an error, return it - } - - //return new cache structure - *id = newCache; - return CC_NOERROR; - } - - // -- initialize -------------------------------- - //-initialize the cache, check to see if one already exists for this principal - // if not set our principal to this principal. This searching enables ticket sharing - krb5_error_code krb5_stdcc_initialize - (krb5_context context, krb5_ccache id, krb5_principal princ) - - { - - int err, err1, found; - //char cName[kStringLiteralLen]; - char *cName = nil; - ccache_p *testNC = NULL; - ccache_it *it; - char *p = NULL, *targetName = NULL; - - //test id for null - if (id == NULL) return KRB5_CC_NOMEM; - - //test for initialized API - if (gCntrlBlock == NULL) - return CC_NO_EXIST; - - //create a principal name for the named cache - err = krb5_unparse_name(context, princ, &cName); - if (err) - return(err); - - //sprintf(cName, "%s@%s", krb5_princ_name(context, princ)->data, krb5_princ_realm(context, princ)->data); - - //look for a cache already extant for this principal - it = NULL; - found = err = 0; - while ((err != CC_END) && (!found)) { - err = cc_seq_fetch_NCs(gCntrlBlock, &testNC, &it); - if (err == CC_NOERROR) { - cc_get_principal(gCntrlBlock, testNC, &p); - if (strcmp(p, cName) == 0) { - found = 1; - cc_get_name(gCntrlBlock, testNC, &targetName); - } - cc_free_principal(gCntrlBlock, p); - err1 = cc_close(gCntrlBlock, &testNC); - } - } - - if (!found) - //we didn't find one with the name we were looking for, use the one we had and change the name - cc_set_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), CC_CRED_V5, cName); - else { - //we found a cache for this guy, lets trash ours and use that one - let's not; sgm 10/7/98 - //cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - err = cc_open(gCntrlBlock, targetName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - if (err != CC_NOERROR) return err; //error opening - cc_free_name(gCntrlBlock, targetName); - } - - free(cName); - - return CC_NOERROR; - - } - - -// -- store ---------------------------------- -// - store some credentials in our cache - krb5_error_code krb5_stdcc_store - (krb5_context context, krb5_ccache id , krb5_creds *creds ) { - - cred_union *cu = NULL; - int err; - - - //copy the fields from the almost identical structures - dupK52cc(context, creds, &cu); - - //finally store the credential - //store will copy (that is duplicate) everything - err = cc_store(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, *cu); - if (err != CC_NOERROR) return err; - - //free the cred union - err = cc_free_creds(gCntrlBlock, &cu); - - return err; -} - - -// -- start_seq_get -------------------------- -// - begin an iterator call to get all of the credentials in the cache -krb5_error_code krb5_stdcc_start_seq_get -(krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) { - - //all we have to do is initialize the cursor - *cursor = NULL; - return CC_NOERROR; -} - -// -- next cred --------------------------- -// - get the next credential in the cache as part of an iterator call -// - this maps to call to cc_seq_fetch_creds -krb5_error_code krb5_stdcc_next_cred - (krb5_context context, - krb5_ccache id , - krb5_cc_cursor *cursor , - krb5_creds *creds ) { - - int err; - cred_union *credU = NULL; - cc_creds *c = NULL; - - err = cc_seq_fetch_creds(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, - &credU, (ccache_it **)cursor); - - if (err != CC_NOERROR) - return err; - - //copy data (with translation) - dupCCtoK5(context, credU->cred.pV5Cred, creds); - - //free our version of the cred - cc_free_creds(gCntrlBlock, &credU); - - return CC_NOERROR; - -} - - -// -- retreive ------------------- -// - try to find a matching credential in the cache -krb5_error_code krb5_stdcc_retrieve - (krb5_context context, - krb5_ccache id, - krb5_flags whichfields, - krb5_creds *mcreds, - krb5_creds *creds ) { - - krb5_cc_cursor curs = NULL; - krb5_creds *fetchcreds; - - fetchcreds = (krb5_creds *)malloc(sizeof(krb5_creds)); - if (fetchcreds == NULL) return KRB5_CC_NOMEM; - - //we're going to use the iterators - krb5_stdcc_start_seq_get(context, id, &curs); - - while (krb5_stdcc_next_cred(context, id, &curs, fetchcreds) == CC_NOERROR) { - //look at each credential for a match - //use this match routine since it takes the whichfields and the API doesn't - if (stdccCredsMatch(context, fetchcreds, mcreds, whichfields)) { - //we found it, copy and exit - *creds = *fetchcreds; - krb5_stdcc_end_seq_get(context, id, &curs); - return CC_NOERROR; - } - //free copy allocated by next_cred - krb5_free_cred_contents(context, fetchcreds); - } - - //no luck, end get and exti - krb5_stdcc_end_seq_get(context, id, &curs); - - return KRB5_CC_NOTFOUND; -} - -// -- end seq ------------------------ -// - just free up the storage assoicated with the cursor (if we could) - krb5_error_code krb5_stdcc_end_seq_get - (krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) { - - //the limitation of the Ccache api and the seq calls - //causes trouble. cursor might have already been freed - //and anyways it is in the mac's heap so we need FreePtr - //but all i have is free - // FreePtr(*cursor); - - //LEAK IT! - *cursor = NULL; - } - -// -- close --------------------------- -// - free our pointers to the NC -krb5_error_code -krb5_stdcc_close(context, id, princ) - krb5_context context; - krb5_ccache id; - krb5_principal princ; -{ - - //free it - free((stdccCacheDataPtr)(id->data)); - //null it out - (stdccCacheDataPtr)(id->data) = NULL; - - return CC_NOERROR; -} - -// -- destroy ------------- -// - free our storage and the cache -krb5_error_code -krb5_stdcc_destroy (krb5_context context, krb5_ccache id ) { - - int err; - - //destroy the named cache - err = cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - //free the pointer to the record that held the pointer to the cache - free((stdccCacheDataPtr)(id->data)); - //null it out - (stdccCacheDataPtr)(id->data) = NULL; - - return err; -} - - -// -- getname --------------------------- -// - return the name of the named cache -char * krb5_stdcc_get_name - (krb5_context context, krb5_ccache id ) { - - char *ret = NULL; - int err; - - //just a wrapper - err = cc_get_name(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &ret); - - if (err != CC_NOERROR) - return ret; - else - return NULL; - -} - -// -- get_principal --------------------------- -// - return the principal associated with the named cache -krb5_error_code -krb5_stdcc_get_principal (krb5_context context, krb5_ccache id , krb5_principal *princ ) { - - int err; - char *name = NULL; - - //another wrapper - err = cc_get_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &name); - - if (err != CC_NOERROR) - return err; - - //turn it into a krb principal - err = krb5_parse_name(context, name, princ); - - return err; -} - -// -- set_flags --------------------------- -// - currently a NOP since we don't store any flags in the NC -krb5_error_code krb5_stdcc_set_flags - (krb5_context context, krb5_ccache id , krb5_flags flags ) { - - return CC_NOERROR; -} - -// - remove --------------------------- -// - remove the specified credentials from the NC -krb5_error_code krb5_stdcc_remove - (krb5_context context, krb5_ccache id , krb5_flags flags, krb5_creds *creds ) { - - cred_union *cu = NULL; - int err; - - //convert to a cred union - dupK52cc(context, creds, &cu); - - //remove it - err = cc_remove_cred(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), *cu); - if (err != CC_NOERROR) return err; - - //free the temp cred union - err = cc_free_creds(gCntrlBlock, &cu); - if (err != CC_NOERROR) return err; - - return CC_NOERROR; - } - \ No newline at end of file diff --git a/src/lib/krb5/ccache/ccapi/stdcc.h b/src/lib/krb5/ccache/ccapi/stdcc.h deleted file mode 100644 index c157770c4..000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc.h +++ /dev/null @@ -1,73 +0,0 @@ -//#include "k5-int.h" -#include "krb5.h" - -#if defined(macintosh) -#include "CCache.h" -#endif - -#if defined(_MSDOS) || defined(_WIN32) -#include "cacheapi.h" -#endif - -#define kStringLiteralLen 255 - -//globals to be exported -extern krb5_cc_ops krb5_cc_stdcc_ops; - -//structure to stash in the cache's data field -//only holds another pointer to the actual cache right now -typedef struct _stdccCacheData { - ccache_p *NamedCache; -} stdccCacheData, *stdccCacheDataPtr; - - -//function protoypes complete with bogus windowsesque macros.. - -KRB5_DLLIMP krb5_error_code krb5_stdcc_close - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_destroy - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_end_seq_get - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_generate_new - KRB5_PROTOTYPE((krb5_context, krb5_ccache *id )); - -KRB5_DLLIMP char * krb5_stdcc_get_name - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_get_principal - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal *princ )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_initialize - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal princ )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_next_cred - KRB5_PROTOTYPE((krb5_context, - krb5_ccache id , - krb5_cc_cursor *cursor , - krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_resolve - KRB5_PROTOTYPE((krb5_context, krb5_ccache *id , const char *residual )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_retrieve - KRB5_PROTOTYPE((krb5_context, - krb5_ccache id , - krb5_flags whichfields , - krb5_creds *mcreds , - krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_start_seq_get - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_store - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_set_flags - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_remove - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds)); diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c deleted file mode 100644 index 4f4fcfc50..000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.c +++ /dev/null @@ -1,368 +0,0 @@ -// stdcc_util.c -// utility functions used in implementing the ccache api for krb5 -// not publicly exported -// Frank Dabek, July 1998 - -#include -#include -#include "stdcc_util.h" -#include "krb5.h" -#include "kv5m_err.h" - -#define fieldSize 255 - -/* on the Mac, we need the calls which allocate memory for the Credentials Cache to use - Ptr's in the system help, so that they stay global and so that bad things don't happen - when we call DisposePtr() on them. However, on other systems, malloc is probably the - right thing to use. - So for any place where we allocate memory for the Credentials Cache, use sys_alloc() and - define it accordingly. -*/ - -#if defined(macintosh) -#define sys_alloc(size) NewSafePtrSys(size) -#else -#define sys_alloc(size) malloc(size) -#endif - -#if defined(macintosh) -//stolen from CCacheUtils.c -// -- NewSafePtrSys ----------------- -// - analagous to NewSafePtr but memory is allocated in the system heap -Ptr NewSafePtrSys(long size) { - - Ptr retPtr; - - retPtr = NewPtrSys(size); - - if (retPtr != NULL) - HoldMemory(retPtr, size); - - return retPtr; -} -#endif - -// CopyCCDataArrayToK5 -// - copy and translate the null terminated arrays of data records -// used in k5 tickets -int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray) { - - cc_data *ccAdr, **cbase; - krb5_address *kAdr, **kbase, **constKBase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - //check pointer - if (cc->addresses == NULL) { - kc->addresses = NULL; - return 0; } - } else if (whichArray == kAuthDataArray) { - //check pointer - if (cc->authdata == NULL) { - kc->authdata = NULL; - return 0; } - } else return -1; - - - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - //calc number of records - while (*cbase++ != NULL) numRecords++; - //allocate new array - constKBase = kbase = (krb5_address **)malloc((numRecords+1)*sizeof(char *)); - //reset base - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - - - //copy records - while (*cbase != NULL) { - *kbase = (krb5_address *)malloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - kAdr->magic = (whichArray == kAddressArray) ? KV5M_ADDRESS : KV5M_AUTHDATA; - kAdr->addrtype = ccAdr->type; - kAdr->length = ccAdr->length; - kAdr->contents = (krb5_octet *)malloc(kAdr->length); - memcpy(kAdr->contents, ccAdr->data, kAdr->length); - //next element please - kbase++; cbase++; - } - - //write terminator - *kbase = NULL; - if (whichArray == kAddressArray) kc->addresses = constKBase; - else kc->authdata = (krb5_authdata **)constKBase; - - return 0; -} - -// copyK5DataArrayToCC -// - analagous to above, but in the other direction -int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) { - - cc_data *ccAdr, **cbase, **constCBase; - krb5_address *kAdr, **kbase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - //check pointer - if (kc->addresses == NULL) { - cc->addresses = NULL; - return 0; } - } else if (whichArray == kAuthDataArray) { - //check pointer - if (kc->authdata == NULL) { - cc->authdata = NULL; - return 0; } - } else return -1; - - - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - //calc number of records - while (*kbase++ != NULL) numRecords++; - //allocate new array - constCBase = cbase = (cc_data **)sys_alloc((numRecords+1)*sizeof(char *)); - //reset base - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - - - //copy records - while (*kbase != NULL) { - *cbase = (cc_data *)sys_alloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - ccAdr->type = kAdr->addrtype; - ccAdr->length = kAdr->length; - ccAdr->data = (unsigned char *)sys_alloc(ccAdr->length); - memcpy(ccAdr->data, kAdr->contents, kAdr->length); - //next element please - kbase++; cbase++; - } - - //write terminator - *cbase = NULL; - if (whichArray == kAddressArray) cc->addresses = (cc_data **)constCBase; - else cc->authdata = (cc_data **)constCBase; - - return 0; -} - - -// dupcctok5 -// - allocate an empty k5 style ticket and copy info from the cc_creds ticket -void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) { - - int err; - - //allocate and copy - //copy all of those damn fields back - err = krb5_parse_name(context, src->client, &(dest->client)); - err = krb5_parse_name(context, src->server, &(dest->server)); - if (err) return; //parsename fails w/o krb5.ini for example - - //copy keyblock - dest->keyblock.enctype = src->keyblock.type; - dest->keyblock.length = src->keyblock.length; - dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length); - memcpy(dest->keyblock.contents, src->keyblock.data, dest->keyblock.length); - - //copy times - dest->times.authtime = src->authtime; - dest->times.starttime = src->starttime; - dest->times.endtime = src->endtime; - dest->times.renew_till = src->renew_till; - dest->is_skey = src->is_skey; - dest->ticket_flags = src->ticket_flags; - - //more branching fields - copyCCDataArrayToK5(src, dest, kAddressArray); - dest->ticket.length = src->ticket.length; - dest->ticket.data = (char *)malloc(src->ticket.length); - memcpy(dest->ticket.data, src->ticket.data, src->ticket.length); - dest->second_ticket.length = src->second_ticket.length; - (dest->second_ticket).data = ( char *)malloc(src->second_ticket.length); - memcpy(dest->second_ticket.data, src->second_ticket.data, src->second_ticket.length); - - //zero out magic number - dest->magic = 0; - //later - //copyCCDataArrayToK5(src, dest, kAuthDataArray); - //krb5 docs say that authdata can be nulled out if we - //only want default behavior - dest->authdata = NULL; - - return; -} - -// dupK52CC -// - analagous to above but in the reverse direction -void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu) { - - krb5_address **tA; - krb5_authdata **tAd; - cc_creds *c; - int err; - #ifdef macintosh - char *tempname = NULL; - #endif - - if (cu == NULL) return; - - //allocate the cred_union - *cu = (cred_union *)sys_alloc(sizeof(cred_union)); - if ((*cu) == NULL) return; - (*cu)->cred_type = CC_CRED_V5; - - //allocate creds structure (and install) - c = (cc_creds *)sys_alloc(sizeof(cc_creds)); - if (c == NULL) return; - (*cu)->cred.pV5Cred = c; - - //convert krb5 principals to flat principals - #ifdef macintosh - //and make sure the memory for c->client and c->server is on the system heap with NewPtr - //for the Mac (krb5_unparse_name puts it in appl heap with malloc) - err = krb5_unparse_name(context, creds->client, &tempname); - c->client = sys_alloc(strlen(tempname)); - if (c->client != NULL) - strcpy(c->client,tempname); - free(tempname); - tempname = NULL; - - err = krb5_unparse_name(context, creds->server, &tempname); - c->server = sys_alloc(strlen(tempname)); - if (c->server != NULL) - strcpy(c->server,tempname); - free(tempname); - #else - err = krb5_unparse_name(context, creds->client, &(c->client)); - err = krb5_unparse_name(context, creds->server, &(c->server)); - #endif - if (err) return; - - //copy more fields - c->keyblock.type = creds->keyblock.enctype; - c->keyblock.length = creds->keyblock.length; - - if (creds->keyblock.contents != NULL) { - c->keyblock.data = (unsigned char *)sys_alloc(creds->keyblock.length); - memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length); - } else { - c->keyblock.data = NULL; - } - - c->authtime = creds->times.authtime; - c->starttime = creds->times.starttime; - c->endtime = creds->times.endtime; - c->renew_till = creds->times.renew_till; - c->is_skey = creds->is_skey; - c->ticket_flags = creds->ticket_flags; - - copyK5DataArrayToCC(creds, c, kAddressArray); - - c->ticket.length = creds->ticket.length; - if (creds->ticket.data != NULL) { - c->ticket.data = (unsigned char *)sys_alloc(creds->ticket.length); - memcpy(c->ticket.data, creds->ticket.data, creds->ticket.length); - } else { - c->ticket.data = NULL; - } - - c->second_ticket.length = creds->second_ticket.length; - if (creds->second_ticket.data != NULL) { - c->second_ticket.data = (unsigned char *)sys_alloc(creds->second_ticket.length); - memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length); - } else { - c->second_ticket.data = NULL; - } - - c->authdata = NULL; - - return; -} - - -// bitTst -// - utility function for below function -int bitTst(int var, int mask) { - - return var & mask; -} - -// stdccCredsMatch -// - check to see if the creds match based on the whichFields variable -// NOTE: if whichfields is zero we are now comparing 'standard fields.' -// This is the bug that was killing fetch for a week. The behaviour -// is what krb5 expects, however. -int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields) { - - krb5_ticket_times b, m; - krb5_authdata **bp, **mp; - krb5_boolean retval; - krb5_principal_data p1, p2; - - - //always check the standard fields - if ((krb5_principal_compare(context, base->client, match->client) && - krb5_principal_compare(context, base->server, match->server)) == false) - return FALSE; - - if (bitTst(whichfields, KRB5_TC_MATCH_TIMES)) { - //test for matching times - //according to the file cache implementation we do: - if (match->times.renew_till) { - if (match->times.renew_till > base->times.renew_till) - return FALSE; /* this one expires too late */ - } - if (match->times.endtime) { - if (match->times.endtime > base->times.endtime) - return FALSE; /* this one expires too late */ - } - } //continue search - - if (bitTst(whichfields, KRB5_TC_MATCH_IS_SKEY)) - if (base->is_skey != match->is_skey) return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_FLAGS)) - if (base->ticket_flags != match->ticket_flags) return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_TIMES_EXACT)) { - b = base->times; m = match->times; - if ((b.authtime != m.authtime) || - (b.starttime != m.starttime) || - (b.endtime != m.endtime) || - (b.renew_till != m.renew_till)) return false; - } - - if (bitTst(whichfields, KRB5_TC_MATCH_AUTHDATA)) { - bp = base->authdata; - mp = match->authdata; - if ((bp != NULL) && (mp != NULL)) { - while ( (bp) && (*bp != NULL) ){ - if (( (*bp)->ad_type != (*mp)->ad_type) || - ( (*bp)->length != (*mp)->length) || - ( memcmp( (*bp)->contents, (*mp)->contents, (*bp)->length) != 0)) return false; - mp++; bp++; - } - } - } - - if (bitTst(whichfields, KRB5_TC_MATCH_SRV_NAMEONLY)) { - //taken from cc_retrv.c - retval = krb5_principal_compare(context, base->client,match->client); - if (!retval) return false; - - } - - if (bitTst(whichfields, KRB5_TC_MATCH_2ND_TKT)) - if ( (base->second_ticket.length != match->second_ticket.length) || - (memcmp(base->second_ticket.data, match->second_ticket.data, base->second_ticket.length) != 0)) - return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_KTYPE)) - if (base->keyblock.enctype != match->keyblock.enctype) return false; - - //if we fall through to here, they must match - return true; -} diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h deleted file mode 100644 index 7d0af3dcb..000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.h +++ /dev/null @@ -1,25 +0,0 @@ -//stdcc_util.h -// -// Frank Dabek, July 1998 - -#if defined(macintosh) -#include "CCache.h" -#endif - -#if defined(_MSDOS) || defined(_WIN32) -#include "cacheapi.h" -#endif - -#include "krb5.h" - -//protoypes for private functions declared in stdcc_util.c -int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray); -int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray); -void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest); -void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu); -int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields); -int bitTst(int var, int mask); -void typeK52cc(krb5_context context, krb5_creds *creds, cc_creds *c, char **client, char **server); -#define kAddressArray 4 -#define kAuthDataArray 5 - diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c index 4570f8053..ae89334a0 100644 --- a/src/lib/krb5/ccache/ccbase.c +++ b/src/lib/krb5/ccache/ccbase.c @@ -31,7 +31,11 @@ struct krb5_cc_typelist krb5_cc_ops *ops; struct krb5_cc_typelist *next; }; -static struct krb5_cc_typelist *cc_typehead = 0; +extern krb5_cc_ops krb5_mcc_ops; + +static struct krb5_cc_typelist cc_entry = { &krb5_mcc_ops, NULL }; + +static struct krb5_cc_typelist *cc_typehead = &cc_entry; /* * Register a new credentials cache type diff --git a/src/lib/krb5/configure.in b/src/lib/krb5/configure.in index 1f924319a..b42fbf0ce 100644 --- a/src/lib/krb5/configure.in +++ b/src/lib/krb5/configure.in @@ -12,6 +12,7 @@ AC_CHECK_FUNCS(flock fchmod chmod strftime strptime geteuid setenv unsetenv gete AC_REPLACE_FUNCS(vfprintf vsprintf strdup strcasecmp strerror memmove daemon getuid sscanf syslog) KRB5_AC_REGEX_FUNCS dnl +KRB5_SOCKADDR_SA_LEN KRB5_BUILD_LIBRARY_WITH_DEPS KRB5_BUILD_LIBOBJS KRB5_BUILD_PROGRAM diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et index d8f8533c8..b483116e1 100644 --- a/src/lib/krb5/error_tables/krb5_err.et +++ b/src/lib/krb5/error_tables/krb5_err.et @@ -315,4 +315,6 @@ error_code KRB5_CHPW_PWDNULL, "New password cannot be zero length" error_code KRB5_CHPW_FAIL, "Password change failed" error_code KRB5_KT_FORMAT, "Bad format in keytab" +error_code KRB5_NOPERM_ETYPE, "Encryption type not permitted" + end diff --git a/src/lib/krb5/keytab/file/ChangeLog b/src/lib/krb5/keytab/file/ChangeLog index 2120127db..4e575b651 100644 --- a/src/lib/krb5/keytab/file/ChangeLog +++ b/src/lib/krb5/keytab/file/ChangeLog @@ -1,3 +1,8 @@ +1998-10-27 Marc Horowitz + + * ktf_g_ent.c (krb5_ktfile_get_entry): restructure the code to use + the compare_enctypes function and not leak memory + Fri Feb 27 18:03:33 1998 Theodore Ts'o * Makefile.in: Changed thisconfigdir to point at the lib/krb5 diff --git a/src/lib/krb5/keytab/file/ktf_g_ent.c b/src/lib/krb5/keytab/file/ktf_g_ent.c index 7122cb41d..57d6edabd 100644 --- a/src/lib/krb5/keytab/file/ktf_g_ent.c +++ b/src/lib/krb5/keytab/file/ktf_g_ent.c @@ -41,6 +41,7 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry) krb5_keytab_entry cur_entry, new_entry; krb5_error_code kerror = 0; int found_wrong_kvno = 0; + krb5_boolean similar; /* Open the keyfile for reading */ if ((kerror = krb5_ktfileint_openr(context, id))) @@ -53,53 +54,69 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry) cur_entry.principal = 0; cur_entry.vno = 0; cur_entry.key.contents = 0; + while (TRUE) { - krb5_enctype entry_type; - if ((kerror = krb5_ktfileint_read_entry(context, id, &new_entry))) break; - switch (enctype) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_RAW: - enctype = ENCTYPE_DES_CBC_CRC; - break; + /* by the time this loop exits, it must either free cur_entry, + and copy new_entry there, or free new_entry. Otherwise, it + leaks. */ + + /* if the enctype is not ignored and doesn't match, free new_entry + and continue to the next */ + + if (enctype != IGNORE_ENCTYPE) { + if ((kerror = krb5_c_enctype_compare(context, enctype, + new_entry.key.enctype, + &similar))) { + krb5_kt_free_entry(context, &new_entry); + break; + } + + if (!similar) { + krb5_kt_free_entry(context, &new_entry); + continue; + } } - entry_type = new_entry.key.enctype; - switch(entry_type) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_RAW: - entry_type = ENCTYPE_DES_CBC_CRC; - break; + /* if the principal isn't the one requested, free new_entry + and continue to the next. */ + + if (!krb5_principal_compare(context, principal, new_entry.principal)) { + krb5_kt_free_entry(context, &new_entry); + continue; } - if (((enctype == IGNORE_ENCTYPE)|| - (entry_type == enctype))&& - krb5_principal_compare(context, principal, new_entry.principal)) { - if (kvno == IGNORE_VNO) { - if (! cur_entry.principal || - (cur_entry.vno < new_entry.vno)) - { - krb5_kt_free_entry(context, &cur_entry); - cur_entry = new_entry; - } - } else { - if (new_entry.vno == kvno) { - krb5_kt_free_entry(context, &cur_entry); - cur_entry = new_entry; - break; - } else - found_wrong_kvno++; - } + if (kvno == IGNORE_VNO) { + /* if this is the first match, or if the new vno is + bigger, free the current and keep the new. Otherwise, + free the new. */ + + if (! cur_entry.principal || + (new_entry.vno > cur_entry.vno)) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + } else { + krb5_kt_free_entry(context, &new_entry); + } } else { + /* if this kvno matches, free the current (will there ever + be one?), keep the new, and break out. Otherwise, remember + that we were here so we can return the right error, and + free the new */ + + if (new_entry.vno == kvno) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + break; + } else { + found_wrong_kvno++; krb5_kt_free_entry(context, &new_entry); + } } } + if (kerror == KRB5_KT_END) { if (cur_entry.principal) kerror = 0; diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 49d6ef3bb..9d1cfb02a 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,39 @@ +1998-10-27 Marc Horowitz + + * vfy_increds.c: rearrange the code a bit to make it more clear + that the logic is correct. + + * str_conv.c: remove enctype and cksumtype string converstions. + They're in the crypto library now, since the information drops + right into the enctype table. + + * ser_eblk.c: ifdef the whole file out, since it's not used + anywhere. it should probably be deleted, but I'm not sure about + backward-compatibility issues yet. + + * rd_req_dec.c: check the auth_context permit-all flag and + permitted_enctypes list, and reject the request if the policy + check fails. + + * init_ctx.c: add code to initialize the prng. It's not great, + but can be improved, and the prng is reseeded when new keys are + processed. Read permitted_enctypes from the krb5.conf file, and + provide accessor functions for it. Make the various etype list + parsers share code as a side effect. + + * get_creds.c: add krb5_get_{validat,renew}ed_creds functions, + which are part of the new init_creds api. The prototypes were + already in, krb5.hin but there was no implementing code. + + * auth_con.c, auth_con.h: add a list of permitted enctypes to the + auth_context for rd_req to check, and create accessor functions + for this list. + + * Makefile.in, enc_helper.c: add enc_helper.c. This provides a + wrapper around the conventional way the library encrypts and wraps + encoded asn.1 structures, so the code isn't repeated in a dozen + places. + Wed Aug 19 17:27:51 1998 Tom Yu * conv_princ.c: Add some additional entries to sconv_list that diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index ec6384e07..3c734210c 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -32,6 +32,7 @@ STLIBOBJS= \ cp_key_cnt.o \ decode_kdc.o \ decrypt_tk.o \ + enc_helper.o \ encode_kdc.o \ encrypt_tk.o \ free_rtree.o \ @@ -114,6 +115,7 @@ OBJS= addr_comp.$(OBJEXT) \ cp_key_cnt.$(OBJEXT) \ decode_kdc.$(OBJEXT) \ decrypt_tk.$(OBJEXT) \ + enc_helper.$(OBJEXT) \ encode_kdc.$(OBJEXT) \ encrypt_tk.$(OBJEXT) \ free_rtree.$(OBJEXT) \ @@ -197,6 +199,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/cp_key_cnt.c \ $(srcdir)/decode_kdc.c \ $(srcdir)/decrypt_tk.c \ + $(srcdir)/enc_helper.c \ $(srcdir)/encode_kdc.c \ $(srcdir)/encrypt_tk.c \ $(srcdir)/free_rtree.c \ diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c index 379508623..335f7ae7d 100644 --- a/src/lib/krb5/krb/auth_con.c +++ b/src/lib/krb5/krb/auth_con.c @@ -1,4 +1,3 @@ - #include "k5-int.h" #include "auth_con.h" @@ -71,6 +70,8 @@ krb5_auth_con_free(context, auth_context) krb5_free_keyblock(context, auth_context->remote_subkey); if (auth_context->rcache) krb5_rc_close(context, auth_context->rcache); + if (auth_context->permitted_etypes) + krb5_xfree(auth_context->permitted_etypes); free(auth_context); return 0; } @@ -274,12 +275,16 @@ krb5_auth_con_initivector(context, auth_context) krb5_context context; krb5_auth_context auth_context; { + krb5_error_code ret; + if (auth_context->keyblock) { - int size = krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; + size_t blocksize; - if ((auth_context->i_vector = (krb5_pointer)malloc(size))) { - memset(auth_context->i_vector, 0, size); + if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype, + &blocksize))) + return(ret); + if ((auth_context->i_vector = (krb5_pointer)malloc(blocksize))) { + memset(auth_context->i_vector, 0, blocksize); return 0; } return ENOMEM; @@ -347,3 +352,58 @@ krb5_auth_con_getrcache(context, auth_context, rcache) return 0; } +krb5_error_code +krb5_auth_con_setpermetypes(context, auth_context, permetypes) + krb5_context context; + krb5_auth_context auth_context; + const krb5_enctype * permetypes; +{ + krb5_enctype * newpe; + int i; + + for (i=0; permetypes[i]; i++) + ; + i++; /* include the zero */ + + if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype))) + == NULL) + return(ENOMEM); + + if (auth_context->permitted_etypes) + krb5_xfree(auth_context->permitted_etypes); + + auth_context->permitted_etypes = newpe; + + memcpy(newpe, permetypes, i*sizeof(krb5_enctype)); + + return 0; +} + +krb5_error_code +krb5_auth_con_getpermetypes(context, auth_context, permetypes) + krb5_context context; + krb5_auth_context auth_context; + krb5_enctype ** permetypes; +{ + krb5_enctype * newpe; + int i; + + if (! auth_context->permitted_etypes) { + *permetypes = NULL; + return(0); + } + + for (i=0; auth_context->permitted_etypes[i]; i++) + ; + i++; /* include the zero */ + + if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype))) + == NULL) + return(ENOMEM); + + *permetypes = newpe; + + memcpy(newpe, auth_context->permitted_etypes, i*sizeof(krb5_enctype)); + + return(0); +} diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h index 9d9df0e86..e6704169e 100644 --- a/src/lib/krb5/krb/auth_con.h +++ b/src/lib/krb5/krb/auth_con.h @@ -20,6 +20,7 @@ struct _krb5_auth_context { krb5_cksumtype safe_cksumtype; /* mk_safe, ... */ krb5_pointer i_vector; /* mk_priv, rd_priv only */ krb5_rcache rcache; + krb5_enctype * permitted_etypes; /* rd_req */ }; diff --git a/src/lib/krb5/krb/decode_kdc.c b/src/lib/krb5/krb/decode_kdc.c index 71e01a811..60c983878 100644 --- a/src/lib/krb5/krb/decode_kdc.c +++ b/src/lib/krb5/krb/decode_kdc.c @@ -48,18 +48,28 @@ krb5_decode_kdc_rep(context, enc_rep, key, dec_rep) { krb5_error_code retval; krb5_kdc_rep *local_dec_rep; + krb5_keyusage usage; - if (krb5_is_as_rep(enc_rep)) + if (krb5_is_as_rep(enc_rep)) { + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; retval = decode_krb5_as_rep(enc_rep, &local_dec_rep); - else if (krb5_is_tgs_rep(enc_rep)) + } else if (krb5_is_tgs_rep(enc_rep)) { + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; + /* KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY would go here, except + that this client code base doesn't ever put a subkey in the + tgs_req authenticator, so the tgs_rep is never encrypted in + one. (Check send_tgs.c:krb5_send_tgs_basic(), near the top + where authent.subkey is set to 0) */ retval = decode_krb5_tgs_rep(enc_rep, &local_dec_rep); - else + } else { return KRB5KRB_AP_ERR_MSG_TYPE; + } if (retval) return retval; - if (retval = krb5_kdc_rep_decrypt_proc(context, key, 0, local_dec_rep)) + if (retval = krb5_kdc_rep_decrypt_proc(context, key, &usage, + local_dec_rep)) krb5_free_kdc_rep(context, local_dec_rep); else *dec_rep = local_dec_rep; diff --git a/src/lib/krb5/krb/decrypt_tk.c b/src/lib/krb5/krb/decrypt_tk.c index 354a3f2a0..47f675591 100644 --- a/src/lib/krb5/krb/decrypt_tk.c +++ b/src/lib/krb5/krb/decrypt_tk.c @@ -42,43 +42,27 @@ krb5_decrypt_tkt_part(context, srv_key, ticket) register krb5_ticket FAR *ticket; { krb5_enc_tkt_part *dec_tkt_part; - krb5_encrypt_block eblock; krb5_data scratch; krb5_error_code retval; if (!valid_enctype(ticket->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, ticket->enc_part.enctype); - scratch.length = ticket->enc_part.ciphertext.length; if (!(scratch.data = malloc(ticket->enc_part.ciphertext.length))) return(ENOMEM); - /* do any necessary key pre-processing */ - if (retval = krb5_process_key(context, &eblock, srv_key)) { - free(scratch.data); - return(retval); - } - /* call the encryption routine */ - if (retval = krb5_decrypt(context, - (krb5_pointer) ticket->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, scratch.length, - &eblock, 0)) { - (void) krb5_finish_key(context, &eblock); + if (retval = krb5_c_decrypt(context, srv_key, + KRB5_KEYUSAGE_KDC_REP_TICKET, 0, + &ticket->enc_part, &scratch)) { free(scratch.data); return retval; } + #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - retval = krb5_finish_key(context, &eblock); - if (retval) { - clean_scratch(); - return retval; - } /* now decode the decrypted stuff */ retval = decode_krb5_enc_tkt_part(&scratch, &dec_tkt_part); if (!retval) { diff --git a/src/lib/krb5/krb/enc_helper.c b/src/lib/krb5/krb/enc_helper.c new file mode 100644 index 000000000..ff4214937 --- /dev/null +++ b/src/lib/krb5/krb/enc_helper.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include "k5-int.h" + +krb5_error_code +krb5_encrypt_helper(context, key, usage, plain, cipher) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *plain; + krb5_enc_data *cipher; +{ + krb5_error_code ret; + size_t enclen; + + if (ret = krb5_c_encrypt_length(context, key->enctype, plain->length, + &enclen)) + return(ret); + + cipher->ciphertext.length = enclen; + if ((cipher->ciphertext.data = (char *) malloc(enclen)) == NULL) + return(ret); + + if (ret = krb5_c_encrypt(context, key, usage, 0, plain, cipher)) + free(cipher->ciphertext.data); + + return(ret); +} + diff --git a/src/lib/krb5/krb/encode_kdc.c b/src/lib/krb5/krb/encode_kdc.c index bb9311f6a..e20c1f536 100644 --- a/src/lib/krb5/krb/encode_kdc.c +++ b/src/lib/krb5/krb/encode_kdc.c @@ -41,10 +41,12 @@ /* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG stuff... */ krb5_error_code -krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) +krb5_encode_kdc_rep(context, type, encpart, using_subkey, client_key, + dec_rep, enc_rep) krb5_context context; const krb5_msgtype type; const krb5_enc_kdc_rep_part * encpart; + int using_subkey; const krb5_keyblock * client_key; krb5_kdc_rep * dec_rep; krb5_data ** enc_rep; @@ -52,14 +54,20 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) krb5_data *scratch; krb5_error_code retval; krb5_enc_kdc_rep_part tmp_encpart; - krb5_encrypt_block eblock; + krb5_keyusage usage; if (!valid_enctype(dec_rep->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; switch (type) { case KRB5_AS_REP: + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; + break; case KRB5_TGS_REP: + if (using_subkey) + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY; + else + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; break; default: return KRB5_BADMSGTYPE; @@ -89,23 +97,8 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } - krb5_use_enctype(context, &eblock, client_key->enctype); - dec_rep->enc_part.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - dec_rep->enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - dec_rep->enc_part.ciphertext.length - scratch->length); - if (!(dec_rep->enc_part.ciphertext.data = - malloc(dec_rep->enc_part.ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } + retval = krb5_encrypt_helper(context, client_key, usage, scratch, + &dec_rep->enc_part); #define cleanup_encpart() { \ (void) memset(dec_rep->enc_part.ciphertext.data, 0, \ @@ -114,30 +107,10 @@ free(dec_rep->enc_part.ciphertext.data); \ dec_rep->enc_part.ciphertext.length = 0; \ dec_rep->enc_part.ciphertext.data = 0;} - retval = krb5_process_key(context, &eblock, client_key); - if (retval) { - goto clean_encpart; - } - -#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);} - - retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) dec_rep->enc_part.ciphertext.data, - scratch->length, &eblock, 0); - if (retval) { - goto clean_prockey; - } - - dec_rep->enc_part.enctype = krb5_eblock_enctype(context, &eblock); - - /* do some cleanup */ cleanup_scratch(); - retval = krb5_finish_key(context, &eblock); - if (retval) { - cleanup_encpart(); - return retval; - } + if (retval) + return(retval); /* now it's ready to be encoded for the wire! */ @@ -149,18 +122,9 @@ dec_rep->enc_part.ciphertext.data = 0;} retval = encode_krb5_tgs_rep(dec_rep, enc_rep); break; } + if (retval) cleanup_encpart(); - return retval; - - clean_prockey: - cleanup_prockey(); - clean_encpart: - cleanup_encpart(); - clean_scratch: - cleanup_scratch(); return retval; } - - diff --git a/src/lib/krb5/krb/encrypt_tk.c b/src/lib/krb5/krb/encrypt_tk.c index cb1fb28b9..e1a1b1850 100644 --- a/src/lib/krb5/krb/encrypt_tk.c +++ b/src/lib/krb5/krb/encrypt_tk.c @@ -44,7 +44,6 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket) const krb5_keyblock *srv_key; register krb5_ticket *dec_ticket; { - krb5_encrypt_block eblock; krb5_data *scratch; krb5_error_code retval; register krb5_enc_tkt_part *dec_tkt_part = dec_ticket->enc_part2; @@ -57,64 +56,12 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket) #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } - krb5_use_enctype(context, &eblock, srv_key->enctype); - - dec_ticket->enc_part.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - dec_ticket->enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - dec_ticket->enc_part.ciphertext.length - scratch->length); - if (!(dec_ticket->enc_part.ciphertext.data = - malloc(dec_ticket->enc_part.ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } - -#define cleanup_encpart() {\ -(void) memset(dec_ticket->enc_part.ciphertext.data, 0,\ - dec_ticket->enc_part.ciphertext.length); \ -free(dec_ticket->enc_part.ciphertext.data); \ -dec_ticket->enc_part.ciphertext.length = 0; \ -dec_ticket->enc_part.ciphertext.data = 0;} - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, srv_key))) { - goto clean_encpart; - } - -#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);} - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) dec_ticket->enc_part.ciphertext.data, - scratch->length, &eblock, 0))) { - goto clean_prockey; - } - - dec_ticket->enc_part.enctype = srv_key->enctype; - - /* ticket is now assembled-- do some cleanup */ - cleanup_scratch(); - - if ((retval = krb5_finish_key(context, &eblock))) { - cleanup_encpart(); - return retval; - } - - return 0; + retval = krb5_encrypt_helper(context, srv_key, + KRB5_KEYUSAGE_KDC_REP_TICKET, scratch, + &dec_ticket->enc_part); - clean_prockey: - cleanup_prockey(); - clean_encpart: - cleanup_encpart(); - clean_scratch: cleanup_scratch(); - return retval; + return(retval); } diff --git a/src/lib/krb5/krb/gen_seqnum.c b/src/lib/krb5/krb/gen_seqnum.c index 3694d2cd0..4b3cd6fe6 100644 --- a/src/lib/krb5/krb/gen_seqnum.c +++ b/src/lib/krb5/krb/gen_seqnum.c @@ -38,71 +38,15 @@ krb5_generate_seq_number(context, key, seqno) const krb5_keyblock *key; krb5_int32 *seqno; { - krb5_pointer random_state; - krb5_encrypt_block eblock; - krb5_keyblock *subkey = 0; + krb5_data seed; krb5_error_code retval; - struct tval { - krb5_int32 seconds; - krb5_int32 microseconds; - } timenow; - krb5_octet *intmp = 0, *outtmp = 0; - int esize; - if (!valid_enctype(key->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - - krb5_use_enctype(context, &eblock, key->enctype); - - if ((retval = krb5_init_random_key(context, &eblock, key, &random_state))) + seed.length = key->length; + seed.data = key->contents; + if ((retval = krb5_c_random_seed(context, &seed))) return(retval); - - if ((retval = krb5_random_key(context, &eblock, random_state, &subkey))) { - (void) krb5_finish_random_key(context, &eblock, &random_state); - return retval; - } - /* ignore the error if any, since we've already gotten the key out */ - if ((retval = krb5_finish_random_key(context, &eblock, &random_state))) { - krb5_free_keyblock(context, subkey); - return retval; - } - - esize = krb5_encrypt_size(sizeof(timenow), eblock.crypto_entry); - intmp = (krb5_octet *)malloc(esize); - if (!intmp) { - retval = ENOMEM; - goto cleanup; - } - outtmp = (krb5_octet *)malloc(esize); - if (!outtmp) { - retval = ENOMEM; - goto cleanup; - } - if ((retval = krb5_process_key(context, &eblock, subkey))) { - goto cleanup; - } - if ((retval = krb5_us_timeofday(context, &timenow.seconds, - &timenow.microseconds))) { - goto cleanup; - } - memcpy((char *)intmp, (char *)&timenow, sizeof(timenow)); - - retval = krb5_encrypt(context, (krb5_pointer)intmp, (krb5_pointer)outtmp, - sizeof(timenow), &eblock, 0); - (void) krb5_finish_key(context, &eblock); - if (retval) - goto cleanup; - - memcpy((char *) seqno, (char *)outtmp, sizeof(krb5_int32)); - -cleanup: - if (subkey) - krb5_free_keyblock(context, subkey); - if (intmp) - krb5_xfree(intmp); - if (outtmp) - krb5_xfree(outtmp); - return retval; + seed.length = sizeof(*seqno); + seed.data = (char *) seqno; + return(krb5_c_random_make_octets(context, &seed)); } - diff --git a/src/lib/krb5/krb/gen_subkey.c b/src/lib/krb5/krb/gen_subkey.c index 89e21a1b7..861d61e72 100644 --- a/src/lib/krb5/krb/gen_subkey.c +++ b/src/lib/krb5/krb/gen_subkey.c @@ -32,24 +32,21 @@ krb5_generate_subkey(context, key, subkey) const krb5_keyblock *key; krb5_keyblock **subkey; { - krb5_pointer random_state; - krb5_encrypt_block eblock; krb5_error_code retval; + krb5_data seed; - if (!valid_enctype(key->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + seed.length = key->length; + seed.data = key->contents; + if ((retval = krb5_c_random_seed(context, &seed))) + return(retval); - krb5_use_enctype(context, &eblock, key->enctype); + if ((*subkey = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL) + return(ENOMEM); - if ((retval = krb5_init_random_key(context, &eblock, key, &random_state))) - return(retval); - if ((retval = krb5_random_key(context, &eblock, random_state, subkey))) { - (void) krb5_finish_random_key(context, &eblock, &random_state); + if ((retval = krb5_c_make_random_key(context, key->enctype, *subkey))) { krb5_xfree(*subkey); - return retval; - } - /* ignore the error if any, since we've already gotten the key out */ - (void) krb5_finish_random_key(context, &eblock, &random_state); - return 0; -} + return(retval); + } + return(0); +} diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index 3a1ec526b..37f2bb5a9 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -160,12 +160,6 @@ krb5_get_credentials_val_renew_core(context, options, ccache, krb5_creds **tgts = 0; krb5_flags fields; - retval = krb5_get_credentials_core(context, options, ccache, - in_creds, out_creds, - &mcreds, &fields); - - if (retval) return retval; - switch(which) { case INT_GC_VALIDATE: retval = krb5_get_cred_from_kdc_validate(context, ccache, @@ -219,3 +213,104 @@ krb5_get_credentials_renew(context, options, ccache, in_creds, out_creds) in_creds, out_creds, INT_GC_RENEW)); } + +static krb5_error_code +krb5_validate_or_renew_creds(context, creds, client, ccache, in_tkt_service, + validate) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; + int validate; +{ + krb5_error_code ret; + krb5_creds in_creds; /* only client and server need to be filled in */ + krb5_creds *out_creds; + krb5_creds **tgts; + + memset((char *)&in_creds, 0, sizeof(krb5_creds)); + + in_creds.server = NULL; + tgts = NULL; + + in_creds.client = client; + + if (in_tkt_service) { + /* this is ugly, because so are the data structures involved. I'm + in the library, so I'm going to manipulate the data structures + directly, otherwise, it will be worse. */ + + if (ret = krb5_parse_name(context, in_tkt_service, &in_creds.server)) + goto cleanup; + + /* stuff the client realm into the server principal. + realloc if necessary */ + if (in_creds.server->realm.length < in_creds.client->realm.length) + if ((in_creds.server->realm.data = + (char *) realloc(in_creds.server->realm.data, + in_creds.client->realm.length)) == NULL) { + ret = ENOMEM; + goto cleanup; + } + + in_creds.server->realm.length = in_creds.client->realm.length; + memcpy(in_creds.server->realm.data, in_creds.client->realm.data, + in_creds.client->realm.length); + } else { + if (ret = krb5_build_principal_ext(context, &in_creds.server, + in_creds.client->realm.length, + in_creds.client->realm.data, + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME, + in_creds.client->realm.length, + in_creds.client->realm.data, + 0)) + goto cleanup; + } + + if (validate) + ret = krb5_get_cred_from_kdc_validate(context, ccache, + &in_creds, &out_creds, &tgts); + else + ret = krb5_get_cred_from_kdc_renew(context, ccache, + &in_creds, &out_creds, &tgts); + + /* ick. copy the struct contents, free the container */ + + *creds = *out_creds; + krb5_xfree(out_creds); + +cleanup: + + if (in_creds.server) + krb5_free_principal(context, in_creds.server); + if (tgts) + krb5_free_tgt_creds(context, tgts); + + return(ret); +} + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_get_validated_creds(context, creds, client, ccache, in_tkt_service) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; +{ + return(krb5_validate_or_renew_creds(context, creds, client, ccache, + in_tkt_service, 1)); +} + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_get_renewed_creds(context, creds, client, ccache, in_tkt_service) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; +{ + return(krb5_validate_or_renew_creds(context, creds, client, ccache, + in_tkt_service, 0)); +} diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 45a076246..c517062f8 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -16,7 +16,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, krb5_data *password; krb5_error_code ret; krb5_data defsalt; - krb5_encrypt_block eblock; char *clientstr; char promptstr[1024]; krb5_prompt prompt; @@ -35,11 +34,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, as_key->length = 0; } - if (!valid_enctype(etype)) - return(KRB5_PROG_ETYPE_NOSUPP); - - krb5_use_enctype(context, &eblock, etype); - if (password->data[0] == '\0') { if (prompter == NULL) return(EIO); @@ -70,7 +64,7 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, defsalt.length = 0; } - ret = krb5_string_to_key(context, &eblock, as_key, password, salt); + ret = krb5_c_string_to_key(context, etype, password, salt, as_key); if (defsalt.length) krb5_xfree(defsalt.data); diff --git a/src/lib/krb5/krb/in_tkt_pwd.c b/src/lib/krb5/krb/in_tkt_pwd.c index 7373f62f1..e03883e9d 100644 --- a/src/lib/krb5/krb/in_tkt_pwd.c +++ b/src/lib/krb5/krb/in_tkt_pwd.c @@ -47,15 +47,9 @@ pwd_keyproc(context, type, salt, keyseed, key) krb5_keyblock ** key; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data * password; int pwsize; - if (!valid_enctype(type)) - return KRB5_PROG_ETYPE_NOSUPP; - - krb5_use_enctype(context, &eblock, type); - password = (krb5_data *)keyseed; if (!password->length) { @@ -73,8 +67,9 @@ pwd_keyproc(context, type, salt, keyseed, key) if (!(*key = (krb5_keyblock *)malloc(sizeof(**key)))) return ENOMEM; - if ((retval = krb5_string_to_key(context, &eblock, *key, password, salt))) + if ((retval = krb5_c_string_to_key(context, type, password, salt, *key))) krb5_xfree(*key); + return(retval); } diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index daa9fd95f..2285b0f42 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -23,6 +23,32 @@ * krb5_init_contex() */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + #include "k5-int.h" #include #include "brand.c" @@ -37,6 +63,8 @@ krb5_init_context(context) { krb5_context ctx = 0; krb5_error_code retval; + krb5_timestamp now; + krb5_data seed; int tmp; /* Initialize error tables */ @@ -70,6 +98,14 @@ krb5_init_context(context) if ((retval = krb5_os_init_context(ctx))) goto cleanup; + /* initialize the prng (not well, but passable) */ + if ((retval = krb5_timeofday(ctx, &now))) + goto cleanup; + seed.length = sizeof(now); + seed.data = (char *) &now; + if ((retval = krb5_c_random_seed(ctx, &seed))) + goto cleanup; + ctx->default_realm = 0; profile_get_integer(ctx->profile, "libdefaults", "clockskew", 0, 5 * 60, &tmp); @@ -197,26 +233,27 @@ krb5_set_default_in_tkt_ktypes(context, ktypes) return 0; } -krb5_error_code -krb5_get_default_in_tkt_ktypes(context, ktypes) - krb5_context context; - krb5_enctype **ktypes; +static krb5_error_code +get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list) + krb5_context context; + krb5_enctype **ktypes; + char *profstr; + int ctx_count; + krb5_enctype FAR *ctx_list; { - krb5_enctype * old_ktypes; + krb5_enctype *old_ktypes; if (context->in_tkt_ktype_count) { - /* application-set defaults */ - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * - (context->in_tkt_ktype_count + 1)))) { - memcpy(old_ktypes, context->in_tkt_ktypes, sizeof(krb5_enctype) * - context->in_tkt_ktype_count); - old_ktypes[context->in_tkt_ktype_count] = 0; - } else { - return ENOMEM; - } + /* application-set defaults */ + if ((old_ktypes = + (krb5_enctype *)malloc(sizeof(krb5_enctype) * + (ctx_count + 1)))) { + memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count); + old_ktypes[ctx_count] = 0; + } else { + return ENOMEM; + } } else { - /* taken directly from krb5_get_tgs_ktypes... */ /* XXX - For now, we only support libdefaults Perhaps this should be extended to allow for per-host / per-realm @@ -228,9 +265,9 @@ krb5_get_default_in_tkt_ktypes(context, ktypes) int i, j, count; krb5_error_code code; - code = profile_get_string(context->profile, - "libdefaults", "default_tkt_enctypes", NULL, - "des-cbc-md5 des-cbc-crc", + code = profile_get_string(context->profile, "libdefaults", profstr, + NULL, + "des3-hmac-sha1 des-cbc-md5 des-cbc-crc", &retval); if (code) return code; @@ -279,6 +316,16 @@ krb5_get_default_in_tkt_ktypes(context, ktypes) return 0; } +krb5_error_code +krb5_get_default_in_tkt_ktypes(context, ktypes) + krb5_context context; + krb5_enctype **ktypes; +{ + return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes", + context->in_tkt_ktype_count, + context->in_tkt_ktypes)); +} + krb5_error_code krb5_set_default_tgs_ktypes(context, ktypes) krb5_context context; @@ -317,80 +364,40 @@ krb5_get_tgs_ktypes(context, princ, ktypes) krb5_const_principal princ; krb5_enctype **ktypes; { - krb5_enctype * old_ktypes; - - if (context->tgs_ktype_count) { - - /* Application-set defaults */ - - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * - (context->tgs_ktype_count + 1)))) { - memcpy(old_ktypes, context->tgs_ktypes, sizeof(krb5_enctype) * - context->tgs_ktype_count); - old_ktypes[context->tgs_ktype_count] = 0; - } else { - return ENOMEM; - } - } else { - /* - XXX - For now, we only support libdefaults - Perhaps this should be extended to allow for per-host / per-realm - session key types. - */ - - char *retval; - char *sp, *ep; - int i, j, count; - krb5_error_code code; + return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes", + context->tgs_ktype_count, + context->tgs_ktypes)); +} - code = profile_get_string(context->profile, - "libdefaults", "default_tgs_enctypes", NULL, - "des-cbc-md5 des-cbc-crc", - &retval); - if (code) - return code; +krb5_error_code +krb5_get_permitted_enctypes(context, ktypes) + krb5_context context; + krb5_enctype **ktypes; +{ + return(get_profile_etype_list(context, ktypes, "permitted_enctypes", + context->tgs_ktype_count, + context->tgs_ktypes)); +} - count = 0; - sp = retval; - while (sp) { - for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++) - ; - if (*ep) { - *ep++ = '\0'; - while (isspace(*ep)) - ep++; - } else - ep = (char *) NULL; +krb5_boolean +krb5_is_permitted_enctype(context, etype) + krb5_context context; + krb5_enctype etype; +{ + krb5_enctype *list, *ptr; + krb5_boolean ret; - count++; - sp = ep; - } - - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) == - (krb5_enctype *) NULL) - return ENOMEM; - - sp = retval; - j = 0; - i = 1; - while (1) { - if (! krb5_string_to_enctype(sp, &old_ktypes[j])) - j++; + if (krb5_get_permitted_enctypes(context, &list)) + return(0); - if (i++ >= count) - break; + + ret = 0; - /* skip to next token */ - while (*sp) sp++; - while (! *sp) sp++; - } + for (ptr = list; *ptr; ptr++) + if (*ptr == etype) + ret = 1; - old_ktypes[j] = (krb5_enctype) 0; - free(retval); - } + krb5_xfree(list); - *ktypes = old_ktypes; - return 0; + return(ret); } diff --git a/src/lib/krb5/krb/kdc_rep_dc.c b/src/lib/krb5/krb/kdc_rep_dc.c index e9431aef9..a9cbcf39b 100644 --- a/src/lib/krb5/krb/kdc_rep_dc.c +++ b/src/lib/krb5/krb/kdc_rep_dc.c @@ -41,12 +41,15 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep) krb5_kdc_rep * dec_rep; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data scratch; krb5_enc_kdc_rep_part *local_encpart; + krb5_keyusage usage; - if (!valid_enctype(dec_rep->enc_part.enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + if (decryptarg) { + usage = *(const krb5_keyusage *) decryptarg; + } else { + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; + } /* set up scratch decrypt/decode area */ @@ -55,30 +58,16 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep) return(ENOMEM); } - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, dec_rep->enc_part.enctype); + dec_rep->enc_part.enctype; - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, key))) { + if ((retval = krb5_c_decrypt(context, key, usage, 0, &dec_rep->enc_part, + &scratch))) { free(scratch.data); return(retval); } - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, (krb5_pointer) dec_rep->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - free(scratch.data); - return retval; - } #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - if ((retval = krb5_finish_key(context, &eblock))) { - clean_scratch(); - return retval; - } /* and do the decode */ retval = decode_krb5_enc_kdc_rep_part(&scratch, &local_encpart); diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c index 17c4f8c7f..87eeca961 100644 --- a/src/lib/krb5/krb/kfree.c +++ b/src/lib/krb5/krb/kfree.c @@ -148,6 +148,16 @@ krb5_free_checksum(context, val) return; } +KRB5_DLLIMP void KRB5_CALLCONV +krb5_free_checksum_contents(context, val) + krb5_context context; + register krb5_checksum *val; +{ + if (val->contents) + krb5_xfree(val->contents); + return; +} + KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred(context, val) krb5_context context; @@ -572,3 +582,4 @@ krb5_free_unparsed_name(context, val) krb5_xfree(val); return; } + diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c index 23545fb61..cdda80d06 100644 --- a/src/lib/krb5/krb/mk_cred.c +++ b/src/lib/krb5/krb/mk_cred.c @@ -28,12 +28,8 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata) krb5_enc_data * pencdata; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data * scratch; - if (pkeyblock && !valid_enctype(pkeyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - /* start by encoding to-be-encrypted part of the message */ if ((retval = encode_krb5_enc_cred_part(pcredpart, &scratch))) return retval; @@ -49,47 +45,11 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata) return 0; } - /* put together an eblock for this encryption */ - - pencdata->kvno = 0; - pencdata->enctype = pkeyblock->enctype; - - krb5_use_enctype(context, &eblock, pkeyblock->enctype); - pencdata->ciphertext.length = krb5_encrypt_size(scratch->length, - eblock.crypto_entry); - - /* add padding area, and zero it */ - if (!(scratch->data = (char *)realloc(scratch->data, - pencdata->ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - - memset(scratch->data + scratch->length, 0, - pencdata->ciphertext.length - scratch->length); - if (!(pencdata->ciphertext.data = - (char *)malloc(pencdata->ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, pkeyblock))) { - goto clean_encpart; - } - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer)scratch->data, - (krb5_pointer)pencdata->ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; - } - - retval = krb5_finish_key(context, &eblock); + retval = krb5_encrypt_helper(context, pkeyblock, + KRB5_KEYUSAGE_KRB_CRED_ENCPART, + scratch, pencdata); -clean_encpart: if (retval) { memset(pencdata->ciphertext.data, 0, pencdata->ciphertext.length); free(pencdata->ciphertext.data); @@ -97,7 +57,6 @@ clean_encpart: pencdata->ciphertext.data = 0; } -clean_scratch: memset(scratch->data, 0, scratch->length); krb5_free_data(context, scratch); diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c index 7986e1856..2e7f2ce25 100644 --- a/src/lib/krb5/krb/mk_priv.c +++ b/src/lib/krb5/krb/mk_priv.c @@ -41,13 +41,10 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, krb5_data * outbuf; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_priv privmsg; krb5_priv_enc_part privmsg_enc_part; - krb5_data *scratch1, *scratch2; - - if (!valid_enctype(keyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + krb5_data *scratch1, *scratch2, ivdata; + size_t blocksize, enclen; privmsg.enc_part.kvno = 0; /* XXX allow user-set? */ privmsg.enc_part.enctype = keyblock->enctype; @@ -66,52 +63,42 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, return retval; /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, keyblock->enctype); - privmsg.enc_part.ciphertext.length = krb5_encrypt_size(scratch1->length, - eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch1->data = realloc(scratch1->data, - privmsg.enc_part.ciphertext.length))) { - /* may destroy scratch1->data */ - krb5_xfree(scratch1); - return ENOMEM; - } + if ((retval = krb5_c_encrypt_length(context, keyblock->enctype, + scratch1->length, &enclen))) + goto clean_scratch; - memset(scratch1->data + scratch1->length, 0, - privmsg.enc_part.ciphertext.length - scratch1->length); + privmsg.enc_part.ciphertext.length = enclen; if (!(privmsg.enc_part.ciphertext.data = malloc(privmsg.enc_part.ciphertext.length))) { retval = ENOMEM; goto clean_scratch; } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, keyblock))) - goto clean_encpart; - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch1->data, - (krb5_pointer) privmsg.enc_part.ciphertext.data, - scratch1->length, &eblock, i_vector))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; + if (i_vector) { + if ((retval = krb5_c_block_size(context, keyblock->enctype, + &blocksize))) + goto clean_encpart; + + ivdata.length = blocksize; + ivdata.data = i_vector; } + if ((retval = krb5_c_encrypt(context, keyblock, + KRB5_KEYUSAGE_KRB_PRIV_ENCPART, + i_vector?&ivdata:0, + scratch1, &privmsg.enc_part))) + goto clean_encpart; + /* put last block into the i_vector */ + if (i_vector) memcpy(i_vector, privmsg.enc_part.ciphertext.data + - (privmsg.enc_part.ciphertext.length - - eblock.crypto_entry->block_length), - eblock.crypto_entry->block_length); + (privmsg.enc_part.ciphertext.length - blocksize), + blocksize); - if ((retval = encode_krb5_priv(&privmsg, &scratch2))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; - } - - /* encode private message */ - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = encode_krb5_priv(&privmsg, &scratch2))) goto clean_encpart; *outbuf = *scratch2; diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c index 45784284c..f0398475f 100644 --- a/src/lib/krb5/krb/mk_rep.c +++ b/src/lib/krb5/krb/mk_rep.c @@ -45,14 +45,11 @@ krb5_mk_rep(context, auth_context, outbuf) krb5_error_code retval; krb5_enctype enctype; krb5_ap_rep_enc_part repl; - krb5_encrypt_block eblock; krb5_ap_rep reply; krb5_data * scratch; krb5_data * toutbuf; - /* verify a valid enctype is available */ - if (!valid_enctype(enctype = auth_context->keyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + enctype = auth_context->keyblock->enctype; /* Make the reply */ if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || @@ -72,49 +69,16 @@ krb5_mk_rep(context, auth_context, outbuf) if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch))) return retval; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, enctype); - reply.enc_part.enctype = enctype; - reply.enc_part.kvno = 0; /* XXX user set? */ - - reply.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length, - eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - reply.enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - reply.enc_part.ciphertext.length - scratch->length); - if (!(reply.enc_part.ciphertext.data = - malloc(reply.enc_part.ciphertext.length))) { - retval = ENOMEM; + if ((retval = krb5_encrypt_helper(context, auth_context->keyblock, + KRB5_KEYUSAGE_AP_REP_ENCPART, + scratch, &reply.enc_part))) goto cleanup_scratch; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, auth_context->keyblock))) - goto cleanup_encpart; - - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) reply.enc_part.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto cleanup_encpart; - } - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_encpart; if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) { *outbuf = *toutbuf; krb5_xfree(toutbuf); } -cleanup_encpart: memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length); free(reply.enc_part.ciphertext.data); reply.enc_part.ciphertext.length = 0; diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c index 726bb434b..1530f7961 100644 --- a/src/lib/krb5/krb/mk_req_ext.c +++ b/src/lib/krb5/krb/mk_req_ext.c @@ -84,7 +84,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, krb5_ap_req request; krb5_data *scratch = 0; - krb5_encrypt_block eblock; krb5_data *toutbuf; request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK; @@ -98,12 +97,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket))) return(retval); - /* verify a valid enctype is available */ - if (!valid_enctype(in_creds->keyblock.enctype)) { - retval = KRB5_PROG_ETYPE_NOSUPP; - goto cleanup; - } - /* verify that the ticket is not expired */ if ((retval = krb5_validate_times(context, &in_creds->times)) != 0) goto cleanup; @@ -135,27 +128,18 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, &(*auth_context)->local_subkey))) goto cleanup; - if (in_data) { if ((*auth_context)->req_cksumtype == 0x8003) { /* XXX Special hack for GSSAPI */ checksum.checksum_type = 0x8003; checksum.length = in_data->length; checksum.contents = (krb5_octet *) in_data->data; - } else { - /* Generate checksum, XXX What should the seed be? */ - checksum.length = - krb5_checksum_size(context, (*auth_context)->req_cksumtype); - if ((checksum.contents = (krb5_octet *)malloc(checksum.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - if ((retval = krb5_calculate_checksum(context, - (*auth_context)->req_cksumtype, - in_data->data, in_data->length, - (*auth_context)->keyblock->contents, - (*auth_context)->keyblock->length, - &checksum))) + } else { + if ((retval = krb5_c_make_checksum(context, + (*auth_context)->req_cksumtype, + (*auth_context)->keyblock, + KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, + in_data, &checksum))) goto cleanup_cksum; } checksump = &checksum; @@ -188,43 +172,12 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, (*auth_context)->authentp->checksum = NULL; (*auth_context)->authentp->authorization_data = NULL; - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, in_creds->keyblock.enctype); - request.authenticator.enctype = in_creds->keyblock.enctype; - request.authenticator.kvno = 0; - request.authenticator.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - request.authenticator.ciphertext.length))) { - /* may destroy scratch->data */ - retval = ENOMEM; - goto cleanup_cksum; - } - memset(scratch->data + scratch->length, 0, - request.authenticator.ciphertext.length - scratch->length); - if (!(request.authenticator.ciphertext.data = - malloc(request.authenticator.ciphertext.length))) { - retval = ENOMEM; - goto cleanup_cksum; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock))) - goto cleanup; - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) request.authenticator.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); + if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock, + KRB5_KEYUSAGE_AP_REQ_AUTH, + scratch, &request.authenticator))) goto cleanup_cksum; - } - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_cksum; - if ((retval = encode_krb5_ap_req(&request, &toutbuf))) goto cleanup_cksum; #ifdef HAVE_C_STRUCTURE_ASSIGNMENT diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c index 1a44a75e5..0d5a49080 100644 --- a/src/lib/krb5/krb/mk_safe.c +++ b/src/lib/krb5/krb/mk_safe.c @@ -90,18 +90,11 @@ krb5_mk_safe_basic(context, userdata, keyblock, replaydata, local_addr, if ((retval = encode_krb5_safe(&safemsg, &scratch1))) return retval; - safe_checksum.length = krb5_checksum_size(context, sumtype); - if (!(safe_checksum.contents = (krb5_octet *) malloc(safe_checksum.length))) { - - retval = ENOMEM; - goto cleanup_scratch; - } - if ((retval = krb5_calculate_checksum(context, sumtype, scratch1->data, - scratch1->length, - (krb5_pointer) keyblock->contents, - keyblock->length, &safe_checksum))) { + if ((retval = krb5_c_make_checksum(context, sumtype, keyblock, + KRB5_KEYUSAGE_KRB_SAFE_CKSUM, + scratch1, &safe_checksum))) goto cleanup_checksum; - } + safemsg.checksum = &safe_checksum; if ((retval = encode_krb5_safe(&safemsg, &scratch2))) { goto cleanup_checksum; diff --git a/src/lib/krb5/krb/preauth.c b/src/lib/krb5/krb/preauth.c index c106dd15a..ab1432fdb 100644 --- a/src/lib/krb5/krb/preauth.c +++ b/src/lib/krb5/krb/preauth.c @@ -160,6 +160,10 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc, for (pa = preauth_to_use, size=0; *pa; pa++, size++) { if ((*pa)->pa_type == KRB5_PADATA_ETYPE_INFO) { + /* XXX use the first one. Is there another way to disambiguate? */ + if (etype_info) + continue; + scratch.length = (*pa)->length; scratch.data = (char *) (*pa)->contents; retval = decode_krb5_etype_info(&scratch, &etype_info); @@ -219,6 +223,8 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc, } cleanup: + if (etype_info) + krb5_free_etype_info(context, etype_info); if (f_salt) krb5_xfree(salt.data); if (send_pa_list) @@ -294,9 +300,6 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key, krb5_data * scratch; krb5_enc_data enc_data; krb5_pa_data * pa; - - - enc_data.ciphertext.data = 0; retval = krb5_us_timeofday(context, &pa_enc.patimestamp, &pa_enc.pausec); if (retval) @@ -305,8 +308,11 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key, if ((retval = encode_krb5_pa_enc_ts(&pa_enc, &scratch)) != 0) return retval; - if ((retval = krb5_encrypt_data(context, def_enc_key, 0, scratch, - &enc_data))) + enc_data.ciphertext.data = 0; + + if ((retval = krb5_encrypt_helper(context, def_enc_key, + KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS, + scratch, &enc_data))) goto cleanup; krb5_free_data(context, scratch); diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index 0a154f6e1..86d325d7b 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -117,12 +117,16 @@ krb5_error_code pa_enc_timestamp(krb5_context context, if (ret = encode_krb5_pa_enc_ts(&pa_enc, &tmp)) return(ret); - ret = krb5_encrypt_data(context, as_key, 0, tmp, &enc_data); + ret = krb5_encrypt_helper(context, as_key, + KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS, + tmp, &enc_data); krb5_free_data(context, tmp); - if (ret) + if (ret) { + krb5_xfree(enc_data.ciphertext.data); return(ret); + } ret = encode_krb5_enc_data(&enc_data, &tmp); @@ -215,7 +219,6 @@ krb5_error_code pa_sam(krb5_context context, char banner[100], prompt[100], response[100]; krb5_data response_data; krb5_prompt kprompt; - krb5_encrypt_block eblock; krb5_data defsalt; krb5_sam_challenge *sam_challenge = 0; krb5_sam_response sam_response; @@ -281,13 +284,6 @@ krb5_error_code pa_sam(krb5_context context, as_key->length = 0; } - /* XXX the server uses this fixed enctype, so we will, too. */ - - if (!valid_enctype(ENCTYPE_DES_CBC_MD5)) - return(KRB5_PROG_ETYPE_NOSUPP); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - #if 0 if ((salt->length == -1) && (salt->data == NULL)) { if (ret = krb5_principal2salt(context, request->client, @@ -305,8 +301,11 @@ krb5_error_code pa_sam(krb5_context context, salt = NULL; #endif - ret = krb5_string_to_key(context, &eblock, as_key, - &response_data, salt); + /* XXX the server uses this fixed enctype, so we will, too. */ + + ret = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5, + &response_data, salt, as_key); + if (defsalt.length) krb5_xfree(defsalt.data); diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c index 7537ac990..86c5ccf72 100644 --- a/src/lib/krb5/krb/rd_cred.c +++ b/src/lib/krb5/krb/rd_cred.c @@ -19,7 +19,6 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc) krb5_cred_enc_part * pcredenc; { krb5_cred_enc_part * ppart; - krb5_encrypt_block eblock; krb5_error_code retval; krb5_data scratch; @@ -28,28 +27,9 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc) return ENOMEM; if (pkeyblock != NULL) { - if (!valid_enctype(pcred->enc_part.enctype)) { - free(scratch.data); - return KRB5_PROG_ETYPE_NOSUPP; - } - - /* put together an eblock for this decryption */ - krb5_use_enctype(context, &eblock, pcred->enc_part.enctype); - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, pkeyblock))) - goto cleanup; - - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) pcred->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void)krb5_finish_key(context, &eblock); - goto cleanup; - } - - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = krb5_c_decrypt(context, pkeyblock, + KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0, + &pcred->enc_part, &scratch))) goto cleanup; } else { memcpy(scratch.data, pcred->enc_part.ciphertext.data, scratch.length); diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c index c4e1ed0b6..f08975f22 100644 --- a/src/lib/krb5/krb/rd_priv.c +++ b/src/lib/krb5/krb/rd_priv.c @@ -66,8 +66,9 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, krb5_error_code retval; krb5_priv * privmsg; krb5_data scratch; - krb5_encrypt_block eblock; krb5_priv_enc_part * privmsg_enc_part; + size_t blocksize; + krb5_data ivdata; if (!krb5_is_krb_priv(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; @@ -76,43 +77,33 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, if ((retval = decode_krb5_priv(inbuf, &privmsg))) return retval; - if (!valid_enctype(privmsg->enc_part.enctype)) { - retval = KRB5_PROG_ETYPE_NOSUPP; - goto cleanup_privmsg; + if (i_vector) { + if ((retval = krb5_c_block_size(context, keyblock->enctype, + &blocksize))) + goto cleanup_privmsg; + + ivdata.length = blocksize; + ivdata.data = i_vector; } - - /* put together an eblock for this decryption */ - krb5_use_enctype(context, &eblock, privmsg->enc_part.enctype); + scratch.length = privmsg->enc_part.ciphertext.length; - if (!(scratch.data = malloc(scratch.length))) { retval = ENOMEM; goto cleanup_privmsg; } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, keyblock))) + if ((retval = krb5_c_decrypt(context, keyblock, + KRB5_KEYUSAGE_KRB_PRIV_ENCPART, + i_vector?&ivdata:0, + &privmsg->enc_part, &scratch))) goto cleanup_scratch; - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) privmsg->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, i_vector))) { - krb5_finish_key(context, &eblock); - goto cleanup_scratch; - } - /* if i_vector is set, put last block into the i_vector */ if (i_vector) memcpy(i_vector, privmsg->enc_part.ciphertext.data + - (privmsg->enc_part.ciphertext.length - - eblock.crypto_entry->block_length), - eblock.crypto_entry->block_length); - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_scratch; + (privmsg->enc_part.ciphertext.length - blocksize), + blocksize); /* now decode the decrypted stuff */ if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part))) diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c index d4d559d14..411a61ddb 100644 --- a/src/lib/krb5/krb/rd_rep.c +++ b/src/lib/krb5/krb/rd_rep.c @@ -47,7 +47,6 @@ krb5_rd_rep(context, auth_context, inbuf, repl) { krb5_error_code retval; krb5_ap_rep * reply; - krb5_encrypt_block eblock; krb5_data scratch; if (!krb5_is_ap_rep(inbuf)) @@ -60,35 +59,15 @@ krb5_rd_rep(context, auth_context, inbuf, repl) /* put together an eblock for this encryption */ - if (!valid_enctype(reply->enc_part.enctype)) { - krb5_free_ap_rep(context, reply); - return KRB5_PROG_ETYPE_NOSUPP; - } - krb5_use_enctype(context, &eblock, reply->enc_part.enctype); - scratch.length = reply->enc_part.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) { krb5_free_ap_rep(context, reply); return(ENOMEM); } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, - auth_context->keyblock))) { - goto errout; - } - - /* call the encryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) reply->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - goto errout; - } - - /* finished with the top-level encoding of the ap_rep */ - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = krb5_c_decrypt(context, auth_context->keyblock, + KRB5_KEYUSAGE_AP_REP_ENCPART, 0, + &reply->enc_part, &scratch))) goto clean_scratch; /* now decode the decrypted stuff */ diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index 0c62c19df..cdbdc81df 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -57,7 +57,8 @@ */ static krb5_error_code decrypt_authenticator - PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **)); + PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **, + int)); #define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew) @@ -119,8 +120,12 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab, return retval; } + /* XXX this is an evil hack. check_valid_flag is set iff the call + is not from inside the kdc. we can use this to determine which + key usage to use */ if ((retval = decrypt_authenticator(context, req, - &((*auth_context)->authentp)))) + &((*auth_context)->authentp), + check_valid_flag))) goto cleanup; if (!krb5_principal_compare(context, (*auth_context)->authentp->client, @@ -243,14 +248,66 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab, } } + /* check if the various etypes are permitted */ + + if ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_PERMIT_ALL) { + /* no etype check needed */; + } else if ((*auth_context)->permitted_etypes == NULL) { + /* check against the default set */ + if ((!krb5_is_permitted_enctype(context, + req->ticket->enc_part.enctype)) || + (!krb5_is_permitted_enctype(context, + req->ticket->enc_part2->session->enctype)) || + (((*auth_context)->authentp->subkey) && + !krb5_is_permitted_enctype(context, + (*auth_context)->authentp->subkey->enctype))) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + } else { + /* check against the set in the auth_context */ + int i; + + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + req->ticket->enc_part.enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + req->ticket->enc_part2->session->enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + + if ((*auth_context)->authentp->subkey) { + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + (*auth_context)->authentp->subkey->enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + } + } + (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number; if ((*auth_context)->authentp->subkey) { if ((retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey, &((*auth_context)->remote_subkey)))) goto cleanup; - } else + } else { (*auth_context)->remote_subkey = 0; + } + if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session, &((*auth_context)->keyblock)))) goto cleanup; @@ -322,52 +379,34 @@ krb5_rd_req_decoded_anyflag(context, auth_context, req, server, keytab, } static krb5_error_code -decrypt_authenticator(context, request, authpp) +decrypt_authenticator(context, request, authpp, is_ap_req) krb5_context context; const krb5_ap_req *request; krb5_authenticator **authpp; + int is_ap_req; { krb5_authenticator *local_auth; krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data scratch; krb5_keyblock *sesskey; sesskey = request->ticket->enc_part2->session; - if (!valid_enctype(sesskey->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, request->authenticator.enctype); - scratch.length = request->authenticator.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) return(ENOMEM); - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, sesskey))) { + if ((retval = krb5_c_decrypt(context, sesskey, + is_ap_req?KRB5_KEYUSAGE_AP_REQ_AUTH: + KRB5_KEYUSAGE_TGS_REQ_AUTH, 0, + &request->authenticator, &scratch))) { free(scratch.data); return(retval); } - /* call the encryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer)request->authenticator.ciphertext.data, - (krb5_pointer)scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - free(scratch.data); - return retval; - } #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - if ((retval = krb5_finish_key(context, &eblock))) { - clean_scratch(); - return retval; - } /* now decode the decrypted stuff */ if (!(retval = decode_krb5_authenticator(&scratch, &local_auth))) { *authpp = local_auth; diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c index 5f0fcd6ca..1c5aca21c 100644 --- a/src/lib/krb5/krb/rd_safe.c +++ b/src/lib/krb5/krb/rd_safe.c @@ -59,6 +59,7 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr, krb5_checksum our_cksum, *his_cksum; krb5_octet zero_octet = 0; krb5_data *scratch; + krb5_boolean valid; if (!krb5_is_krb_safe(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; @@ -122,14 +123,14 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr, message->checksum = his_cksum; - retval = krb5_verify_checksum(context, his_cksum->checksum_type, - his_cksum, scratch->data, scratch->length, - (krb5_pointer) keyblock->contents, - keyblock->length); + retval = krb5_c_verify_checksum(context, keyblock, + KRB5_KEYUSAGE_KRB_SAFE_CKSUM, + scratch, his_cksum, &valid); + (void) memset((char *)scratch->data, 0, scratch->length); krb5_free_data(context, scratch); - if (retval) { + if (!valid) { retval = KRB5KRB_AP_ERR_MODIFIED; goto cleanup; } diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c index b06ef2bfc..19de14e1a 100644 --- a/src/lib/krb5/krb/send_tgs.c +++ b/src/lib/krb5/krb/send_tgs.c @@ -55,21 +55,15 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf) krb5_checksum checksum; krb5_authenticator authent; krb5_ap_req request; - krb5_encrypt_block eblock; krb5_data * scratch; krb5_data * toutbuf; /* Generate checksum */ - checksum.length = krb5_checksum_size(context, context->kdc_req_sumtype); - if ((checksum.contents = (krb5_octet *) malloc(checksum.length)) == NULL) - return(ENOMEM); - - if ((retval = krb5_calculate_checksum(context, context->kdc_req_sumtype, - in_data->data, in_data->length, - (krb5_pointer) in_cred->keyblock.contents, - in_cred->keyblock.length, - &checksum))) { - free(checksum.contents); + if ((retval = krb5_c_make_checksum(context, context->kdc_req_sumtype, + &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, + in_data, &checksum))) { + free(checksum.contents); return(retval); } @@ -102,43 +96,11 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf) /* Cleanup scratch and scratch data */ goto cleanup_data; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype); - request.authenticator.enctype = in_cred->keyblock.enctype; - request.authenticator.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - request.authenticator.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_free_ticket(context, request.ticket); - retval = ENOMEM; - goto cleanup_scratch; - } - memset(scratch->data + scratch->length, 0, - request.authenticator.ciphertext.length - scratch->length); - - if (!(request.authenticator.ciphertext.data = - malloc(request.authenticator.ciphertext.length))) { - retval = ENOMEM; - goto cleanup_ticket; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, &(in_cred)->keyblock))) - goto cleanup; - /* call the encryption routine */ - if ((retval=krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer)request.authenticator.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup; + if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AUTH, + scratch, &request.authenticator))) + goto cleanup_ticket; retval = encode_krb5_ap_req(&request, &toutbuf); *outbuf = *toutbuf; @@ -185,6 +147,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs, krb5_timestamp time_now; krb5_pa_data **combined_padata; krb5_pa_data ap_req_padata; + size_t enclen; /* * in_creds MUST be a valid credential NOT just a partially filled in @@ -212,50 +175,21 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs, if (authorization_data) { /* need to encrypt it in the request */ - krb5_encrypt_block eblock; if ((retval = encode_krb5_authdata((const krb5_authdata**)authorization_data, &scratch))) return(retval); - krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype); - tgsreq.authorization_data.enctype = in_cred->keyblock.enctype; - tgsreq.authorization_data.kvno = 0; /* ticket session key has */ - /* no version */ - tgsreq.authorization_data.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - tgsreq.authorization_data.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - tgsreq.authorization_data.ciphertext.length - scratch->length); - if (!(tgsreq.authorization_data.ciphertext.data = - malloc(tgsreq.authorization_data.ciphertext.length))) { - krb5_free_data(context, scratch); - return ENOMEM; - } - if ((retval = krb5_process_key(context, &eblock, - &in_cred->keyblock))) { - krb5_free_data(context, scratch); - return retval; - } - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) tgsreq.authorization_data.ciphertext.data, - scratch->length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); + + if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY, + scratch, + &tgsreq.authorization_data))) { krb5_xfree(tgsreq.authorization_data.ciphertext.data); krb5_free_data(context, scratch); return retval; - } - krb5_free_data(context, scratch); - if ((retval = krb5_finish_key(context, &eblock))) { - krb5_xfree(tgsreq.authorization_data.ciphertext.data); - return retval; } + + krb5_free_data(context, scratch); } /* Get the encryption types list */ diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c index 5705b711f..42b9bfeb6 100644 --- a/src/lib/krb5/krb/ser_actx.c +++ b/src/lib/krb5/krb/ser_actx.c @@ -56,7 +56,6 @@ krb5_error_code krb5_ser_authdata_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_address_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_authenticator_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_checksum_init KRB5_PROTOTYPE((krb5_context)); -krb5_error_code krb5_ser_encrypt_block_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_keyblock_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_principal_init KRB5_PROTOTYPE((krb5_context)); @@ -95,17 +94,20 @@ krb5_auth_context_size(kcontext, arg, sizep) */ kret = EINVAL; if ((auth_context = (krb5_auth_context) arg)) { - required = sizeof(krb5_int32)*8; - kret = 0; + /* Calculate size required by i_vector - ptooey */ - if (auth_context->i_vector && auth_context->keyblock) - required += (size_t) - krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; + if (auth_context->i_vector && auth_context->keyblock) { + kret = krb5_c_block_size(kcontext, auth_context->keyblock->enctype, + &required); + } else { + required = 0; + } + + required += sizeof(krb5_int32)*8; /* Calculate size required by remote_addr, if appropriate */ - if (auth_context->remote_addr) { + if (!kret && auth_context->remote_addr) { kret = krb5_size_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer) auth_context->remote_addr, @@ -226,18 +228,25 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain) (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype, &bp, &remain); + kret = 0; + /* Now figure out the number of bytes for i_vector and write it */ - obuf = (!auth_context->i_vector) ? 0 : (krb5_int32) - krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; - (void) krb5_ser_pack_int32(obuf, &bp, &remain); + if (auth_context->i_vector) { + kret = krb5_c_block_size(kcontext, + auth_context->keyblock->enctype, + &obuf); + } else { + obuf = 0; + } + + if (!kret) + (void) krb5_ser_pack_int32(obuf, &bp, &remain); /* Now copy i_vector */ - if (auth_context->i_vector) + if (!kret && auth_context->i_vector) (void) krb5_ser_pack_bytes(auth_context->i_vector, (size_t) obuf, &bp, &remain); - kret = 0; /* Now handle remote_addr, if appropriate */ if (!kret && auth_context->remote_addr) { @@ -555,8 +564,6 @@ krb5_ser_auth_context_init(kcontext) kret = krb5_ser_authenticator_init(kcontext); if (!kret) kret = krb5_ser_checksum_init(kcontext); - if (!kret) - kret = krb5_ser_encrypt_block_init(kcontext); if (!kret) kret = krb5_ser_keyblock_init(kcontext); if (!kret) diff --git a/src/lib/krb5/krb/ser_eblk.c b/src/lib/krb5/krb/ser_eblk.c index 20b3da672..04e21faab 100644 --- a/src/lib/krb5/krb/ser_eblk.c +++ b/src/lib/krb5/krb/ser_eblk.c @@ -22,6 +22,8 @@ * */ +#if 0 /* i don't believe this is used anywhere --marc */ + /* * ser_eblk.c - Serialize a krb5_encblock structure. */ @@ -249,3 +251,5 @@ krb5_ser_encrypt_block_init(kcontext) { return(krb5_register_serializer(kcontext, &krb5_encrypt_block_ser_entry)); } + +#endif diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c index 6346aef23..b30638d4f 100644 --- a/src/lib/krb5/krb/str_conv.c +++ b/src/lib/krb5/krb/str_conv.c @@ -31,17 +31,13 @@ * * String decoding: * ---------------- - * krb5_string_to_enctype() - Convert string to krb5_enctype. * krb5_string_to_salttype() - Convert string to salttype (krb5_int32) - * krb5_string_to_cksumtype() - Convert string to krb5_cksumtype; * krb5_string_to_timestamp() - Convert string to krb5_timestamp. * krb5_string_to_deltat() - Convert string to krb5_deltat. * * String encoding: * ---------------- - * krb5_enctype_to_string() - Convert krb5_enctype to string. * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string. - * krb5_cksumtype_to_string() - Convert krb5_cksumtype to string. * krb5_timestamp_to_string() - Convert krb5_timestamp to string. * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string * krb5_deltat_to_string() - Convert krb5_deltat to string. @@ -52,24 +48,12 @@ /* * Local data structures. */ -struct enctype_lookup_entry { - krb5_enctype ktt_enctype; /* Keytype */ - const char * ktt_specifier; /* How to recognize it */ - const char * ktt_output; /* How to spit it out */ -}; - struct salttype_lookup_entry { krb5_int32 stt_enctype; /* Salt type */ const char * stt_specifier; /* How to recognize it */ const char * stt_output; /* How to spit it out */ }; -struct cksumtype_lookup_entry { - krb5_cksumtype cst_cksumtype; /* Checksum type */ - const char * cst_specifier; /* How to recognize it */ - const char * cst_output; /* How to spit it out */ -}; - struct deltat_match_entry { const char * dt_scan_format; /* sscanf format */ int dt_nmatch; /* Number to match */ @@ -83,21 +67,6 @@ struct deltat_match_entry { * Local strings */ -/* Keytype strings */ -static const char enctype_des_in[] = "des"; -static const char enctype_null_in[] = "null"; -static const char enctype_descbccrc_in[] = "des-cbc-crc"; -static const char enctype_descbcmd4_in[] = "des-cbc-md4"; -static const char enctype_descbcmd5_in[] = "des-cbc-md5"; -static const char enctype_des3cbcsha_in[] = "des3-cbc-sha"; -static const char enctype_descbcraw_in[] = "des-cbc-raw"; -static const char enctype_null_out[] = "Null"; -static const char enctype_descbccrc_out[] = "DES cbc mode with CRC-32"; -static const char enctype_descbcmd4_out[] = "DES cbc mode with RSA-MD4"; -static const char enctype_descbcmd5_out[] = "DES cbc mode with RSA-MD5"; -static const char enctype_des3cbcsha_out[] = "DES-3 cbc mode with NIST-SHA"; -static const char enctype_descbcraw_out[] = "DES cbc mode raw"; - /* Salttype strings */ static const char stype_v5_in[] = "normal"; static const char stype_v4_in[] = "v4"; @@ -112,24 +81,6 @@ static const char stype_olrealm_out[] = "Version 5 - Realm Only"; static const char stype_special_out[] = "Special"; static const char stype_afs3_out[] = "AFS version 3"; -/* Checksum type strings */ -static const char cstype_crc32_in[] = "crc32"; -static const char cstype_md4_in[] = "md4"; -static const char cstype_md4des_in[] = "md4-des"; -static const char cstype_descbc_in[] = "des-cbc"; -static const char cstype_md5_in[] = "md5"; -static const char cstype_md5des_in[] = "md5-des"; -static const char cstype_sha_in[] = "sha"; -static const char cstype_hmacsha_in[] = "hmac-sha"; -static const char cstype_crc32_out[] = "CRC-32"; -static const char cstype_md4_out[] = "RSA-MD4"; -static const char cstype_md4des_out[] = "RSA-MD4 with DES cbc mode"; -static const char cstype_descbc_out[] = "DES cbc mode"; -static const char cstype_md5_out[] = "RSA-MD5"; -static const char cstype_md5des_out[] = "RSA-MD5 with DES cbc mode"; -static const char cstype_sha_out[] = "NIST-SHA"; -static const char cstype_hmacsha_out[] = "HMAC-SHA"; - /* Absolute time strings */ static const char atime_full_digits[] = "%y%m%d%H%M%S"; static const char atime_full_digits_d[] = "%y.%m.%d.%H.%M.%S"; @@ -184,20 +135,6 @@ static const char dt_output_hms[] = "%d:%02d:%02d"; * Lookup tables. */ -static const struct enctype_lookup_entry enctype_table[] = { -/* krb5_enctype input specifier output string */ -/*------------- ----------------------- ------------------------*/ -{ ENCTYPE_NULL, enctype_null_in, enctype_null_out }, -{ ENCTYPE_DES_CBC_MD5, enctype_des_in, enctype_descbcmd5_out }, -{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in, enctype_descbccrc_out }, -{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in, enctype_descbcmd4_out }, -{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in, enctype_descbcmd5_out }, -{ ENCTYPE_DES3_CBC_SHA, enctype_des3cbcsha_in, enctype_des3cbcsha_out }, -{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in, enctype_descbcraw_out } -}; -static const int enctype_table_nents = sizeof(enctype_table)/ - sizeof(enctype_table[0]); - static const struct salttype_lookup_entry salttype_table[] = { /* salt type input specifier output string */ /*----------------------------- ----------------------- ------------------*/ @@ -211,21 +148,6 @@ static const struct salttype_lookup_entry salttype_table[] = { static const int salttype_table_nents = sizeof(salttype_table)/ sizeof(salttype_table[0]); -static const struct cksumtype_lookup_entry cksumtype_table[] = { -/* krb5_cksumtype input specifier output string */ -/*----------------------- --------------------- ------------------------*/ -{ CKSUMTYPE_CRC32, cstype_crc32_in, cstype_crc32_out }, -{ CKSUMTYPE_RSA_MD4, cstype_md4_in, cstype_md4_out }, -{ CKSUMTYPE_RSA_MD4_DES, cstype_md4des_in, cstype_md4des_out }, -{ CKSUMTYPE_DESCBC, cstype_descbc_in, cstype_descbc_out }, -{ CKSUMTYPE_RSA_MD5, cstype_md5_in, cstype_md5_out }, -{ CKSUMTYPE_RSA_MD5_DES, cstype_md5des_in, cstype_md5des_out }, -{ CKSUMTYPE_NIST_SHA, cstype_sha_in, cstype_sha_out }, -{ CKSUMTYPE_HMAC_SHA, cstype_hmacsha_in, cstype_hmacsha_out } -}; -static const int cksumtype_table_nents = sizeof(cksumtype_table)/ - sizeof(cksumtype_table[0]); - static const char * const atime_format_table[] = { atime_full_digits_Y, /* yyyymmddhhmmss */ atime_full_digits_Yd, /* yyyy.mm.dd.hh.mm.ss */ @@ -403,30 +325,6 @@ strptime(buf, format, tm) } #endif /* HAVE_STRPTIME */ -/* - * String to internal datatype routines. - * - * These routines return 0 for success, EINVAL for invalid entry. - */ -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_string_to_enctype(string, enctypep) - char FAR * string; - krb5_enctype FAR * enctypep; -{ - int i; - int found; - - found = 0; - for (i=0; i strlen(out)) - strcpy(buffer, out); - else - out = (char *) NULL; - return((out) ? 0 : ENOMEM); - } - else - return(EINVAL); -} - KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_salttype_to_string(salttype, buffer, buflen) krb5_int32 salttype; diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c index bb8ea349b..85a846503 100644 --- a/src/lib/krb5/krb/vfy_increds.c +++ b/src/lib/krb5/krb/vfy_increds.c @@ -68,12 +68,7 @@ krb5_verify_init_creds(krb5_context context, krb5_creds in_creds, *out_creds; krb5_auth_context authcon; krb5_data ap_req; - int keytab_key_exists, rd_req_succeeds, nofail; - keytab_key_exists = 0; - rd_req_succeeds = 0; - nofail = 0; - /* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN */ server = NULL; @@ -103,11 +98,31 @@ krb5_verify_init_creds(krb5_context context, goto cleanup; } - if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) - goto cleanup; + if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) { + /* this means there is no keying material. This is ok, as long as + it is not prohibited by the configuration */ + + krb5_error_code ret2; + int nofail; + + if (options && + (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) { + if (options->ap_req_nofail) + goto cleanup; + } else if ((ret2 = krb5_appdefault_boolean(context, + &creds->client->realm, + "verify_ap_req_nofail", + &nofail)) + == 0) { + if (nofail) + goto cleanup; + } + + ret = 0; + goto cleanup; + } krb5_kt_free_entry(context, &kte); - keytab_key_exists = 1; /* If the creds are for the server principal, we're set, just do a mk_req. Otherwise, do a get_credentials first. */ @@ -166,61 +181,37 @@ krb5_verify_init_creds(krb5_context context, NULL, NULL)) goto cleanup; - rd_req_succeeds = 1; - -cleanup: - /* I could test the error case first, but then there would be a - chance that the verification would succeed when there was - actually a significant failure (some transient condition could - make rd_req fail, and this would not be a problem if nofail was - not set */ - - if (!keytab_key_exists) { - krb5_error_code ret2; - - if (options && - (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) - nofail = options->ap_req_nofail; - else if ((ret2 = krb5_appdefault_boolean(context, &creds->client->realm, - "verify_ap_req_nofail", - &nofail)) - == 0) - ; - else - nofail = 0; - } - - if ((keytab_key_exists && rd_req_succeeds) || - (!keytab_key_exists && !nofail)) { - ret = 0; + /* if we get this far, then the verification succeeded. We can + still fail if the library stuff here fails, but that's it */ - if (ccache_arg && ccache) { - if (*ccache_arg == NULL) { - krb5_ccache retcc; + if (ccache_arg && ccache) { + if (*ccache_arg == NULL) { + krb5_ccache retcc; - retcc = NULL; + retcc = NULL; - if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) || - (ret = krb5_cc_initialize(context, retcc, creds->client)) || - (ret = krb5_cc_copy_creds_except(context, ccache, retcc, - creds->server))) { + if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) || + (ret = krb5_cc_initialize(context, retcc, creds->client)) || + (ret = krb5_cc_copy_creds_except(context, ccache, retcc, + creds->server))) { if (retcc) - krb5_cc_destroy(context, retcc); - } else { + krb5_cc_destroy(context, retcc); + } else { *ccache_arg = retcc; - } - } else { - /* if this returns an error, then that's the return - from this function */ - ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg, - server); - } - } + } + } else { + ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg, + server); + } } - if (!server_arg) + /* if any of the above paths returned an errors, then ret is set + accordingly. either that, or it's zero, which is fine, too */ + +cleanup: + if (!server_arg && server) krb5_free_principal(context, server); - if (!keytab_arg) + if (!keytab_arg && keytab) krb5_kt_close(context, keytab); if (ccache) krb5_cc_destroy(context, ccache); @@ -233,6 +224,3 @@ cleanup: return(ret); } - - - diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 0ee4a7192..84f0dec67 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,16 @@ +1998-10-27 Marc Horowitz + + * c_ustime.c, localaddr.c: moved here from lib/crypto + + * ktdefname.c (krb5_kt_default_name): there is code in the tree + (notably, the admin server code) which uses globals to set the + keytab which will be used by gssapi. this is gross, and we need a + better answer. However, even that didn't work if there was an env + var or krb5.conf variable, since those override krb5_defkeyname. + Add a new global, krb5_overridekeyname, which really does override + all the other keytab locators. While I'm at it, make the buffer + overflow checks sane. + Fri Sep 25 22:32:16 1998 Theodore Y. Ts'o * ccdefname.c: We shouldn't try to use the CCache API on Unix diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in index 9e132dbc8..56edfac36 100644 --- a/src/lib/krb5/os/Makefile.in +++ b/src/lib/krb5/os/Makefile.in @@ -12,6 +12,7 @@ PROG_RPATH=$(KRB5_LIBDIR) STLIBOBJS= \ an_to_ln.o \ + c_ustime.o \ def_realm.o \ DNR.o \ ccdefname.o \ @@ -54,6 +55,7 @@ STLIBOBJS= \ OBJS= \ an_to_ln.$(OBJEXT) \ + c_ustime.$(OBJEXT) \ def_realm.$(OBJEXT) \ DNR.$(OBJEXT) \ ccdefname.$(OBJEXT) \ @@ -96,6 +98,7 @@ OBJS= \ SRCS= \ $(srcdir)/an_to_ln.c \ + $(srcdir)/c_ustime.c \ $(srcdir)/def_realm.c \ $(srcdir)/DNR.c \ $(srcdir)/ccdefname.c \ diff --git a/src/lib/crypto/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c similarity index 99% rename from src/lib/crypto/os/c_ustime.c rename to src/lib/krb5/os/c_ustime.c index e790acc95..350c1aa5c 100644 --- a/src/lib/crypto/os/c_ustime.c +++ b/src/lib/krb5/os/c_ustime.c @@ -27,7 +27,7 @@ #define NEED_SOCKETS #include "k5-int.h" -#ifdef macintosh +#ifdef _MACINTOSH /* We're a Macintosh -- do Mac time things. */ diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c index c645635ab..0493244f6 100644 --- a/src/lib/krb5/os/ktdefname.c +++ b/src/lib/krb5/os/ktdefname.c @@ -30,6 +30,9 @@ extern char *krb5_defkeyname; +/* this is a an exceedinly gross thing. */ +char *krb5_overridekeyname = NULL; + KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_default_name(context, name, namesize) krb5_context context; @@ -40,19 +43,24 @@ krb5_kt_default_name(context, name, namesize) krb5_error_code code; char *retval; - if ((context->profile_secure == FALSE) && + if (krb5_overridekeyname) { + if ((size_t) namesize < (strlen(krb5_overridekeyname)+1)) + return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, krb5_overridekeyname); + } else if ((context->profile_secure == FALSE) && (cp = getenv("KRB5_KTNAME"))) { - strncpy(name, cp, namesize); - if (strlen(cp) >= (size_t) namesize) + if ((size_t) namesize < (strlen(cp)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, cp); } else if (((code = profile_get_string(context->profile, "libdefaults", "default_keytab_name", NULL, NULL, &retval)) == 0) && retval) { - strncpy(name, retval, namesize); - if ((size_t) namesize < strlen(retval)) + if ((size_t) namesize < (strlen(retval)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, retval); + free(retval); } else { #if defined (_MSDOS) || defined(_WIN32) { @@ -66,9 +74,9 @@ krb5_kt_default_name(context, name, namesize) sprintf(name, krb5_defkeyname, defname); } #else - strncpy(name, krb5_defkeyname, namesize); - if ((size_t) namesize < strlen(krb5_defkeyname)) + if ((size_t) namesize < (strlen(krb5_defkeyname)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, krb5_defkeyname); #endif } return 0; diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index cb204b597..9f33e5d98 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -20,16 +20,329 @@ * this software for any purpose. It is provided "as is" without express * or implied warranty. * - * Just a stub that calls krb5_crypto_os_localaddr(). * + * Return the protocol addresses supported by this host. + * + * XNS support is untested, but "Should just work". */ +#define NEED_SOCKETS #include "k5-int.h" +#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32) + +/* needed for solaris, harmless elsewhere... */ +#define BSD_COMP +#include +#include +#include + +/* + * The SIOCGIF* ioctls require a socket. + * It doesn't matter *what* kind of socket they use, but it has to be + * a socket. + * + * Of course, you can't just ask the kernel for a socket of arbitrary + * type; you have to ask for one with a valid type. + * + */ +#ifdef HAVE_NETINET_IN_H + +#include + +#ifndef USE_AF +#define USE_AF AF_INET +#define USE_TYPE SOCK_DGRAM +#define USE_PROTO 0 +#endif + +#endif + +#ifdef KRB5_USE_NS + +#include + +#ifndef USE_AF +#define USE_AF AF_NS +#define USE_TYPE SOCK_DGRAM +#define USE_PROTO 0 /* guess */ +#endif + +#endif +/* + * Add more address families here. + */ + +/* + * BSD 4.4 defines the size of an ifreq to be + * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len + * However, under earlier systems, sa_len isn't present, so the size is + * just sizeof(struct ifreq) + */ +#ifdef HAVE_SA_LEN +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif +#define ifreq_size(i) max(sizeof(struct ifreq),\ + sizeof((i).ifr_name)+(i).ifr_addr.sa_len) +#else +#define ifreq_size(i) sizeof(struct ifreq) +#endif /* HAVE_SA_LEN*/ + + + +extern int errno; + +/* + * Return all the protocol addresses of this host. + * + * We could kludge up something to return all addresses, assuming that + * they're valid kerberos protocol addresses, but we wouldn't know the + * real size of the sockaddr or know which part of it was actually the + * host part. + * + * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's. + */ + KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_os_localaddr(context, addr) krb5_context context; krb5_address FAR * FAR * FAR *addr; { - return krb5_crypto_os_localaddr(addr); + struct ifreq *ifr, ifreq; + struct ifconf ifc; + int s, code, n, i; + char buf[1024]; + krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ]; + int n_found; + int mem_err = 0; + + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + s = socket (USE_AF, USE_TYPE, USE_PROTO); + if (s < 0) + return errno; + + code = ioctl (s, SIOCGIFCONF, (char *)&ifc); + if (code < 0) { + int retval = errno; + closesocket (s); + return retval; + } + n = ifc.ifc_len; + +n_found = 0; + for (i = 0; i < n; i+= ifreq_size(*ifr) ) { + krb5_address *address; + ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); + + strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); + if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) + continue; + +#ifdef IFF_LOOPBACK + if (ifreq.ifr_flags & IFF_LOOPBACK) + continue; +#endif + + if (!(ifreq.ifr_flags & IFF_UP)) + /* interface is down; skip */ + continue; + + /* ifr->ifr_addr has what we want! */ + switch (ifr->ifr_addr.sa_family) { +#ifdef HAVE_NETINET_IN_H + case AF_INET: + { + struct sockaddr_in *in = + (struct sockaddr_in *)&ifr->ifr_addr; + + address = (krb5_address *) + malloc (sizeof(krb5_address)); + if (address) { + address->magic = KV5M_ADDRESS; + address->addrtype = ADDRTYPE_INET; + address->length = sizeof(struct in_addr); + address->contents = (unsigned char *)malloc(address->length); + if (!address->contents) { + krb5_xfree(address); + address = 0; + mem_err++; + } else { + memcpy ((char *)address->contents, + (char *)&in->sin_addr, + address->length); + break; + } + } else mem_err++; + } +#endif +#ifdef KRB5_USE_NS + case AF_XNS: + { + struct sockaddr_ns *ns = + (struct sockaddr_ns *)&ifr->ifr_addr; + address = (krb5_address *) + malloc (sizeof (krb5_address) + sizeof (struct ns_addr)); + if (address) { + address->magic = KV5M_ADDRESS; + address->addrtype = ADDRTYPE_XNS; + + /* XXX should we perhaps use ns_host instead? */ + + address->length = sizeof(struct ns_addr); + address->contents = (unsigned char *)malloc(address->length); + if (!address->contents) { + krb5_xfree(address); + address = 0; + mem_err++; + } else { + memcpy ((char *)address->contents, + (char *)&ns->sns_addr, + address->length); + break; + } + } else mem_err++; + break; + } +#endif + /* + * Add more address families here.. + */ + default: + continue; + } + if (address) + addr_temp[n_found++] = address; + address = 0; + } + closesocket(s); + + *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1)); + if (*addr == 0) + mem_err++; + + if (mem_err) { + for (i=0; imagic = KV5M_ADDRESS; + (*addr)[0]->addrtype = hostrec->h_addrtype; + (*addr)[0]->length = hostrec->h_length; + (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length); + if (!(*addr)[0]->contents) { + free((*addr)[0]); + free(*addr); + return ENOMEM; + } else { + memcpy ((*addr)[0]->contents, + hostrec->h_addr, + (*addr)[0]->length); + } + /* FIXME, deal with the case where gethostent returns multiple addrs */ + + return(0); } +#endif diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index c0ccf7e38..d8187ac3a 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -46,7 +46,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) const char *realm_kdc_names[4]; char **masterlist, **hostlist, *host, *port, *cp; krb5_error_code code; - int i, j, out, count; + int i, j, out, count, ismaster; struct sockaddr *addr_p; struct sockaddr_in *sin_p; struct hostent *hp; @@ -103,6 +103,9 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) } if (master_index) { + *master_index = 0; + *nmasters = 0; + realm_kdc_names[0] = "realms"; realm_kdc_names[1] = host; realm_kdc_names[2] = "admin_server"; @@ -113,10 +116,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) krb5_xfree(host); - if (code) { - *master_index = 0; - *nmasters = 0; - } else { + if (code == 0) { for (i=0; masterlist[i]; i++) { host = masterlist[i]; @@ -138,11 +138,10 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) krb5_xfree(host); } - /* at this point, is master is non-NULL, then either the master kdc + /* at this point, if master is non-NULL, then either the master kdc is required, and there is one, or the master kdc is not required, and there may or may not be one. */ - #ifdef HAVE_NETINET_IN_H if (sec_udpport) count = count * 2; @@ -175,10 +174,15 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) continue; } - if (masterlist) - for (j=0; masterlist[j]; j++) - if (strcasecmp(hostlist[i], masterlist[j]) == 0) + ismaster = 0; + if (masterlist) { + for (j=0; masterlist[j]; j++) { + if (strcasecmp(hostlist[i], masterlist[j]) == 0) { *master_index = out; + ismaster = 1; + } + } + } switch (hp->h_addrtype) { @@ -211,7 +215,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) default: break; } - if (masterlist) + if (ismaster) *nmasters = out - *master_index; /* Free the hostlist entry we are looping over. */ @@ -219,6 +223,11 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) hostlist[i] = 0; } + if (masterlist) { + for (i=0; masterlist[i]; i++) + free(masterlist[i]); + free(masterlist); + } free ((char *)hostlist); diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog index 7db853923..50ec692cb 100644 --- a/src/lib/rpc/ChangeLog +++ b/src/lib/rpc/ChangeLog @@ -1,3 +1,12 @@ +1998-10-27 Marc Horowitz + + * svc_auth_gssapi.c, auth_gssapi.h: fix the set_name prototype, + add a new unset_names function + +Sun Jul 26 18:13:39 1998 Sam Hartman + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:07:38 1998 Tom Yu * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/rpc/Makefile.in b/src/lib/rpc/Makefile.in index 1340d3ffd..a03ef026f 100644 --- a/src/lib/rpc/Makefile.in +++ b/src/lib/rpc/Makefile.in @@ -6,7 +6,7 @@ CFLAGS = $(CCOPTS) $(DEFS) -DGSSAPI_KRB5 -DDEBUG_GSSAPI=0 ##DOSLIBNAME=libgssrpc.lib LIB=gssrpc -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=OBJS.ST SHLIB_EXPDEPS= \ diff --git a/src/lib/rpc/auth_gssapi.h b/src/lib/rpc/auth_gssapi.h index 218b5cb9d..2cdd20f2f 100644 --- a/src/lib/rpc/auth_gssapi.h +++ b/src/lib/rpc/auth_gssapi.h @@ -111,8 +111,10 @@ PROTOTYPE((CLIENT *clnt, char *service_name)); void auth_gssapi_display_status PROTOTYPE((char *msg, OM_uint32 major, OM_uint32 minor)); -bool_t _svcauth_gssapi_set_name -PROTOTYPE((char *name, gss_OID name_type)); +bool_t _svcauth_gssapi_set_names +PROTOTYPE((auth_gssapi_name *names, int num)); +void _svcauth_gssapi_unset_names +PROTOTYPE(()); void _svcauth_set_log_badauth_func PROTOTYPE((auth_gssapi_log_badauth_func func, diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c index 2a3233ee9..df59859f0 100644 --- a/src/lib/rpc/svc_auth_gssapi.c +++ b/src/lib/rpc/svc_auth_gssapi.c @@ -887,7 +887,7 @@ done: } /* - * Function: _svcauth_gssapi_set_name + * Function: _svcauth_gssapi_set_names * * Purpose: Sets the list of service names for which incoming * authentication requests should be honored. @@ -916,6 +916,13 @@ bool_t _svcauth_gssapi_set_names(names, num) if (server_name_list == NULL) goto fail; + for (i = 0; i < num; i++) { + server_name_list[i] = 0; + server_creds_list[i] = 0; + } + + server_creds_count = num; + for (i = 0; i < num; i++) { in_buf.value = names[i].name; in_buf.length = strlen(in_buf.value) + 1; @@ -939,19 +946,41 @@ bool_t _svcauth_gssapi_set_names(names, num) } } - server_creds_count = num; - return TRUE; fail: - /* memory leak: not releasing names/creds already acquired */ - if (server_creds_list) + _svcauth_gssapi_unset_names(); + + return FALSE; +} + +/* Function: _svcauth_gssapi_unset_names + * + * Purpose: releases the names and credentials allocated by + * _svcauth_gssapi_set_names + */ + +void _svcauth_gssapi_unset_names() +{ + int i; + OM_uint32 minor_stat; + + if (server_creds_list) { + for (i = 0; i < server_creds_count; i++) + if (server_creds_list[i]) + gss_release_cred(&minor_stat, &server_creds_list[i]); free(server_creds_list); - if (server_name_list) + } + + if (server_name_list) { + for (i = 0; i < server_creds_count; i++) + if (server_name_list[i]) + gss_release_name(&minor_stat, &server_name_list[i]); free(server_name_list); - return FALSE; + } } + /* * Function: _svcauth_gssapi_set_log_badauth_func * diff --git a/src/mac/TestTrack/ChangeLog b/src/mac/TestTrack/ChangeLog deleted file mode 100644 index ac6e96426..000000000 --- a/src/mac/TestTrack/ChangeLog +++ /dev/null @@ -1,24 +0,0 @@ -Tue Jul 7 17:00:00 1998 Miro Jurisic - - * initTestTrackGlue.c renamed to ShlibTestTrack.c. removed CFM initialization code from - there, since we are calling ShlibTestTrack from CFM initializers in *.CFM.c. Also updated - to fix the bug where we were closing application's resource fork (oops). - -Fri Dec 20 12:35:32 1996 Marshall Vale - - * GSSforSAP.r: Moved resources for the timebomb out to Rez - format for easier CVSing - * macSAPglue.c (__initializeSAPglue): Added new conditions to the - timebomb code so that it can identify individual applications - and not just fail globally. - -Tue Dec 17 13:53:36 1996 Theodore Y. Ts'o - - * GSSforSAP.r: Fix expire time in the text resource to be June 1, - 1997. - -Fri Dec 13 14:58:20 1996 Theodore Y. Ts'o - - * macSAPglue.c (__initializeSAPglue): Change the timebomb date to - be June 1, 1997. - diff --git a/src/mac/TestTrack/MITAthenaLib b/src/mac/TestTrack/MITAthenaLib deleted file mode 100644 index d7ae71ad3..000000000 --- a/src/mac/TestTrack/MITAthenaLib +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :$%e*9%&dD'9ZB8aTBJ"cD'aL2j!%!*!%b$d!!!*A#-K+EhNKF'9QCQdf1'X!!!! "XG%Hb!#3$3-!!J#3$NXd!!",0!!!5c3!!!#8!!%#!*!%"3#3"LFJ!!!R)!!!"GJ !!%[)!J%#!*!%$J#3$J9)!!"4S!3"!J"0B@PZ!#9"09G[FQaN!%a[B@4PFJ#3"#T 46PErp#m0F!%[!$!mUQi[!#*YrC3J@8k3!#TZrr!Y32rdF!%[!$!mU'i[!#*YrC3 J@8k3!#TZrr#`V[rdCJB`2!)!B!3`2!3!6Pj1GBp1G@e8EfpXBQpi9(*KF(-!!#T 46PErq$!Z!!S#J!!!#!"Q"(!!B!*`!8jH6R3!")Y(CA48FQ&`9(P`C3!!+P&19[r d51FB"$BZ!!S[!f(rN!6%'!!-"!!"CK*Krj!%@!*$"rqf3'd%0MbSRbm%,`-LEIf 8)&P1N!!UE[r`,8$rp(!",`!`2+LI,`!LEIf8)&P1N!!UE[r`X+lrp&E!4!"*`%c I!"K1ANjd!!5+9(*KF%9iDA0dF`!!!#T46PErj#m05'lrk(!",`!LEIcB)&P1N!! UE[rJ5'lrj#mZ!!`[,J!)-#lrpLm!)Qhmc#"C6T!!+Qlri%M!C``JEJ!)3P!JEJ! -3T!!6Pj1G!!)MdGPG&0jFh4PE8C[E'4PFJ!!+P&19[rd51F30#CZ!!JNEJ!-GJ! `2+'Y,`"Krj!%#%S!Caa)E[rd,caQEfaN)QhpN!!J@8k3!#TZrr")`'B#GJ&+!fB -,`S[#f(rN!4@B#J[#Lm,F!![!#mmBh4bE$!mJ!![!#*YrB`J@8k3!#TZrr")`'F %3P0#NNcI$!K1ANjd!!L24f9d3e"KEQ9X4QpXC'9b!!!U88j@rRa)jam%,Li!##` Z!!`k,J!5+#i!&%+ZriT"l[jq,8MrN!!p4Iq8,86rVMem!!(rQQ"F[UlrRQC1[+l rSQC)F!%[!%KZrRi["#m&)QhpV#"C6T!!+QlqH$B!F!%[!#mmC'jbF#*YrA`J@8k 3!#TZrRK+J'B3,`-LEIeB)&P1N!!UE[jiB!3`!f!H8QlrQLe%rkj)E[pq)Qhmr#" C6T!!+QlqH%M!Cj!!F2p-h`$i6Pj1G!!3Ne0PBA*MD%C[E'4PFNC[FN418P!!!#T 46PErm#m$5'lrmNKZrrCKrrrrrT3[,[rb-#lrpLm!,cakG'0`,caMC'9fBIq3"!` f!!a$rrpR"$!$B'j)E[rb5'lrpQ(rrrrpr#mZrr)`,[rf,`![2'edBh![2'0NCAC KrrrrrYBf!!a$rrpR"$!$B$K)E[rb5'lrpQ(rrrrq+#mZrr)`,[rf,`![2'edBh! [2'0NCACKrrrrrU!f!!a$rrpR"$!$B!*`rbBI6Pj1GBP2F'9Z6h9b8NB!!#T46PE rq%MR%!4+VISSC`C`!'!!!04Krj!%,$B!F!%[!#mmC'jbF#*YrA`J@8k3!#TZrr3 V32SN5Uhk*'B3)QhpL#"C6T!!+Qlrp'!!!*`[,ISN)Qhp##"C6T!!+Qlrp!a$rrp R$Lm$)Qhp@#"C6T!!+Qlrp#mYqL3LEIc8)&P1N!!UE[rd,bhk*#*YrE`J@8k3!#T Zrr3JEISN+e$k+#mZ!!K)H!!"5(J$i5mYqLJLEIcX)&P1N!!UE[rd0J!`!dM!6qm !%'FN,bhk*#*Yr0`J@8k3!#TZrr3[,ISN)QhpZ#"C6T!!+Qlrp%+YqLJ`!bBI6Pj 1G!!%M%p`C@j5CA0[E(CPFJ!!!#T46PErq#m05Uhk+'B%F14J+LmZ!"3[,J!3,bi !$#mZ!!K)H!!$,c`!!2rK,bhk+#*Yr1`J@8k3!#TZrr41ANjd!"#*8h4b9'p"C'4 b!!!U88j@rrK)EIT)5'hk6#mZ!!KKr`!!!SK+J'F%F!"J-N(YqNJV52T!3Uhk4%( YqN`V52SX3Uhk-(!#+d$k0(!%+d$k1%(YqN!V52Sm3Hhk,#!)6Pj1G!!%M@GPG'K [Fh4LH@jKE@8!!#T46PErp#m05'hl6%KYr[`LEIcS)&P1N!!UE[r`5-!Y32rd)#l rp%jH6R@,Eh"PEPpNFQPfCA)!!#T46PErq#m05Uhl8'F1)Qhl8#"C6T!!+Qlrp'! #F!"1ANjeMh9cCA*IB@*[FR4IC'PcF!!!+P&19[ri51F3*#4Z!!Kf!!a5!!&R"M! 55-"J('(rN!5`*J"R"#!$B!iLEIe`)&P1N!!UE[rdB0K-h`3)6Pj1G!!%L(GKDA4 ICQpb!!!!+P&19[ri51F3"%TYqdaQ%Q(rN!3f*J"+JfF')!0J!!#`5(J!CN+R5'h la#*YrM3J@8k3!#TZrr3lEIY-qp`lI!!QqpiVEJ!)qq!EI!!Hqq4#,I[P'hcr`2[ Q5'hla#*Yr@`J@8k3!#TZrr4)EI[8BIq3"%3Q!%Ki!'C#TdKYqm3LEIid)&P1N!! UE[rd1fhl62[F1h`!+[[H+fi!#2[J5'hla#*YrC`J@8k3!#TZrr4+EI[8CK![,I[ N)QhqQ#"C6T!!+Qlrp%U$CJBf,I[85--J!bBI6Pj1G!!%N!"dBh"IBfa[Ff9IFh4 bC@&Y!!!!+P&19[ri51F3"%TYqdaQ%'(rrrrq5LB!5S0R"(!!B&C)H!"Q3UG)EIY H)Qhq0#"C6T!!+Qlrp$YYqdclGMYm!#MlH#YZ!!MlHNKYqeiLEIeX)&P1N!!UE[r d5'hlEQ(rrrrqDLB!5S0R"(!!B!T+EIZD9X"%!%R!*Kp1ANjd!!5,G'0`Af0KER* PB@3!!#T46PErq%MR%$3QEJ!-5Uhl9'BN5'hr!L*Yr[JJ@8k3!#TZrr4)`#B!5S0 R"L!$B!!!RR!"+d$l9(!3,`")H!2!,bhqk#*Yr8JJ@8k3!#TZrr3N3$Ym!!(lA%K Yqe`[#LmYrZ`[,J!))Qhqp#"C6T!!+Qlrp#"YrZ`-N!$rrkAqCK")EIYFBIrrrrf i)'hql##!,`SLEIdS)&P1N!!UE[rd)'hql%U3!'F))'hql#!3B#)JEIlX)Qi!%#+ S!33J#fF3)%XLEIlX3qN!"#!)%0PQr(!!60m-#%jH6R3!$)pZFepbCA0[E(CPAfj KE@8!!#T46PErq#"Z!!JLEJ!--UJ!!NjH6R3!#)abCA0[E(CPAh"bEf-!!!!U88j @rrK)j`!N$'i!!3!1CKJNEJ!3,bS!##mZ!"!LDJ!%)&P1N!!UE[rd*&p1ANjd!"# +G@4`Afj[G'PQH3!!!#T46PEr[%MR%$3QEJ!)GJ"+EIY-CK*Krrrrr'BQ!%U$C`B J!f!!!-4)H!!k3UG)E[qq)Qhq0#"C6T!!+QlrZ%Ki!!`LEIkF)&P1N!!UE[qi*%! J#QB'F!aJ!!#52A`!&2rB2@hl62r@,@i!%2rH,@i!&2rL5Uhl@'BFF"![!%Ki2X! [,IlN)Qhp5#"C6T!!+QlrZ#Y!qeJYEIYBrqBp8rrU,8Vrl%KZrliLEIeX)&P1N!! UE[qi5QlrcQF@,`SLEIkB)&P1N!!UE[qi-#lrcNM!B"`NV[rD*@i!(!!%*@i!$!! ))'i!'##+0UlrkL!$60m-#%jH6R3!')aeC("IFQ9RDA0dCA)!!!!U88j@rkJ[$8K i!$T#TdKZrliLEIid)&P1N!!UE[qN2@i!'[qb,@i!&2qd3QlrZ#eZ!!MrUMem!"I rf$eYqdcreL"ZrkSY82rD,@i!$2rJ2@i!%[rN(A`!!IrU3HlrXLe)rqC)E[qq)Qh pE#"C6T!!+QlrT%KZrmjKrrrrqfiY32qZ)#lrVNjH6R3!&)jeC("IFf9ZC&pNCh* KE3!!!#T46PEr[%MR'#3S,J!B5(J!1N+R5'lr[L*YrM3J@8k3!#TZrlJNEJ!)2A` !&IrB2@hl62r@,9,rfR!!%#hl6Me!rpj)E[qq)QhpE#"C6T!!+QlrZ%KZrmjKrrr rq[)Q!%U$C`3J!f"dF!!`,[rUZ)"X"#!%B!C`!$!ZrqSLEJ!8)'lrjR)JX)&P"+) ZB!j+J'F+)JN5f&1!C[SL3A!!-#lrkL"Z!"`JJ#"Z!!`JV[rJ)'i!%$#Zrq3pI!! @rpK)E[qq)QhpE#"C6T!!+QlrZ%KZrmjKrrrrqRJQ!#!$60m%'%jH6R3!')eeC(" ICf9dAf4RFQ&Y!!!U88j@rlK)j`!N5(J!1N+R5'lr[L*YrM3J@8k3!#TZrl3NEJ! )2A`!'2rB2@hl62r@,9,rfNKZrliLEIeX)&P1N!!UE[qd5'lrcQ(rrrrk$#e!rlS [#L*YrTJJ@8k3!#TZrl3NAdjH6R3!")YeC("IFQ9XC@&cC3!!+P&19[r851F3"(B !5Qhl6'B-BIrrrrPJ*J"+JfC!5(J!*%+R5'lre#*YrM3J@8k3!#TZrp!pI!!2rqi pEIY-rqa)E[r8)QhpE#"C6T!!+Qlrd%TZrq4Q##"Z!!JJV[r`*Kp1ANjd!!51Cf9 dAfejAfP`Af&NC()!!!!U88j@rrK1ANjeL'jPG&pTC'aP!!!!+P&19[ri51F3"%U Yr#TR"(!!B'4)H!N!)QhqR#"C6T!!+Qlrp#Y!r#T+VI`UCK"`$#Y!m%JlI!!-r,j `rf!k5(J*!%+R,bhm+L*YrM3J@8k3!#TZrr4f!'!B)!-'J!!!!)"b5%`$'!!JEI` U)B!B"&+$F##fJ'hLF!!Q(djH6R@+BfKPBfYID@jTG!!!!#T46PErq#m$BIq3"'a +J'F%F!"J-(B!B#4`5%`$#!!JEI`U#$!!"`J!CK"`5%`$#!!JEI`UdF!J#'!+8S0 `),D!EGC`!#BI6Pj1GC&RCA4IG@jeFf9NAh0[BfYPG!!!+P&19[ri*#i!#()!B#* `5%`"#!!JEI`UY,!)"'B3F%K-!3J!)'hm+Y(!)!KJ#P+"F##bJ'hBF!"1ANjd!!5 ,CQPZC&pcEf0VCA3!!#T46PErq%MR!#3NEJ!)5(J!"%+R,`SLEIid)&P1N!!UE[r d3US!1%UU!$4R%#mU!$3LEIkB)&P1N!!UE[rd3US!0%+U!$!NAdjH6R3!")jbC@a PBA0PAh0[BfYPG!!!!#T46PErq%MR(#3Q,J!)+Li!$#JZ!""`!VD!CJT+K'FBF!+ iJ'F5F"BV32")1h`!&[bqF2pJ!!#bF!+kJ'FBF!'kJ'F5F"BV32")1h`!&[bqF2p J!!#8BIrrrrkJ*%!J#QB3F!`V32")1h`!$2bqF2pJGM9$!!Je3`!B08-!+$9%!#S P43!X5US!0'Bb5(J)!#*YrT`J@8k3!#TZrr3P3!!d*A`!!!J!!$"+UJ!dCK"`$#Y !m%JlI!!-r,j`rf!U5(J!"%+R,`SLEIid)&P1N!!UE[rd!")!J!*5J(m#+J$[!!& #UJ!i)#S!"%cI"$K1ANjd!!b'FfpMDf9d!!!!+P&19[ri51F!*#4Z!!`)%J!(CK" )EIm))Qhp4#"C6T!!+Qlrp1R5!%K531r5!%JNAdjH6R3!#*4cEf0VCA4ICACPER4 ID'&ZC'aPFJ!!!#T46PErq%MR'$JS,J!3+'i!'#mZ!!KKrrrrrIBN3#!+CK*`&LY !m%JlI!!@r,j`rf!!!-*`!V#U!#aQ#!aU!!)!#'F5F"BV32")1h`!&[bqF2pJ!!# J5US!1'C),bhqi%KU!$J[+J!`,bS!0#m+5'S!#Q(rrrrj&LB!5S0R&Lm+BIrrrrh BF"NV32")1d2m[R$rB'")DJ!-BIrrrr[k!#S!%!!"F"#`VJ!FCJB-9!!#Ca"`&LY !m%JlI!!@r,j`rf!b*N`["#mZ!!``+`!#,`![+`!%,bS!1'(rrrrjY#B!5S0R$R! C+d$`5$Y$r,j`rf!#)!4-ha`B6Pj1G!!BKR0PEQ4dE`!!!#T46PErp%MR%$!QEJ! F,bi!#'(rrrrmmL4!)!TQ%R!@+d$`5$Ym!"Em[R$rB!!!LR!#X+S!,'B)$'S!!J! )Ca"`&LY!m%JlI!!@r,j`rf"SF"#`Nf-3F"BV32")1h`!&[bqF2pJ8R!3*S!QEJ! B0V`!!NKZrr3[,J!3,bi!$%KV!!*)D`!%,bS!1'(rrrrjPLB!kG)!5'F+kG)!5&0 !lp)!5%U$CJBJ,[rdB!a`'5Y!m%Jl3rbqF2p-h``)6Pj1G!!BL(*PBhCQFQpY!!! !+P&19[ri51FI2#SZ!!JSEJ!-*Qi!%#iZ!"3NEJ!B)!TQ"(cqB#3LEId3)&P1N!! UE[rdFMa-%K!!dS!J+J!%6(`!N!4"'Y#",!")H!!J3UG)EIb1)Qhq0#"C6T!!+Ql rp%Ki!#"#TdKYr'iLEIid)&P1N!!UE[rd5(J!)%+R5'hm6L*YrM3J@8k3!#TZrr4 )H!!J3UG)EI`Z)Qhq0#"C6T!!+Qlrp(J!)!aQ"%RYr#iJ#fB%4qhm,NU(CJC"lI` Z,JKf!'!!!+)J!qU))J0d(m+#G!(MUX5c$!"R(L!$FKr!JA)"iDNJ!qU)3HhmEN( `$!!J%)#"))"5K#!$kSJL!h3I`S*d!H1Ua,3-!'GBF)$3Jh)JX)&Z6Lm$BIrrrrX J*%!J#QG!#")!"fFkkG)!5'B@F!'`UJ!XCL`[+J!mBIrrrr5D5S"R(L!$FKr!JA) "iDNJ!qU)3HhmMN(`$!!J%)#"))"5K&+$YS9Y!2pF5S4Q*#*YrA!J@8k3!#TZrr4 KrrrrqESLEId3)&P1N!!UE[rdX)CP!2mZ)!9HJ#B!j)2JLq#,i)[ULpD!jS0`),D !B`*f)#*-3HhmML!$FL#`J@8%SLjJ$NU!C`SL#4,B8i"QqL*")NY"lIaZ)!0b),# "C35L,Q!15S"R#L)*%YK6J'Ek)N%L4d(Yr%iJ!h)JX)&P"+)ZB!j+J'F+)JN5f&1 !C[SL35!%60mFq%jH6R3!&)CcC@aPBh3!!!!U88j@rrK)ja!N*Li!#!b$!!!!J'` 5,`-LEIh3)&P1N!!UE[rdB!!!RLm$BIrrrrRS*%!J#QB'F!"J!!#+)!TR$JJ5!!G R#!aU!!)!+'F3F"BV32")1h`!&[bqF2pJCL!U!#a6J'F'8i"R,Q!q5US!2'G),bS !2'(rrrrb6LB!5S0R1(!C+d$`5$Y$r,i[#Q(rrrrjd($rB#a+UJ!iCa`[+J!iBIr rrrH!B""`&LY!m%JlI!!@r,j`rf!+,`TKrrrrqD*`!%cI"!K1ANjd!!5-FfpMDf9 dAf0XEh0P!!!!+P&19[ri,`e+VIbZCK4)H!,))QhqR#"C6T!!+Qlrp#Y!r+j+VIb bCK4)H!!8)QhqR#"C6T!!+Qlrp#Y!r,*1ANjeLh4dAf&XE'pMBA4P!!!U88j@rrJ [$8UYr+jR%#mYr+iLEIkB)&P1N!!UE[rd3UhmVNUYr,*R%#mYr,)LEIkB)&P1N!! UE[rd3UhmXNjH6R@(G(4ICR*PC3!!+P&19[[S,`e"l[[i)Qi!%#!)%0PQr%KZqrJ LEIeN)&P1N!!UE[[N5'llkNKZqr4)E[[b-#i!$Lm!,bi!##*Yr43J@8k3!#TZqq4 )E[[i,bllp#*Yr63J@8k3!#TZqq41ANjd!!b3!(4dAh0PG&pTG'9YAh4PH(3!!!! U88j@qqJ[$8KZqqT)E[[d5'llmM!Z!!i[!#mZ!!JLEId8)&P1N!!UE[[N5'llq#m Zqr3LEIdN)&P1N!!UE[[N5'llq#*Yr33J@8k3!#TZqq3JEJ!33qllq#!)%0PQr%j H6R3!$*!!G(4ICf9dAfPdC@eIG'9iG!!!!#T46PErj%MR%$`SEJ!)*'i!$#CZ!"" `!$!59i"R$R!!-"*EJ'F'F!"J!!$Z*LS!!J+$!!!!r`b$!!!!!fF8$)-!!!!0C`` -J`!!!"YRCQ!!!-Bf[!!"5'lrkNKZrr4)E[rbF!%[!#m-)Qhp&#"C6T!!+Qlri(! +,`![,[rd)Qhp'#"C6T!!+Qlri%KZrqC)H!!))Qhp$#"C6T!!+Qlri(!!,`![,[r d)Qhp'#"C6T!!+Qlri(!"B'3f[!!#5'lrkNKZrr4)E[rbF!)[!#m-)Qhp&#"C6T! !+Qlri(!+,`![,[rd)Qhp'#"C6T!!+Qlri%KZrqC)H!!))Qhp$#"C6T!!+Qlri(! !,`![,[rd)Qhp'#"C6T!!+Qlri(!"B!*`!%cI(!K1ANjd!!b0G(4ICA9TAfCTE(4 PFJ!!+P&19[p),`e#V[p@3UlrA%KZrdSLEIeJ)&P1N!!UE[p%5N"R"($rB#j#V[q +3QlrQMeZrf$rP%+Zrj!!5'lrIL*Yr2!J@8k3!#TZrd4+3'F%F2pJ"#!Zrja1ANj eQ(4dAfGPG&pfEfaIBh*PBA4TEfjIC'&dC3!!!#T46PErj%MR!$`SEJ!)3QlrpNK irrp#Tc!m"%`[!#*Yr5`J@8k3!#TZrq!Q3#!,CJC`rf!!!9SJ9%)3)&4#+!"N,a4 `"#m!,`YKrrrrr53J9%KS!'4`"Lm!,`YKrrrrr4*`%#m!5(J2d#mYrYJLEIe))&P 1N!!UE[rJ*%")E[rU)Qhp9#"C6T!!+Qlri#m,)Qhp6#"C6T!!+Qlri%KZrqj)E[r N5'lrk(!",`![#b*Yr43J@8k3!#TZrq"`!bm!F!-[!#*YrE!J@8k3!#TZrq"`r#m !F2`[!%KZrqiLEIh!)&P1N!!UE[rJF"![!(!3,`")E[rZ)Qhmb#"C6T!!+Qlri%K ZrrB[#L*Yr13J@8k3!#TZrq!-EJ!"rrCR#!aZ!!,rpQEH,`SLEIdS)&P1N!!UE[r J$'i!!IrfCL`[&(!%,`![#f(rrrrmU#"85'J!C(!',`![#f(rrrrmPQ(rrrrq1#" 8)8!!b#m,)QhpH#"C6T!!+Qlri#m-)QhpD#"C6T!!+Qlri#m-)QhpY#"C6T!!+Ql ri$!ZrrC)`%cI(!"1ANjd!!54G(4IC@4TG&peFf9bAfPZCQm!!#T46PErq%MR!#3 `2!4-,`![2(4dG@NLEIdm)&P1N!!UE[rd*%"+J'C85(J!c#*Yr3!J@8k3!#TZrr3 N3%KYre)`2!4-,`![2(4dG@N[#L*Yr6!J@8k3!#TZrr4)H!$-3UF[%L*YrM3J@8k 3!#TZrr3[#Q(rrrrpjP1!CbT`rf"D$#i!!3!2C`jKrrrrr9SJ8V#S!-KR%#m+BIr rrrh!8i"R"($rB$3LEJ!))&)J2!!!!-ab),#"C35L,Q!15S"R#L)*%YK6J'Ek)N% [#L*YrB!J@8k3!#TZrr4`!#4I6Pj1G!!)N!"dG&pRCA4IGA0PFPpTEQC[!!!!+P& 19[rN,`e)E[rSF!%[!#*Yr0JJ@8k3!#TZrq!p32rQCb)`,[rQ5-![!%KYrfB[,J! ))Qhpp#"C6T!!+Qlri%r[!!aJ8$!Zrr4)`#m!F!!3,[ra,`"`!"!Zrr![!$!Zrqj )`#m!-#lrl%M!,`!`,[rU5-![!$!ZrqK)`#m!5'hrK#mZ!!JLEIhd)&P1N!!UE[r J6qm!*%jH6R3!"*0dG&pRCA4IFhPcAf9ZGQPbEfjc!!!U88j@rr4)j`!N-$`%6#m !,ca$8e45)Qhp2#"C6T!!+Qlrm#4!5S"R4Lm+)Qhp[#"C6T!!+Qlrm#m5BIrrrqS 5,8$rp'F1)'lrp#"S!"!J8#Y3r,B[#L*Yr0`J@8k3!#TZrr![#L*YrB!J@8k3!#T Zrr!NAdjH6R@8G(4ICf9dAh0PFRCPFPpTF'&NC()!!!!U88j@q"K)jam%&Li!&bJ Z!"Kk!(i!)QhpU#"C6T!!+Qli&$e!rYi`,Ibm,`!LEIcd)&P1N!!UE[J8F!'iJ'm D)Qhp%#"C6T!!+Qli&%a%!!&+J@F'F!"J!!*L5UhmYQB5BIq3""C+VIbfCJC`!'! !!NT)E[VHBIrrrrj3GJ"+!fFX%#i!%bm!5'lqp'(rrrrp5%U!Cb3`,[lH,`!LEIc d)&P1N!!UE[J8F2pJ!!)13Llqp%)ZreK#V[qmBIrrrrK#5(J#b%+R,bhmVL*YrM3 J@8k3!#TZq"3JEIbZ-,`!!5"Yr+iaI!!"!!)JEIbZ-A`!!3!%5J0R"(!"B!*`!#" Yr+ia3!!')Qhp%#"C6T!!+Qli&#"Yr+iK3!!)5'lkhNKZreK)E[ld5'hrd%KZq#) LEIhd)&P1N!!UE[J8)'hmXL#Z!!JJEIbb)@i!$!!%3HhrfL*Yr,)M5!!)3Hhr8#* Yr,)M5!!-3Hli)L*Yr,)M5!!3,bhmXLmYr+jKr`!!!PiX!%+R5(J!!NKi!!*Krrr rm9)Q!$em!!,r`$em)66r`LeYr,Era%Ki!"")E[r!3UF["LmYr+i[!f(rrrrbF(S !6qm!&%Ki!#"#TdKZrp!LEIid)&P1N!!UE[J8)!0b(m#"FJ(KU5!$kSK"l[r33I! -!#!3J)%JJ(!&,8$rm%+Zrr4)E[r`3UG#TdKZrp")H!%!BIrrrr2Z+!"+K'BB5(J !%%KZrm"#Tbm',bhmVLm$BIrrrr(k5S4Q#&+&F!1kJ'f%F!'iJ'C@F"!Y32JH5'l i(NKZrm"#TdKi!XJ[,IbZ,`0KrrrrmY!S!#"Yr+i-D!!%!!CQ+%KZrZ![,IbZBIm !!!#L)'lql"!35F!%J!!!!&*R!Q!#I[mYE[l`q"S[!f(rrrreK'(rrrrfUM!ZrYi [!#*Yr23J@8k3!#TZq"3J"dcI!2K1ANjd!"5+G'9cG&pdFQ&MD`!!!#T46PErq#m -)'i!##*Z!!`SEJ!3)Li!&'!++-Lab@3%5KKQq#!"8i&+J'EZ+&p1ANjd!"#3!(C IF'&bFf9IF'YdAf4KG'%!!!!U88j@rrK)H!!&,bi!$#"Z!!K)D!,()'i!#%KS!!a Krj!%QNjH6R3!#)YfAh"KFR0PAh"VG!!!+P&19[ri51FB2#4Z!!JSEJ!-*Qi!%#B Z!"3S#Q!f5T0Q"%)DB"BJ6*(+,`J[%bm+)Qhpm#"C6T!!+Qlrp%+R,`SLEIhS)&P 1N!!UE[rd)%"5L#4)@)XJ!e1$5S"Q`L"+NF3J#%cI("K1ANjd!"#6GPpKFh0PE@* XC9p`Dh4IC'&dB3!!+P&19[ri,`0f"5m$,bi!$#"Z!!K"k!,)NF0)8#"Z!!K)D!! -BIq3"&Tb$0#"*Kp1ANjd!!L1GPpKFh0PE@*XC9p`Dh3!!!!U88j@rrK)jaJN*'i !#(B!BIm!!!&`)QhpU#"C6T!!+Qlrp$J!F2mV32bkF!'`UJ!-CM"`!5m!,bS!%#* YrD3J@8k3!#TZrr4)`#Y!r,T`rl#Yr,TQ$L*YrBJJ@8k3!#TZrr3f!#m%)Qhmp#" C6T!!+Qlrp$!$60m%'%jH6R3!"*&IAfPZDA4TB@aTHQ9I9&466!!!+P&19[ri,`e `rl#Yr,TQ%M!Yr,`[!#*Yr9JJ@8k3!#TZrr4Kr`!!!2a1ANjeN!"IAh4PFQeTEQ& dC9p89&0-!!!!+P&19[ri-#hm[NjH6R@3!%GPG%*64%eKBdp64A*bEh)!!!!U88j @rrK`!%jH6R3!")j*ER0dB@aX3fpZFfpXC3!!!#T46PErq%jH6R@08Q9YEhCP3fp ZFfpXC3!!+P&19[riF!"1ANjd!!L69h*TG'9$D'&bFe4[3fpZFfpXC3!!+P&19[r iF!"1ANjd!!L88Q9KC%0SBA*c4R*[E80[ER0[E'8!!!!U88j@rrK1ANje+P&19[r i,`dJ$5m!,bhqa#*YrV3J@8k3!#TZrr3V32c!BIq3"0C`!%jH6R3!"#T46PErq#m 0)Qhq[#"C6T!!+Qlrp#mYr-!LEIk`)&P1N!!UE[rd6Pj1G5T46PErq%MR!#4J'L" YrX!JNR$r,`![+J!))QS!"#"C6T!!+Qlrp#"YrX!N8#!+CY`NAdjH6R8U85m-+'m !##*[!!a`!#"YrVKJ%%U3!'B)))`K53!%B!j5J&#)$)!!!!#!EHK`rbKI6R3!##T 4)Lm!"%U"E4J-J3!!!)"X%#!"jiJJEIkidF"#N!"#U!!%6R3!"#"[!!4`!*!!V`! -)8!!"(!!)Lm!#*'"))"1G!!-)'m!"#![!!b3!+m!&#&!!!3J,`!))Lm!%*'"))" 1G!!86PErk%MR(cJU,J!)*'i!$#KZ!"!QEJ!85T*Q#%UU!!4R!!$@GJ"i!#"&,"! YD!!%rr3Y8[rX,@S!"2rSIJ"k!%+Zrr"J!!#8eS-J"!+!J!!!!'F%F!''J0L%)!B #J)!!!!"R"(!"L)$FKL!Zrr3#J)!!!!"R"(!"M)!J,[rdd)!Y32rdhSFJ"3+!J!! !!'F%F!'1J0U&YUlrl')-YUlrl'BdZ+lrk'8ZF!'+J#e$rrJY42rm,bS!"#mU!!! [,[rm,blrq%KZrrKKrj!%&LBZrrJS,[rm8Ulrm("!X+lrm'i!rfBJ$'F'+)FT43! %)!YR"LD$*d3!"%cI(2K1ANjd!""19J!!,`SNEJ!)3UF[#NKZ!"4)EJ!-BIrrrrl Q)!SNAdjH6R3!&%j@!!![#L4Z!!J[#N+R5'i!&%KZ!!aKrrrrrX!J#L4I6Pj1G!! 8)#m!",#[!!aR#'85F!&1G!!3)#m!#,#[!""R#'6ZF2p1G!!3F!"1G!!3*#m!##! [!!3L,`!-P+m!%*'"C`TY"R!"6R3!%($r6R3!%#"[!!3J,`!))8!!"!J!!"pR#($ r))"1G!!)F!!JJ%jd!!JU88j@rrK)j`!N5(J!!5*YrR!J@8k3!#TZrr3JEIkN5T! !CKJ[,IkJ)Qhq)#"C6T!!+Qlrp#"YrU4`!5#!,bi!##mYrU!LEIiF)&P1N!!UE[r d*%")H!!")QhqE#"C6T!!+Qlrp#!+*&p1ANjd!!3U88j@rrJ[$5"YrU4+N!"R0%K i!!%LEIj`)&P1N!!UE[rd,bi!##mYrU!LEIiB)&P1N!!UE[rd5(J!!5*YrQ`J@8k 3!#TZrr41ANjd!!3U88j@rrK)ja!d*'i!##CZ!"!Q,J!83T)PEJ!-!!3#+J!I!!J #+J$[!!K#+J!-3LS!$8+U!"*+JfFB,`0)H!!#,`X[#L*YrR`J@8k3!#TZrr4J&%+ R3UG#Tbm+)QhqI#"C6T!!+Qlrp#9U!"B!(N+U!#,TkJ(#!!46J'F'9B"R('!`*@h q8!!b*@hq@!!f*@hq9!!k*@hq6!!qB"C#UJ!b*@hph!!f*@hpf!!k*@hpe!!q3US !3NcI$!K1ANjd!"!U88j@rrK)ja!N5(J!!L*YrR!J@8k3!#TZrr4f!#4YrYaJ)ZR U!F)!"'F8,`SLEIjN)&P1N!!UE[rd!QVqI`!%8S0`4YA!F#1fJ'hB5(J!!L*YrQ` J@8k3!#TZrr4-h`3)6Pj1G5T46PErq%MR'#4i!(B!*'hqh'!LkHS"`J!%Ca3[#L* YrQ!J@8k3!#TZrr4+J'F#H2p5Jh"'eF"`)lD!EGJJ"%cI""K1ANje+P%[$#K[!!J LE`!-)%`L%@!B$"!!$@B'%,`!#Q!+$"!!#QB%%,`!$9+))!&6J8U!CZ!SAdjd!!J U85"[!!3KD!!@!"iKD!!D!#)J+!!5`+J!*T'S!#)KD!!5!#j1G!!%+P&19[ri51F 30#4Z!!JQEJ!-)'S!(T(U!"BQ#%U$Ce3P3`!L##S!"J!&CK4)DJ!L,bS!&L*YrSJ J@8k3!#TZrr3[+J"#5'S!)LmU!"B[%L*U!$SJ@8k3!#TZrr3Q!#!,C`3QUJ!L5S0 R"#!$B"JJ+J!LdDS!%Lm+)QhqK#"C6T!!+Qlrp(!!60m-#%jH6R3!##T46PErq%M R($3NEJ!)*Qi!$#BZ!"!S,J!8kHT4`J!%kHS!!`!)CJ4+K@B'F2pJ!!$+5S0R%R! "YS"R$(!#YS"R"R$rB!!!Y%UU!"CR'!JU!!3!#'F3,bS!&L*YrTJJ@8k3!#TZrr6 [kM&#!!3#+J$[!!JJ5P#)A)JP5!!@)%T3L&b)*8J!(R!"*8!!'N+U!#*#UJ!Q5S0 R"R!"Z)"N#L"U!"j#%(!!B&)J#fBH,`3LEIkF)&P1N!!UE[rd*N"+J'B%F2pJ0J! U!"!!##9,!"BPDJ!@!"iP4!!D3US!*ZRU!F)!"&1!CK)J"!+!!!!"rfB)*A`!!!( r!#C`!%cI$$K1ANjd!"!U88j@rrK)jaJN+#i!##4Z!!cTkM(#!!4#UJ!L5LS!$@B %5S0Q"R$rB!!"%(!#YS"Q$#*YrL3J@8k3!#TZrr6TkJ!$!!KQ81RU!)-!"()#`)& R41RU!)-!"()%`)&R(NKi!!*#Tbm+)Qhq1#"C6T!!+Qlrp%U!C`C`!'!!!-!#+J! I!!J!+J!J!!J[#L*YrS3J@8k3!#TZrr6TkJ!$!!K6!'F3&A`!!3!03US!)R$rB!! !M1RU!8)!"&8!C`iJDJ!HNHS!&V(U!"TQ)N+R,`SLEIk!)&P1N!!UE[rd5S"R$K9 m!!%!$8+U!#*`rf"38kS!)L"U!"j5UJ!H%)6TkJ&#!!49!'FdkHS"3J!%C`C`#VL !CL*#Tbm+)QhqJ#"C6T!!+Qlrp%U!C`i9I!!"!!e#UJ!LF2pJ#%+U!#*`!"!%60m %'%jH6R3!##T46PErq%MR%!4f!#"YrR4`!E#3!'B%F!&JCNKi!!-LEIj`)&P1N!! UE[rd)'hqG%U3!'Bm)Qhq*#"C6T!!+Qlrp(!!,`!LEIl8)&P1N!!UE[rd5N"R#L" YrR4`!L#!B")JEIkS)+hqd#"YrR4`!5#!GJ&)H!!$)QhqE#"C6T!!+Qlrp#!$*Kp 1ANje+P&19[ri51F!*#4Z!""Krj!%E%U!CJ4`!@!d)'hqh%KS!%BLEIjJ)&P1N!! UE[rd,a)[,J!-)Qhqb#"C6T!!+Qlrp#5!F2q`NQB%F!&J!R!!*&p1ANjd!"!U88j @rrK)j`!N*'i!%'(rN!385S"Q"(!"B#![%LmZ!!`LEIl-)&P1N!!UE[rd*)"`rl# 5CJ4`!@!#F!!NAdjH6R3!%#T4F!"1G!!%+P&1G!!%+P&1G!!%+P&19[rd51FI2#K Z!!JX,J!-+#i!%#4Z!"3Q"N`%-!"+JfF15LS!$@B)kHS"`J!%CJC`!'!!!LETkJ( #!!49J'B-)Qhq*#"C6T!!+Qlrm!JU!!B!"@FLkHS"`J!%9i"R'1RU!8)!"&8!C`l TkJ&#!!46!'F%F!"J!R!"+J$TkJ!$!!KQ81RU!)-!"()#`)&R41RU!)-!"()%`)& R(NKi!!*#Tbm+)Qhq1#"C6T!!+Qlrm%U!C`C`!'!!!D3#+J!I!!J!+J!J!!J[#L* YrS3J@8k3!#TZrr$TkJ!$!!K6!'F3&A`!!3!03US!)R!!B!!"F#C-H!"+JfF!!2! JDJ!HXHS!&QB'5S9R!!$J)'S!(T(U!"BJ+J!DN!#)*8!!)TR-,@S!)[rdYUlrp'3 %,82rp1RU!8)!"&-!CLa+V[rdCbB[,[rd5(J!#Lm,)Qhq,#"C6T!!+Qlrm#K!5S" R#L"-8SL4bbe)rr4+V[rdCciLDJ!H)%XJ,[rdFL#`J@8%SLjJ$NU!C`SL#4,B8i" QqL*"eqlrp0LZrr5@V[rd)#lrp0'U!"iJ,[rdNDS!)NUU!#*R$#!-CJMTkJ&#!!4 Q*%+R,`SLEIk!)&P1N!!UE[r`,J"+KfF1&A`!!3!03US!)RB!B!T+JfF'5S9Q!2m f5S0R@NU&CPBSDJ!@+LS!'L9,!"BP3`!D)%[4`b9)!"j)E[rd,`SLEIk!)&P1N!! UE[r`5S"R#K9m!!%!$8+U!#,BV[rd*8`!&L9&!"S[#L*YrS3J@8k3!#TZrr"#UJ! LkHS"3J!%93"R"%+U!#)J"0#'8i"-4J!!60mFq%jH6R3!%#T46PErq%MR'#3NEJ! ))!TQ"($rB&VTkJ(#!!4Q"(!!B%i[#L*YrQ!J@8k3!#TZrr3Q!#m5)QS!2L"C6T! !+Qlrp#J!!QVqI`!%3T))+J!%!!KR%#mU!"BLEIkB)&P1N!!UE[rd5S0Q"%U%C`4 `rf!#F!"-h`3B6Pj1G!!%+P&19[ri51F3*#4Z!!JJ#QB3)QhqM#"C6T!!+Qlrp'! !!+"++J!0CJMTkJ(#!!4Q"R$rB!!!M1RU!!-!#!`!!!0P$!)U!"m!#!!U!%!!#1R U!!-!#&8!CJ4#UJ!LkHS!!`!)8`"R#J)U!"m!#(!!B&$TkJ(#!!46J'B5,`SLEIj !)&P1N!!UE[rd*J"J!RB!3UF[#L*YrS!J@8k3!#TZrr4+J'F1&A`!!3!03US!)R$ rB"!#+J!I!!JP3`!53US!)R!!60m%#%jH6R3!"#T40#m!"R)!)'hqA'!1Y&"Q"#! )B!j5JA")dF"`)l+!EHa`!%jd!!3U88j@rm4)ja!m*Li!##KZ!!`NEJ!3*Qi!&%+ Zrp)p3rrH,8crjLe5rqT#E[rb)!YR*%KZrmBLEIc3)&P1N!!UE[r!B!SL5b"C6T! !+Qlr`%TZrpCZm'!35'lraL*Yr1!J@8k3!#TZrm!NV[rZ$'lrfIr@CJa+NQF%F!" J%(!#B!a+E[r@CJ4`!'!#F!&-ha`)6Pj1G!!3+P&19[r%51F32#BZ!!JSEJ!-*'i !%#CZ!"4#V[r5282rhLe-rqBY8[rU3QlrmL!,Cb4)E[r')QhpA#"C6T!!+Qlr`'! +)NXJ@8k3!#TZrm"+E[r@E["J%%KZrmBLEIfJ)&P1N!!UE[r!*+lrlNTZrpCQ"(! !B!*`!8cI(!K1ANjd!"!U88j@rm4)ja`d+Li!##CZ!!`S,J!3*'i!&%+Zrp)p4Ir H)!4R$P@!C`*J%$em!!,rmQ!12A`!!IrbB!C`!@!!!4!Y8rrd)!TR*%KZrmBLEIf %)&P1N!!UE[r!B!SL5L"C6T!!+Qlr`%TZrpCZm'!35'lraL*YrCJJ@8k3!#TZrm! J%j!!V[rd*J"+J'm!!,BJ,[rdd)-Y32rL)!TR*%KZrmBLEIe!)&P1N!!UE[r!B!S L5L"C6T!!+Qlr`%TZrpCZm'!35'lraL*Yr2JJ@8k3!#TZrm"+E[r@CJ4`!'!#F!& +J'CL3UlrdMe&rpiJ"'F19B"R!Q!32A`!![rbB!`pI!!"rr*J"(!"B%`Y8rrd)!T R*%KZrmBLEIf%)&P1N!!UE[r!B!SL5L"C6T!!+Qlr`%TZrpCZm'!35'lraL*YrCJ J@8k3!#TZrm!QV[rd5QlreQB%F!"J!R!"60m-1%jH6R3!%#T46PErI%MR%#3Q,J! ),`0Krrrrr9SN3$e$rjC)E[pq)Qhp8#"C6T!!+QlrH$B!CLSJ#QFQ)%T3L#e)rj! !2@S!![q8,@S!"2qZ5'lrIL*YrA3J@8k3!#TZrhJf!#!+C`*#8NT$CJ4`!'!#F!& -h`3)6Pj1G!!%+P%LE`!%kHN4`J!%$!%!!@F'$!%!!QB'5LN!$@F-)'hq5(!M))" `rf!dkHN!!`!)CJBJ+3!5B#BJD3!HNHN!&L)T!#l5L1RT!!-!#!`!!!0P#ZRT!!- !#&@!NS!J!8jd!!3U88j@rrJ[$5mZ!!JLEIj%)&P1N!!UE[rd6Pj1G!!%+P&19[r i51FB0#4Z!!JQ,J!3kHT"`J!%$!3!!@B'5LS!$@F1)'hq5(!M))"`rf!!!4ETkJ! $!!K6!'BX3UF[#L*YrS!J@8k3!#TZrr4+J'FB&A`!!3!03US!)L"YrNK`)b#!F2p J!!$JF!'fJ'B@GJ![#L*YrN3J@8k3!#TZrr3S!0QZ!!a`!VD!CfETkJ#$!!4A!'G FkHS!!`!)93"R#ZRU!!-!#&F!CNJJ,J!-X+S!%Q3+)#i!$,#U!#jN#!)U!"m!#'! b)#i!$*!!UJ!Z)'S!&Y(!*8J!(L!U!"+3!+i!$#9!!#)#+J!I!!J!+J"!!!KJ"J) U!"m!#1RU!!-!#'C'*QS!-L!,Cc![+J"#,`0)EJ!-,a)L5b"C6T!!+Qlrp%U!CaB 9I!!"!!e#UJ!L)'hq5(!M))"`rf!33LS!$#9Z!!`!%N+U!#*`!%cI$"K1ANjd!!` U88j@rrK)ja`N*'i!##SZ!!`S,J!3*J8["#m$,`SLEIim)&P1N!!UE[rd60m%1%j H6R3!$#T46PErq%MR'#3NEJ!)+#i!$#BZ!"![!bm%,`SLEIiS)&P1N!!UE[rd)!T -h`3B6Pj1G!!-+P%[#bC[!!JN,`!-)#m!%")#)NY5J'!-XKPQ##"*8iJJ#'!'8i" Qm(!!*Pp1G!!-+P%LE`!%*#m!##![!!`5!L"*dF"5J'!)XL"Q"#!)B!C6J'EdF!" 1G!!-+P&)ja`!)'m!%#J[!"3U,`!BGJ!@"(!JZS"PAR!$+!K%K-L!5S4R#*U%%-0 6K'Ek5S0R&L!$FK$MU#)$G"MPUB+!)!2KL)#"KS!S"HU-5S4R&#$$)--J`b$$)-- J`b$$)-06K'EXH"r)KH5-5S4R"L$$8i4QqR!$bS"+K@F'%-06K@Ek60m!1%jd!!` U85"YrU`JVIk3!%je+P%[#b*[!!JQ58+V!!3J5eL)*dJ!$#G)!!JQL#0YrK3!%#0 YrK!!�m!!#!!!!B3UN!(%+T!#"#U3!N*Pp1G!!%+P&19[ri51FF2#4Z!!JQ,J! -+%T+JfF'F2LfJ'-'F!"J!!$D@)0`r#)$9S(#J#B"YUS!''9!5US!%'Fk5US!('B dH"$BJbm+,`3LDJ!3)&P1N!!UE[rd+J![#Lm%,`9Kr`!!!9JQ3#!,CJC`!'!!!)j fr-D6B(*`%,D!C!*f%#m$,`aKr`!!!I)Q3#!,C``[#bm-BIm!!!'bB%"+UJ!3Cc+ fUJ!BBJKi%0LU!"KJ"(J3f)-[#Lm%)QS!%#"C6T!!+Qlrp#S!,`S["#m&BIm!!!$ X*N!J#fB%F!"J)Lm$,`X[$'(r!!!"`LB!F!%L%i+!*S&`!S'c1!!J5eL))!K-ha` i6Pj1G!!)+P&19[ri51FB2#KZ!!JQEJ!-+!`J#fF!!)iN5eQ+F2iL%X+!*)&fr-D 5*NVA`h$p)K2#J#D"*d2rr#m+,`4Kr`!!!ISN3(EmaT)Q5YI$5U`!&'G)F!,!NQC #5UVrr'`m5T0X1#C+8BYCLdU6C`SJ8b&V!!3!"'!'+@X!"!!J5UX!"'F')'X!"## 6,``[#b*X!"3J@8k3!#TZrr4J#Lm+,`4Kr`!!!(*-ha`B6Pj1G!!)+P&)j`!B*#m !$#)[!"!SE`!85S*Q"(!!B%!L3R!3NS!Q58UX!#"R"L"X!#!JLd+6*f`!)!!%+8X !)&#*F2`LJ&L*)S%J!9Q!dm!LJ9L*F2`LJ#"#8)KBL#!)60mB!%jd!!`U85m,)Qm !##C[!!`J59L)*dJ!"#GT!!`!##"T!!`K5`!%)dX!$#CI6R3!##T4,`XQE`!))Qm !$,26CJBJ8bDS!!JJD3!))@N!"!!%)'N!"#&T!!J!##CI6R3!##T4,``LE`!))Lm !$#"4+%K`r-#3!,#"C3BLL#!)B!SJD!!)XFaQkR!!+&p1G!!)+P&)jami*Qm!+#B [!#a`r#)$9S(#J#B"+K0qr-k&+!HBJb4,eFFX%NU'E4a`!F#'CKB[#Lm[!#KKrj! %DRlmcSEBKpA(B!T`%,L!C!3J"f"#F!2!KB#$*S!S5pR$F!(!K@B%+82rr(!"`)9 +J'F%F!*J!R!!J)3SJ#9%rra`r5)5`S!NJ5m-,bm!+'(rrrrqkL!$60mFq%jd!!` U88MR($JSE`!F*'m!)(Mmb*)Q5YI%+K0fr-D&5S9Y'R!"`)9Q&#m,,`aKrrrrrYc BJh!$`*+!K#5!*LVrr(!#`**Q"%U$E!BPK%MmB"iQ5TI$,`X[$'(rrrrqX0D%F!2 !Ni#$*S!RJcMm*%XJ#NcI($K1G!!)+P&19[ri,`d[,J!))Qhpa#"C6T!!+Qlrp%j H6R3!##T46PErq#m0,bi!##*Yr4`J@8k3!#TZrr41ANjd!!JU88MR'$K2lrr`*Lm !+#K[!#`QE`!`*%-II!!"!!*#,`!$3Lm!"%)[!!9#,`!'3Um!#%+[!!a5LK!55F! Q!()PX)&Q("p$!!G"l`!#3p-Lf#,B)YJbf#"+8SJJ#'!!!U*i!5!$")!!!!!JCb" AJ'FX8B"R%&@!C`CAJ'FSB$4#,`!#B$!II!!"!!0J+!`[!!%!!fFJ(h`!!J!$B"J II!!"!!9J%%S[!!*R#Kpm!!)!!Q!#H!"+K'F)8SS@%NR$B+"`+VD!CMjBP#"8,fM rr!!)5UMrr'`13Lm!!L![!!K%J#p!!!K5LKB55F0J+R!+6#m)!!!)FY$5Jp+!,d% !#&++&K**`h!!%!-JEIl`%$!)!()3`)&QeJb[!!!"r3!)EaiII!$r!!G"l`!#3p- Lf#,B)YJbf#"+8SJJ#'!!!F4`,VD!CPSII!!"!!45LK!55F!Q!()UX)&Q0&L8)&3 [D2rm!!a+U2rmE!4#,`!%8SS@%NR$B#T`#N`[#!!!$(,3dS25J#p"!!a5LKB55F0 `!"!$)'hqm"!`#!"b%-#"CYCi!3b$!!!!D'F5$)-!!!"XCa)-J`!!!%aR%Q!B(h` !!3!'B")II!!#!!CJ#Kpm!!3!"Q!#H!"+K'F'8SS@%NR$(d-!"b!$")!!!!"&C`! !L&@!ChB%J!!!!"&R2&'!9i"R!!#d8i"R-&1!CfT6J'GQ8i"R9P@!Cb"EJ'F!!,a 6J'F@8i"RGPH!C`!!S&@!C`KAJ'F%B!!!XJ`[!!3!"QB'(h`!!`!'5Lm!"'B+F!% [3!!-B!!!QJ`[!!)!!QB!!*!!(h`!!3!#B!!!KNU[!!aQ"R!",d!!$!`[!!%!"QF )$#m!!J!'CJJII!$r!!GJB%S[!!4Q@R!',d!!$'"5(h`!!J!'(h`!!3!&(h`!H!! (F!J[3!!-B$K+,`!%CJC+,`!'Cb`II!$r!!GJ*%S[!!CR(Kpm!2m!"f!@$#m!"!! 'CJiII!!$!!CJ"Kpm!2m!"d([!!*$db,B)YJLf$,B)%T5L#!)6qm!%%cI("K1G!! -+P&)jam`+#m!)#C[!#4q!#S%*%Y#)R`!5S4Q'NU[!$*Q&%S[!#YR#!`[!'m!,@F ')!TJ!!%JF!!3,`!Y")!!!!"BCc44J&Q!Ca*EJ'F1AB"R&Pf!CaTAJ'FHB#*f#NU %E"a%KAi"B"Cf#%)[!#PJ$RB+3Lm!+@!'GK"#,`!T)!9-3`!"+!&-3e!&F!UiJ'` 'F$$BJ'!@F!UBJ!`[!(J!,@B'F'(BJ'!%F%(BJ"8%8SC+K@E+F!LfJ'B55Lm!+fF -$")!-'F'&6`!-&+'$#m!!J!SCL3[E`!Z!$*+KfB'5Lm!+@F%8km!-R!3YS"Q#NS [!#YR"&@[!$)J5j(+)#m!-Y#)$)!!!!(pE`T`!'"'&6`!-&+'[+m!-QhdF"#fJ'B 15Lm!+fF)&5m!,48m!$"+KfF'&6`!,@!D$#m!!3!TCJB92!!VB!`-,`!#!#PQ""8 m!#!J#NcI$2K1G!!B+P&)ja``6qrrk#C[!$Kk!#p[!$!!##p[!$3!$#4,3L*i!%+ R3UF[,`!m,bm!2'(rrrrQC%T!CKT+V`"'CK4+,`!rC`J-,`"[!%&R"L!+B!!"hR! !%#m!335!!!!!@'Gd8B"CJ'F5@i"R$Pf!Cd*GJ'G39i"RAQ"X3Um!%#pm!!!!#J! 83UG#Tbm[!$`[,`!mBIrrrqBX5N"X5Lm[!!`[,`!-5'm!%'(rrrrNBRS"B$4#V`! 3,h`!!!!)!"4#,`!pB#*#V`!3,h`!!!!+!"4#,`!pB""#V`!3,h`!!!!3!"4#,`! p,bm!&#m[!"3[,`!8,bm!&%K[!""KrrrrjA3Q+!!%,bm!&#m[!"3[,`!8,bm!&%K [!"KKrrrrj6"`#VD!E!C`-0D!B"C`#TD!$#m!H!""CJC`BGD!B!4`3GD!&305K%+ R3UF[,`!8,bm!&'(rrrrP4%T!CSa)H!!)3UF[,`!F,bm!('(rrrrP,%T!CK*+,`! rC``-%J!`C`B92!!`8S3-,`!#!$aQ0Lp[!%)!4NU&CJC+,`!pC`46V`"'5(J!%%+ R,bm!(#m[!"aKrrrrj1C+3'B+5Lm!2fF%9Dm!4L",NFSJ,`"'d)J-J!!!!Ie[#R! !B&J92!!`8S5iV`"'EI4)H!!33UF[,`!F,bm!('(rrrrNSNT!CJj+,`!rC`J9,`" "&6`!-%U&C`B92!!YB"S-,`!"!$eQ"K8m!#YJ$!`[!!)!2@B%&6`!)#!+6qm!'%c I$$K1G!!F+P&)ja`i*'m!(#B[!#"+Jf`@3K*#DJ!#&A`!!3!%&A`!-!!&B!!!VR! !%#S!",D!E!!!SLC+@S[A`e+,'#0*a(,3f)%-"!!&CLa`!"!U!!3S5PU-f-"6M,R ,B`B-&!!`Cr5jbfB+%#[rrh)"`)&J!R!"+J"J1J`%!!9H`%3!5F!U!'!X'#0*a(, 3f)(BK3`%!!PH`%3!5F!U!'B%5J4Q"&1$B!`3"%R!FM$3J4D!B!4+JfE35S9R%P* U!!)9I!!"!!39I!!a!!9J#NU$C`$r4"9$!!4-ha`i6R3!##T46PEra%MR($3QEJ! 8$+i!!!(p!#*["R!!B!!$`%)ZrmipI!!Jrp")E[r5,bi!%#mZ!!`[,J!)5'lrcL* YrF`J@8k3!#TZrm"`!"!ZrpC&l[r5@SV8`'!)8blreP*Zrp3-,J!"rpCM"J`L!$" RkR!!%#lre`5!!!!!-'F1")!!!!!CCa"EJ'G3B'4#,[r53Qlre'"D3Ulra%+ZrmK #E[r-5'lra%KZ!!Jr2!!)UHYX%L4,@iSJ5L*YrJ`J#"$CC[aJ%#4,@BSJ5L*YrJJ J#"$CC[`J#Q!!!`BN5eQ+)%SLEIi%)!J3f@Em)!TJ!!,`F!!3,[r@8i$4E[r8*%Y #)R!!%#i!(35!!!!!4@F!!,49J'FB")!!!!!HC`!!TP1!C`!"RP1!C`4J!!+bF!! 3,[r@X+i!)Qm1,bi!)NKZrp*KrrrrrHB-E[rmrp4Y$$!Zrp4)`,#Z!#*Y-%SZ!"Y R"P1Z!#*J$(!!%#lreP1!,8!!)J`Z!'F!(@B)(A`!C3!GB%!GI!"&!"eJ1%SZ!"Y R%$!Zrp4)`&+!NDi!)Q!!!5)`,[r85-"5J()!%LlreT+!,8%!)NU"E!!"#%+Z!#* J!!%!)#i!)P+!FJ!5,[r@XS"[%L!Z!#*5J#m!5'lrdQ(rrrrp5$JZrp4)a(SV5S4 X"%5%HLef!'!D)!4-I!J"!!!!#R!`dS!9!8am5!3!!!!+8S0+K'ELF!+fJ'hF&38 9,J!G)%Z4bL!Z!#,3L!b!!!!"r@m'F!"J!!'Q)#i!)P+!FJ!5,[r@XS"X'(!!%#l reLJZ!#*8K*L!B!392!!`8i4Qq(J!'#lreR!!%!4(l[r5@S[@`'!#&506K'Ek5Ui !)QB'5Li!'fF%&6`!,K8ZrpG+,[r5C`J92!!YB!!"3!`Z!!%!'@B)&6`!+f!!!6! -,J!#!"PQ!!%Q&6`!)'!!!4j`!"!ZrpBb,[r85-&%JG+!8i%S!8U"E!*i!,LZ!#* [0#!%N!#Z!#*b!")ZrpD5J#m"5'lrdQ(rrrrm-R!!%#lreM)Zrp4)`85"dS"6J5J "5S&X!RJ!-#lre%M!8S!U!%U!E!*k!#!&d)3-J!!!!Ie["R!!B!!!UR!!%#lreNI Zrp*DLpE!GJ"J"K8m!$"5Jb!Z!#+3!)5fJ'h`GJ"J""8M8S1fK'`5F!!3,[r@YS" YlQ!'&6`!-&+$YS4YpNUZ!#*Q"NSZ!"YR""8m!#j+K@FNGJ"J"K8m!$"5Jh!!%#l reL)&NS#fJ@hXB!39)e+$YS9Yq'!%&6`!-%SZrp*R"K8m!#eJ'J`Z!!%!'@B'&6` !+f!-$#i!!J!CCJ392!!J)!T-h``i6Pj1G!!J+P&19[h-51FI2#CZ!!JNEJ!-IL! S5RJ!B!!&%%Ki!#8[$#*YrH`J@8k3!#TZrFJX!'Bf)%a`re+!5KKQqLB!f)0+JfF !"1`[#dKi!!%[!bm-)QhqD#"C6T!!+Qlpb%U!CJ!%d($rB!!%c#"'NF`Q#0L$5S0 R)#m,5(J!!5m$,``LEIjS)&P1N!!UE[h)5S"Q"R$rB!!%S#K'5'lrkNKZ!"![$'( rrrrcr#K!F!!3,[r[")!!!!!PC`!$&J5!!!!!)'F!!ET9J'F!!E3%J!!!!"&R!!$ m8B"AJ'F!!Z"6J'G#8i"R!!'B8i"R!!'58i"R!!'-9B"R,&Z!C`!#I&1!C`!!cPQ !C`!"rP@!C`!!`PH!C`!![!5!!!!!KfF!!VjJ!!+k$#i!![rZCJjBVJ!3)'i!%#S SrraJ+J`Z!!2rlQB@8+i!%#"Z!"!YD2rirH)YD2rmrHCJ$&LZ!"!JEJ!3+LMrr!` Z!!(rlQB%-%8U#!`Z!!2rlQBS3HlrqLmJ,b![)#mJ5'lrkLmZrHB[,[hLBIrrrrG i*%"+J'BNB!!#2N(ZrrS[)#mJ,b![)%KZrqS["@(rrrreqL4!5S"R!!)H3HlpkN( S!Iq4bLB)B!!#4J`Z!!,rlQB1@+i!%#"Z!"!U+2rmB#S-,J!$rqjQ&P#Z!"!JEJ! 3,@Mrq2hL,@Mrr2hQB!aBVJ!3)'i!%#SSrr`-,J!"rqjQ"R!!-!8U!!`Z!!2rlQB S3HlrqLmJ,b![)#mJ5'lrkLmZrHB[,[hLBIrrrrE+*%"+J'BNB!!"N!""l[rk,b! [)#mJ,b")E[rU,`9Krrrrp8`N3%U!C`!"F%(ZrHT"k!(rNFSQ#'!!!CJ-,J!%rqj Q(R!+dDi!%#"Z!"!YD2rfrGJYD2rkrG`pD2rqrH"J+&#Z!"!JEJ!35'Mrq%KZrFi r2!J1UHXYE[h1rGJYE[h5rG`pE[h@rH""l[rk,b![)#mJ,b")E[rU,blpi#mZrG` [,[hBBIrrrrNf*%"+J'F!!1K"l[hU3HJ"rj(+*JKJ!!%3@+i!%#"Z!"!ND2rm)!T Q"#4YrJ"+,[rYCaaf!"BD5Llrl'F!!1UfV[rdE`!!iLBZrr4J!!$D5Llrl'FQ*Ll rp#m$3UF[#L*YrM!J@8k3!#TZrFJX!'F!!,JJ4T(+*JKJ!!#Z)%T`re+!5KKQqLB !B!!!RPLZ!"!JEJ!3*'Mrr(!!%#lrlQF38i"R%P1!Ca46J'F@B!!"P#5%B!!"MM5 %B!!"L#5%B!!"JLm%,`TKrrrrh$4J!!&d4HlpkPLZ!"!JEJ!3&+MrrhB"B%4&l[h U&,`!*AB"B$JJ4R$r8S"+''Ek*J$BJdU$Cb![#dKi!!%[!bm')QhqD#"C6T!!+Ql pb%U!CJC`rf!!!5SJ"'!!!53X!dSZrqTR!!#Q$#i!![rUCJ4`-'!#F#!H!!`5!#Y R#!`5!#eQ!!##$!F!-'Ck)#X!)P1V!#*+J'F3)'X!(P+V!"i3NR!!%"*J&#m,%"* *`#m!)QhqH#"C6T!!+Qlpb&+!CJC`rf!!!,a5LP1$B$SJ+`!L8kX!)NU!Ca!JD`! H8UX!(K#(F!!3"f!8,`X3"dR!,`!LEIji)&P1N!!UE[h)8S"Q"($rB(a5KVbZrr" Y`%U$Cai[#dKi!!%[!bm+)QhqD#"C6T!!+Qlpb%U!CJ4`rf"55LlrkQC#B$SJ+`! L8kX!)NU!Ca)JD`!H8UX!(K#m!#"`!(!JB")[#dKi!#!LEIji)&P1N!!UE[h)8S" Q"($rB"*5KVbZrr"Y`0L'5K4Q!2VZ)!4-haci6Pj1G!!-+P&19[q`51F32#4Z!!J SEJ!-*Qi!%%Ki!!&)H2rr,`T)E[qb)Qhpi#"C6T!!+QlrV#m,,`a)E[qb)Qhpr#" C6T!!+QlrV#B!5S0Y"%)b1!!J!dcI(!K1ANjd!!`U88j@rrJ[$8KZ!"![,J!-,bi !##*YrIJJ@8k3!#TZrr41ANje+P%[$#K[!!JJE`!-)#m!%#*))%a5J'!1%0PQ#Q! #3KK6J'EkB!46J'EZ)!`SAdjd!!`U88MR'$!QE`!8+#m!'#4,&J4J$,J$CJJJ5P1 ))!KJ%KJDC["+!fF%NFKJ"#"+8iJJ#%cI$"K1G!!)+P&)jaJ`*Qm!&#J[!"JN5jI ,&J4J#,J$CJ3Q5P1,'"TQp#!,C`3J#f!15J0R"*()B!3J5P1))!K-h``B6R3!##T 46PErq%MR'$3NEJ!)*Qi!$#JZ!"!Q,J!8,`3[#b"YrH3[%#m+)QhqP#"C6T!!+Ql rp1rU-!-!##m+)QhqK#"C6T!!+Qlrp(!!60m-'%jH6R3!%#T4F!*1G!!3+P&`!%j d!"!U8A!!6R3!"#T46PEr3%MR'!3S,J!)5S4Y#R!#Z)"Z"(!!B(T#E[pF286r@%+ Zre*)E[p!)Qhp1#"C6T!!+Qlr2$B!-!0)`'Bm2@lr9[q8286rPNKZrhiLEIe3)&P 1N!!UE[mm0J!`!dM!CKT#V[q3!$eZreErP%KZrhiLEIdJ)&P1N!!UE[mm-!0)`'F +-!0)`#"YrNJJJ%T$CJ4`!'!#F2p-h`!B6Pj1G!!%+P&2lrrd,fm!&!!#,fm!'!! '2fm!(!!+,bm!)%K[!!B[,`!B,aF[,`!),bm!%$mm!!ZTke"2@%p2l`!-6R3!&!J N!4q"K!)K!3%LK"J#)3%")S3B!L%"!5+!Z!)N!4q(k)B#!3X!$#)5&!)K!3-L%K3 @)L3i!L)N-!)L*#J))4-6)K%8!L%"!b)4&"BL*$J#)L3`!L)N+!JK%4-L%"3#)3% $)K!8&L)N1!)L*$!#)L3S!*&%))&r!C!*!T!&!C!5"!L3$c#3#JL3"k#3"S#3&!L 3"Q#3"N#3&!L3"!'!N!G!N"N)N!G!#*!'J)!)N!j!3!L3#i#3"%!)N!K!J!L3"%" !#*!&J*!,#)#3"!L3#J%N,8PZCJ)M5@jQ!501B8i$)Kh!!+Y3)L-)JJ*,)a!M'#- J)bJM-#-i#XJM3#0))e!M@#0J)fJ+aJV##Vi+Z#0`)hJMJ#1))j!!)jJMS#1S)l! MZ#2!)mJMd#2B%aJMi#2S)r!Mq"-F*!!N##33*"JN)"-8*%!N5#43*&JNB#4S*(! NH#5!*)J2l!rS$q32i#53!#5B#q!NS"q8*4JNU#5`*,JN`#6S!#BNm#6i*3!+c!Q i*3JR*4!%,NP38!%J-39SEh0dFbGcEf0VCA4ICACPER4ID'&ZC'aPFMSJFfpMDf9 d)'j[G#"TEL"eFf@UrJF,)YIe!5%3!5%%!L)Ni!JK2`%J-408CA0d9(*KBfXJ9A0 PFL"*EQC[4A*bEh)J*@3J4f9dG'PZCb"6HA-J4@jfDA*[ER-")%T&ERC@CA)J*@3 JE@&MD&4jF'8J*@3JFhPc9Q9b)#9N)("bEf-J*@3J4P"9)#9N)%0[E'pb883J*@3 JDf*N)#9N)'&d9Q9bFb!PC!)S*A-k*A-k*A-#*8eKBdp6!51UrJF-)58")4!")33 #)L6)!#SL2c`")`DTm!)Lrrd5)L,3JJ+""NVd)Y"+9#,35N`Ld%T%)Y"+2#,35HS Ld%QU)Y"*F#,356iLd%ND)Y")`#,33i3Ld$J#)Y!hj#,306BLd$3`)Y!clL,3-q) Ld$0@)Y!c,#,3-[`Ld$,))Y!bP#,3-83Ld$%Q)Y!`a#,3-&!Ld#lf)Y!ZGL,3,H) Ld#c`)Y!XGL,3+K!Ld#S+)Y!U"#,3+I`Ld#Qi)Y!TB#,3*jBLd#D5)Y!Q"#,3*G` Ld#@N)Y!PAL,3*2`Ld#3q)Y!Mp#,3)iSLd#&X)Y!K1#,3)3)Ld#"m)Y!J@#,3)$i Ld#!H)Y!Ir#,3(l`Ld"mX)Y!E%L,3&C!!)Y!1jL,3#(`Ld!K8)Y!%JL,3!i)Ld## B5c3#D!(J%L%"!5%-"#&H"b5+!3--!b-""J%")4`$*3&S!@%-!bB"r2rrh6J#)J, %!5)"%!-P!i)"!3J$)`5#!B%$"`J!!!63!!J!!!8i!3`!!!9`!3J!!#8&T!%K#!- P"I)"!3J$*3EH!3%)!b8(DJ&K#!-L#&3'*3Km!5!)!b8)[!&K4!-M#F!"!5&B!b8 +A!%M4!-P#e!")%J$*3['!3%X!b)-2JBP$&3"!3J$)JcJ!5)"#!-L$8!'*3f-!5! )!b80kJ%R#!-P$ZB")!J$)Jmd!5,M#!-L%$`")Q%-!b84#J(r#!-P%bi")3J$)a3 -!3%K#!-M&&S"!5%)!bB8T2rrh6i#*K8DrrrG4!)P&C!!!H%F!bB@`[rrh8S#*4F i!H!F!b8Bj!%J#!-M'GB"!5%F!b8DKJ%J$!-Q'a,rrpe3!L)GiJBL(LS#)3J$*4j L!H-)!b)Hj!%L!3J$*4mX!5-)!b-I[!%")3J$)Krm"L-JV!%")3J$)b$D!3%K#!- P)3)")!J$)L%i"L)KcS%$"[mB!!!Ld#!!!!!LpL!!!!!M(![rN!3!N!F"!!!Nf!! !!!%!!#63!!!!!3!!!%!!!!!"!!!"A!!!!C3!!!8)!!!!!3!!!!3!N!p!!*!)!J! !$3)!!"`#!!!Q!J!!-J)!!$S#!!"'!J!!6J)!!&N#!!"P!J!!F!)!!))#!!#5!J! !R3)!!+S#!!#k!J!!a!)!!-X#!!$D!J!!i!)!!1S#!!$i!J!""J)!!4%#!!%J!J! "-J)!!8X#!!&B!J!"C!)!!AB#!!'(!J!"N`)!!D%#!!'U!J!"[`)!!FF#!!(6!J! "f`)!!HJ#!!(e!J!#!`)!!JS#!!)D!J!#+3)!!M3#!!*#!J!#8!)!!Pm#!!*[!J! #IJ)!!SF#!!+5!J!#QJ)!!US#!!+i!J!#aJ)!!Y)#!!,K!J!#l!)!![N#!!-"!J! $$`)!!ad#!!-M!J!$,3!"!*!&(!#3"!4"S!!!2%)!!F1!)8)!S!!!JN)!!F1!)8) !S!!!b%)!!F1J!"qB5Mp#6!q"S!!L&%)!J1p'38)!5@jdCA*QB@0P6'PL!%CbB@e P8QpeEQ45C@0d!%GPG&G%5@jQE`"33P*PB@4"FhPZB`"0EhCP5%KT!&0jFd9ZGQP bEfjc!%K9EQa[BfX!8%*5C@&N8hPZB`"0Ef4KE%4TB@a[C`"2F'9Z4(*TGQ9b!%0 KE'a9EQPfCA*cB@a3FQpM!&"#5%GPG&C*EQC[8hPZB`"9Ff95CA0'D@aP!&"#8f9 d48p'8hPZB`"33NK(CA4'5@jQEe0jEQ-!6Q9h5'&ZC'aP!(!bBh0dFJ"%CA4KBfK 5CA0[GA*MC3"%C@aKH3"8D@0V3fpeER3!4f9d4'PKE'pR5A4PE3")D@aTG'9$Efj dFQpX!%4TFh"[Ff93G()!8%*'E(9cD&C[E&0jEQ-!4f9d4'PKE'pR5A4PE94PH(3 !4'PcF'pcC9*[GA4TEQ9%CA0MFQP`G'pb!%GPG%jPGd4TB@a[C`""C'45CA0[GA* MC3"6CA4%D@&XEfG*G'9Y9'9iG!"33NGPG%C$3NPZCQp6H@jM!%GPG&*PFfpeFQ0 P!&"#8f9d48p'3A0jEQ-!4'9LG@G6G()!6Q9h8QpeG'PZC84PFf0bDA"dEh)!8f9 d8'pbG!"33N0XEh0P8hPZB`"(CA43Eh*d!%0XEh0P8Q9c4QPXC3"33PGbDA4P3A0 jEQ-!8%*)4f9d9QpX8hPZB`"M-R"cG()!3fKKEQGPC&*PFfpeFQ0P!&"#3fpZG(* [E%&cH@jM!&0jFh4PE94KFfX!8%*)4'9XCA4P8hPZB`"%DA0`Eh0P4'PKE'pR!%G PG%PZC&*PFfpeFQ0P!&*PE'9KFf95CA0[GA*MC3"33P0PG%C3Eh0"FhPZB`"5CA0 &FR*[FJ"'D@jN4QpXC'9b!%GPFh4KE(3!6NGPG&4bBA""C'4bCA0c!&"#8f9d4P" [Fe0jEQ-!8%*$EfjdFQpX8hPZB`"33PGbDA4P8hPZB`"'8h"2F'9Z8Q9c4QPXC3" $GA*5CA0'D@aP!%K2F'9Z8Q9c4QPXC3"3C@j6DATP!&GbDA4P8Q9cEh9bBf8!4'P cF'pcC8KKEQ4XC3")6'pMD`"*ER0PG&*PBh3!6Q9h8(4b!%GPG%*64%eKBdp64A* bEh*(E(9P!%GPG%*64%eKBdp64A*bEh)!G'9cG&pdFQ&MDdGXG@8!G'9cG&pdFQ& MD`!!#!!!!!J!!J!8a+F!%$dd!!jkQJ!+TjN"!!-d!!!LX!!"!J!$53!!*-J!!3% !!eS!!#)!!!%#!!0T!!!Ni!!"!*!)5Qpj)A"PCQC`Gh"M!!!!!E(413S!N!d$!!) !N!6rN!3!N!CR+!!!CbJ!!'FS!!!'!!!%"!$rN!3!N!BP&!!!%2%!!!3G!!"Y-!) ""!$rN!3!N!i&H!!!!)!%"!3!N!ArN!3!N!F"!!!#H!!!!!%!!!*`!!!!!J!!!%) !!!!"!!!"I!!!!DJ!!!8i!!!!!3!!!!3!N!p"!*!,$3#3#`%!!!""!*!%!J!!&3) !!#3#!!!Z!J!!1J)!!%)#!!"1!J!!9J)!!'%#!!"Y!J!!H!)!!)S#!!#D!J!!T3) !!,)#!!$#!J!!c!)!!0-#!!$L!J!!k!)!!2)#!!%!!J!"$J)!!4N#!!%S!J!"1J) !!9-#!!&J!J!"E!)!!Ai#!!'2!J!"Q`)!!DN#!!'b!J!"a`)!!Fm#!!(E!J!"i`) !!I!#!!(q!J!##`)!!KN#!!)J!J!#-!)!!Mm#!!*+!J!#@!)!!QB#!!*e!J!#K3) !!T3#!!+G!J!#U!)!!V!#!!,!!J!#cJ)!!Y`#!!,S!J!#p`)!!`3#!!-2!J!$&`) !!b8#!!-V!J!$13)!!d-#!!0+!!%!N!89!*!%5N&#&%!"3J&!!8)IJ&0'&35"#S% #!3""!8-"`3""!8-"`3""!81+!d#'!!"*ER4PFQCKBf9-D@)!6@&dD%aTBJ"'FQ& YC9*[G@jN8Q9MG!"(CA4A4%PZCQm!8%*5C@&N3A0jEQ-!6@pfC8K)D3"6HA0&ERC TFQpZF`")9@jXEf0V!&"#8Q9KC&0jEQ-!6@pNB@a%D@&XEfF!6h"PEN4bDACPFJ" $B@aX9@jTGQ9bFf&X8(*[B`"33NK(CA4@5@jQEe0jEQ-!9A0P8Q9c4QPXC3"33P0 PG%924P0jEQ-!8%*)4f9d4NPZCQp6H@jM!%jPGdKKEQ4XC3"`-Q0cG()!4'9dB@0 S8Q9cEh9bBf8!4'9XBAN!9'PMDd0[G@jd!%GPG%4TB@a[CdPdC@d!5'PXDA4P3fp ZG(*[E!"%DA0`Eh0P8(4b!&"#4QaeFfK@Efa6H@jM!%GPG%4TB@a[CdPdC@e8CAK d!%4TFh"[Ff95Eh9dD@jP4'9cBh*TF(4[FJ"(CA41CAG%D@&XEfF!3@4N8Q9cEh9 bBf8!8f9d4'PKE'pR5A4PE94PH(3!8%*(CA4'3d**EQC[8hPZB`"(CA45CA0[GA* MC3"33P0PG%924N&cH@jM!%4PBR9R8h4b!%jPGe*[GA4TEQ9%CA0MFQP`G'pb!&0 PG&"[FR3!8%*$E'pcC90jEQ-!4f9d8'pbG!"$E'pcC9*PFdCTE'8!3Qa[BfY0EhC P4'&dB3"33PGbDA4P3A0jEQ-!8%*)4f9d9QpX8hPZB`"M-R"cG()!3fKKEQGPC&* PFfpeFQ0P!&"#3fpZG(*[E%&cH@jM!&0jFh4PE94KFfX!8%*)4'9XCA4P8hPZB`" %DA0`Eh0P4'PKE'pR!%GPG%PZC&*PFfpeFQ0P!&*PE'9KFf95CA0[GA*MC3"33P0 PG%C3Eh0"FhPZB`"5CA0&FR*[FJ"'D@jN4QpXC'9b!%GPFh4KE(3!6NGPG&4bBA" "C'4bCA0c!&"#8f9d4P"[Fe0jEQ-!8%*$EfjdFQpX8hPZB`"33PGbDA4P8hPZB`" '8h"2F'9Z8Q9c4QPXC3")6h"PEP*PFdCTE'8!3h9b8Q9c4QPXC3"3C@j6DATP!&G bDA4P8Q9cEh9bBf8!5%a[BfX!4'PcF'pcC8KKEQ4XC3"*ER0PG&*PBh3!6Q9h8(4 b!'jeE6*NC@-!4f9d3P0%6@&M6e0&FR*[FNGPG%*64%eKBdp64A*bEh*(E(9PG'9 cG&pdFQ&MDh4PFh4IG(*KBfY(E(9P!!!!#!!!!!J!!J!3263!&-5R!!URQ3!1HTS #!!05!!!#J!!"!3!$BJ!!!pJ!!3)!!hB!!!*S!!%"!!1!!!!$,!!"!*!)I!J#TT! !!3!)P#(r`$JK!%#!!3!)I!J$TNk!!#"m#!+QNq(rr*!!!3!)P#(r`$aJ!!%iBkT Z1)!!!8J!Ab'!33!8I(mEH$aJ!!%iBkKZ1)!!!8J!A`Q!33!8I!2i3%##!!`iB!) !5!!!#$KJ"!#!!3")1#%!3(`)!kD$iIrm6S!!)&4N"5P!JJ!-1'!!!%k!!#!iB!! "6S!!)(`)!UD6iIrmNm(rq*1Krr53!!%!#*3Krl"mIaYiIq2lH%[rrmPmIKYiIm- (G#`$!!&!JJ!J5rrr8AaM"c4Ar`9qIq3(0(`%'!""J!!)1q#SRhrMqhKra20i5!" HDB""!"4mI4Yi2'!!!6KMU*miJ!!"5!"H8B""!"4m!qK!I+!!*P5P(rjSS`!"J!% !@$JK!&"m#!1QJq(rr)2"rrL$SIrd6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(rS(a q'hKmRb0i1'!!!6L"!$a)!&iTJ%%!&+KK!%Tra20iIqAlH$M"!$K)!&iTJ%%!&(a M"c9"JJ!81'!!!,"q!!!iJ!!!N!#I!!#!!3"S1#%!B(`)!kD$iIrmJm(rq%k!!#" m#!+QNq(rr*2"rrL6SIrdN!!"!!L8)Iq`I(dEH(bH)hJli!!!1'#KV8[rrX&8B`B r3B)!*$aJCQmiBfaN1)%!1%J!AB'!33!8I'-(08##!!Jli!!"9q-'2d##!"4rSqY iIm6cH%[rrbP)!!!m1'#!!$b!Bh3iK(*X1+!!!(qQkhKrar0i5!"GKB""!"4mB`F e3B)!&$L!!!#`R3!!1+!!!*!![J!!J!%!@$JK!&"m#!1QJq(rr)2"rrL$SIrd6S! !)(`)!UDrBIrXN!!"!!L8)Ii`I(XEH(bF)hKm[5YiI0icH$KJ!!#3!'%"4$L"!$L 3!)%"5V1K!8k6`3&S1+!!!E#K!94)!!"mJ-%"@(`'f%"!JJ"JJ1%"A(`(i%"!JJ" 8Ik2VH(r%mhJiS3!i1-!!!8J!A2@!33!8I(mEH$aJC'iiBh*`1)!!!8J!A2@!33! 8+!-!!%##!"4rirYi5!"EmB""!"4)!!!-Iq2lH%J!!#bT!3&813J!!E%"!956`3& S1'%"1%J!A0'!33!8I'-(08'#rhJiB2rrJ!%"f$JK!G"m#!1QZf(rl%k!!#"m#!+ QNq(rr*!!!3!)P#(rX$KK!$`iJ3!i5rrq36aJBf3iBf9f2)"kG$L%Bh#SS3!mJ-% !1%[rrZ9mIaYiIq-(0#`$rrp"JJ!-Iq2lH%J!!)JiB3!m1)%!1%[rrBdmB'0N1'0 PGMb!EA3iK'0`U+%!2)$"!$K,rrkPI(mEH(rN"c3X"2rr3B)!$(rMqhK)!!")1'% !2$L"!$K,rrh"2'"MC$KMCABmJ'ed1)4MF+LK!$b!`3!i5rrqCAar'hKrj3Fd,!A rrd'#!!arirYi5!!!#$KJrrq!!3"B1#%!8(`)!kD$iIrm6S!!)(`)!UD6iIrmNm( rq*!!!3!)P#(r`*!!B3"BJ')"p#J$!!""JJ!-1'!!!%J!!-a,rrlYI(mEH$aJC'i iBh*`1)!!!8J!@fQ!33!8N!"L!IL!JJ(i+!3!!%##!"")!&SaJ%%!&%J!!*5!BJ( i5!"EFB""!"4rj3Fd,!Arrd'#!""rirYi5!"D1B""!"5!BJ(i5!"ECB""!"5!BJ( i5!"DDB""!"5!`J(iJ-B!!*!!`J(dJ')"p$L!!q%iS!!"J-%!@%J!@df!33!8I(i EH(r("c9"JJ!NJ')"q%J!@df!33!8J')"q%J!@eQ!33!813!!!*%#!I4r`r0iJ!% !5$JK!%"m#!1QJq(rr)2"rrK1J!!JI!J#TT!!!3!)P#(r`*!!B3"BN!#"!&b3!+% !B*!!`3"NJ')"p#J$!!"!JJ!-1'$rj%J!!#b!BJ(d2)!!!6L%rq%iS!!$J-%!@)$ K!&b"!3"JJ5%!C%J!@Uf!33!8J!%!5$JK!%"m#!1Q6S!!)(`)!UD6iIrmNm(rq*! !!3!)P#(r`*!!B3"B1q)4r$[#%I5!B3"B1))3mB#L!Aa)!!-CB!!!!#`$!!""JJ! -1'!!!%J!!$b!BJ&mN!"q!!!iJ!!!N!#H!!3iSK$aN!#r!!!i`!!!N!$I!!3ii!! #N!$r!!Jj!!!%N4m!$*2I!""rirYiJ!%!5$JK!%"m#!1QJq(rr)2"rrK1J!!JI!J #TT2Krrb3!!%!#*3Krm!iBJ,i1))#$NJ!AI'!33!8I(m(0(rMqhL!!3")1#%!3(` )!kD$iIrm6S!!)(`)!UD3!!%!#*3Krm#!BJ))+!-!!%'#!"5"JJ))5!"H+B""!"4 )!!!)1'!!!)!"!%Ji)3"!I!J$TNk!!#"m#!+QNq(rr*2"rrL3!!%!#*3Krm"mIKY iU(i!!#`$!!&"JJ!-U(i!!%J!!#4,rrqCI(mEH8'#!!arirYi5!!!%%J!@DQ!33! 85rrrd)!"!%Ji)3"!I!J$TS2Krrb$`Iri6S!!)(`)!UD6iIrmNm(rq*1Krr53!!% !#*3Krl"mI4Yi1q)5%+KL!JiX!`!!3))!(%[rr[PmIKYi,"i!!%'#!!ar`r0i5!! !Z(rMqhJiJ!!!1+!!CNJ!-lPJ!!!!U))#$V#I!"JiS!!QX,m!'T1r!"`i`!!HQ0m !)$MJ!!#Br`!K13$r`*NI!#*rirYi5!"F[B""!"3iI`!35rrr#Aaq'hKrirYi1)! !!$LJ!'C)!$0KB!!!!+NL!Jka2`!B18!!+V&I!"U6[`!FIq2lH%J!A-@!33!8UAm !%#`,!!"!JJ!3J(m!)%J!(M9J!!!!,"i!!%##!!LVh`!3Im2cH)!"!&Ji)3"3I!J $TS2Krrb$`IriJk(rp%k!!#"m#!+QNq(rr*2"rrL3!!%!#*3Krm#3!'%!@$[L%RL SBJ)1,!-!!%##!"a,rrhTI(iEH#`H!!""JJ!-1'!!!%J!!'arirYi1)!!!$LJ!'C )!$+TB!!!!+L#!Jk`R`!B1+!!+,#r!"U!`3"BN!$I!"arirYi5!"E`B""!"3iI`! 35rrq$Aaq'hJX(J!!3B)!$$KJ!!")!!!BS2m!2#J(!!"p!!!Q93JIrQN$!!'!!3" )1#%!3(`)!kD$iIrmJm(rq%k!!#"m#!+Q[f(rl*!!!3!)P#(rX*!!B3"SI*XMH*! !S3"`1q)5i)2#!Bb!BJ)%,!-!!%##!#`iBJ,p5rrl&@!!!!"mI3Fd,"d!!%'#!!a rSqYi5!!!T$L!!!'3!))#")"L!C!!1)!$`$LJ!!&)!&FeJ%%!&(am'hJiS!!"X,i !!)"K!'Krj2YiIiAMH(r'mhK,rr[0B!!!!)$I!!!X"UAq3))!%(r$mhK,rrdTN!" r!!"rJq0i5!"A(B""!"5!r`!!,!F!!%'#!!b!I`!!5!!!,)%I!35")3"`N3N!!#J E!!""JJ!8If2EH$LI!!4)!%mYB!!!!$KJ!!#!!3"B1#%!8(`)!kDlBIrX6S!!))# M!!#`T!!!6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(r`,#"!&jm[LYiS'%!ALJ$!!& !JJ!FIprcH(r$mhL!R`!)JCm!"%J!@SQ!33!8J!%!5$JK!%"m#!1QJq(rr)2"rrK 1J!!JI!J#TT2Krrb6`IriNk(rp*1"rr#3!!%!#*3Krh"mI"YiN!#"!+b3!+%!X*! !`3#dN!$K!,L4!3#m1k)6p$[!!!#SBJ)1,!-!!%##!"a,rrZKI(iEH#`H!!""JJ! -Im2cH%J!!1JiB3!i1)!!!$LJ!$T)!$"KB!!!!$KJ!!a)!"VGB!!!!(ar'hJS(`! !3))!$$KJ!!a)!!#d1)!!&,#"!&+SSJ)1X+%!8)$"!,#3!-%!@)$K!,53!1%!A)% G!!!S#!!!3))!()"L!B3iJ$l!1+!!!8J!9@@!33!8N!"p!!#"23!!N5%!B+&F!!# a33"NNq%!CMKK!$K)!&NCJ%%!&+PK!%JX#`!!3B)!'(rMqhK)!"V4B!!!!+KK!%K )!!!`JB%!9*'I!!#!B3#mN!"r!!5!J3#XN!#I!!L!S3#iNq8!!+$"!'5`h!!!Im2 cH)!"!*Ji)3#3!(`)!kD$iIrmJm(rq)1Krr5$JIr`6S!!)(`)!UD6iIrmNm(rq*! !!3!)P#(rF*!!B3#SN!#"!+b`S3#bN!$"!,53!1%!Z$KK!%3iJ!!!1+!!1NJ!,c9 J!!!!J'%!Z,"K!$L!J3#dN!#"!$SiS!!!X+%!2S2K!+Ji`!!AX-%!AUML!Jk`i3" FJ4m!!*%"!'#")3#XN5%!CU&"!,+a33"U1@!!!CPK!(!jJ3!iNB%!E$KK!%4)!&J 4J%%!&$KK!&4,rrTGI(iEH(r$mhL!!3#B1#%!N!"m#!1QJq(rr)2"rrK1J!!JI!J #TT2Krrb6`IriNk(rp*!!!3!)P#(rF*!!B3#SN!#"!+b3!+%!X*!!`3#dI2dlH*% "!,`iB3!i1)!!!$LJ!$T)!#jTB!!!!)2"!+JiB!!9X'%!8UL#!Jk`J3"3J,i!!*! !S3"8L-)#$,$"!&JiB3!i5!"AGB""!"3iB3")5rrj`Aar'hJX(`!!3B)!$(rMqhK )!!"dJ'%!Y)#"!'#Ji3"NI"di!%#!!!arTHYi5!!!#+#K!'4)!#fjB!!!!+%"!'5 ")3#mN3N!!)&"!&U"B3#XN8X!!+'"!&k!B3#`XB-!!$L!!"D`J3"51'%!1%J!9[Q !33!81'%!5%[rq89mIaYiIq2lH)!"!*Ji)3#3!(`)!kD$iIrmJm(rq)1Krr41J!! JI!J#TT2Krrb3!!%!#*3Kri#3!'%!Q$KK!$`iJ!!!1+!!1NJ!,@PJ!!!!Jq%!Q$K J!"L`B3"@U))#$V#"!&5![`!!N!#K!&JiB3!m5!"@IB""!"3iB3"-5rribC!!B3! iIq2lH%J!'$9J!!!!J!%!L$JK!)"m#!1QJq(rr%k!!#"m#!+QNq(rr*!!!3!)P#( rN!#3!'%!L+KL!JiX!`!!3))!&%[rq!PmIaYi,"m!!%##!%`iB3!i1)!!!$LJ!#4 )!#c4B!!!!$L!!!q`J3"5U+)#$V#K!&!iB3!i5!"9mB""!"5S`3"),!B!!%##!"# !i3"8J3%!L*!!k!!!J!%!H$JK!("m#!1QJq(rr%k!!#"1J!!JI!J#TT2Krrb3!!% !#*3Krm#!BJ)3+!-!!%'#!!`iB!!!5!!!J$KJ#3")!"EGB!!!!*!!BJ)3J))#%#J %!!"!JJ!N1+!!$$M#&l#3!+B!!$MJ!!`j!K4iX1J!!$KJrrp)!!"%J')#%$L!!!! iS!N!5!!X%@!!!!!li!!!5!!!($Nr!)#"3J)3(Am!5$P+!!4p+PNZ1rm!!5`I!#" "J2rN1'!!!)!"!%Ji)3"!I!J$TS2Krra1J!!JI!J#TT2Krrb3!!%!#*3Krm",rrm p,!-!!%'#!!`iB!!!5!!!3$[J!!")!!!XJ')#%"bI!%KmBb#Z9'22rd##!"5!SJ) 3(0m!5(aP-K4)!!!81rm!!5`I!#""J2r81'!!!)!"!%Ji)3"!I!J$TS2Krra1J!! JNq(rr$[J!!")!!!`J))#%"br!%JiK!!%I)3S,R`$)!"!JJ!8J-)#%"cr!%KmCMS 85!!!&$[r!!%X(`!J3B$rd$KJ!!#$iIrm6S!!)(`)!UD6iIrmN!!"!!L8)Ir!I(m EH(rMqhJiJ!!!1+!!"%J!+ZPJ!!!!1'!!!*!!I`!iJ*m!0#J%!!""JJ!3J(m!0%J !&G9J!!!!1+!!!*!![`!d1-!!!*!!h`!`J!%!5$JK!%"m#!1QJq(rr%k!!#"m#!+ Q[d(rk*!!!3!)P#(rX(am'hKmQL0iI,XVH$ZL&(Jl`KH`,"`!!N##!"3X'`!!3B) !*#`E!!*"JJ!F1'!!&T!!IJ!!1)!!&V#G!!!iB2rr5!!"!#`D!!*"JJ!N,"S!!8' #!"`iS!!@N!#q!!!i`!!@X0d!!$KJrrp)!!$B5rrq@Aar'hJS(`!!3))!($MJ!!b 3!2i!!$N!!!ba(3!!1'$rrdJ!!,#cR`!)Xjm!',1I!#LcI`!UNem!,)%r!$3S#3! !3))!3$KJ#!")!"4GB!!!!*!!I`!d18!)!*&I!$#"I`!d+!X!!%##!"`jJ!!-NCi !!$KJ!!b`I3!!1'$rrdJ!!&4rirYi1)!!!$LJ!!4)!#Q4B!!!!$L!!!')[`!!8)8 q-*Lr!!!i`!!!S2m!!&$(2(#`r`!!13!!!)Nr!!&4#5EfQ6m!!6P!!!#4A`!iJ(m !")!"!&Ji)3"3I!J$TVY"rqK1J!!JI!J#TT2Krrb3!!%!#*3Krm#3!)%!A)2K!&b )I`!!9'22rd##!"!iBJ-$5!"5(B""!"5JR`!!9)A12MLP!!&3T$a`X*m!!)!"!%J i)3"!I!J$TS2Krra1J!!JI!J#TVm"rq#3!!%!#*3Krk#3!'%!H*!!J3"mI,JVH(c j1hL4!3#-1k)8H$[#&l#!B3"i5rrpAAar'hJS(`!!3))!($KJ!"D3!(i!!$L!!"D `R3!!1'$rrdJ!!4L![`!X,!8!!N##!"#Jh`!)+!B!!N'#!"`ii!!@N!$q!!!j!!! @X4d!!$KJrrp)!!$SJ6m!1#J*!!"!JJ"S1(m!#RrNqhL![`!dJ0m!-$Mr!$L"!J' i5rrhD@!!!!"mHKYi,"S!!%'#!#"rirYi5rrp&6P!!"Q4AJ!!Xed!!$KJrrp)!!# 81(m!$%[rq[9J!!!!1@!!!BQI!!&4E#EfQCm!!B"K!)`S!`!33))!%+#C!!!S"!! #3B)!($LJ!"D3!,i!!$M!!"D`h3!!1'$rrdJ!!%Kr2-YiJ(m!1)#F!!5J[!!#J-% !I(m(`hK,rrJjB!!!!(al'hJX'`!!3B)!'$MJ!"Q3!2i!!,0p!!!iB2rr5!!!#(m $`hL!!3"S1#%!B(`)!kDl!IrJ6S!!)(`)!UDr3IrSN!!"!!L8)IqJN!"K!(L3!)% !I*!!S3#!N!$K!)Kp'N0i1k)8H$[#&l#!B3"i5rrlhAar'hJS(`!!3))!($KJ!"D 3!(i!!$L!!"D`R3!!1'$rrdJ!!0#![`!X,!8!!N##!"#Jh`!)+!B!!N'#!"`ii!! @N!$q!!!j!!!@X4d!!$KJrrp)!!#JJ6S!!#J*!""!J!!F18!!&T&H!!!jB!!@XAd !!$KJrrp)!!"m1B!!%*'D!!#$J3#)1'!!!V"m!!#!I`!i1*`!"$Lm!!+!`3"mJ1% !J$N"!$K,rrIPB!!!!(al'hLJR`!!9)612d'#!"LJ[`!!9+E12MM'rrp3a6a`X,m !!#`E!!"!JJ!-J'%!1%J!!"3ii!!CN!$q!!#cI3!!1'$rri!"!'Ji)3"JI!J$TVY "rqK1J!!JI!J#TVjKrmb3!!%!#*3Krj!!I(JEH(bE)hKm[#YiI0-cH(cd1hJkSK4 B1b)8'$Y#%rJS&!!!3))!$$VJrrj)!!!S5!"*cB""!"5!P!!!()3!2)#d!!3i`%% DI+8cPRaM+K4qj"S8Id26H$L!!!!iS!!J5!!PZ@!!!!"r)mYi1)!!!$LJ!#")!#@ PB!!!!$KL&$JiJ!!!1+!!)%J!*C&J!!!!IU1VH$L!!!!iS!!J5!!PI@!!!!!lS!! !+"X!!%##!!KqZkYi+"`!!%##!!Kq[+Yi+"-!!%##!!KqXkYi1q!!!%J!!0Jii!! "9qJ'rRcR3$"AkHMkI6a),RcR5$P"JJ!N18!!!9IV"[jp5PJ`9qcSqRajB#jmBe0 iI(PK,MZp!!%iJ!!"9q8'rRb%+$"AjZMkI0X`,Rb%-$P"JJ"m12rrJ#`(!#""J3" `Iq2lH%[rqBPmIKYi+"i!!%'#!&b*(J!!93M2rd'#!&#K2J!!95R12d##!#5"AJ! X,!S!!8##!$L!IJ!m5rraX@!!!!!X!`!!3B)!*$PJ!!&Al!EqI@YJ-&IMk2TmQKJ ZI)4EH(bD'5il[3!"1rm!!A`I`!""J2mS,"d!!%##!#4)!%RGJ%%!&%[rppPJ!!! !5!")0B""!"4m!lK!3B$qq$Li!!GmYKj`IYB"P#J@!#"!J3!)1X!!)(pMfhKr400 iIX@cH%J!)q&J!!!!Ii2MH(mNbhKqaE0i5!!Mc@!!!!"qBjYi1))81(l&XhK)!#1 jB!!!!(qMkhL!!3"i1#%!F(`)!kDkBIr-6S!!)(`)!UDrBIrXN!!"!!L8)Iq`I(X EH$ZL&(Jl`KH`,"X!J%#!!"4rBpYi5!"#m@!!!!")!!$dIf2EH%[rq%PmIaYi+"m !!%##!!`iB!!!5!!!f#JI!!""JJ!FL(m!!&4Mcrp"JJ!3S*m!+#J%!!*"JJ!F1+! !&T!![J!!1-!!&V$G!!!iB2rr5!!!S)$r!#`X"`!#3B)!9%#!!'`X"`!"3)!!#%J !!'#"(`!m+!J!!%'#!'b!I`!m5rr['@!!!!"mI"Yi,"`!!%'#!&3j)!!CN6i!!,1 G!!"rirYi5rrhp6KJrrp)!!"%J9m!1#J+!!""JJ!XJ(m!1%[rp9PJ!!!!5!!!($P J!"D4IJ!!1B!!&V'G!!!iB2rr5!!!%(rMqhK,rrHa1'!!!)!"!&Ji)3"3I!J$TVY Krqa1J!!JI!J#TT!!!3!)P#(r`)"L!L!S!`!!3))!&$KJ!XK)!!d*B!!!!*!!BJ) JJ))#(#J%!!"!JJ!81'!!&%J!$1eJ!!!!N!"L!Kb!!3")1#%!3(`)!kC1J!!JI!J #TT!!!3!)P#(r`)"L!L!S!`!!3B)!%)"L!L")!!djB!!!!$L!!!#3!))#))#L!K` S"3!!3B)!%)"L!Ka)!!dCB!!!!$M!!!#3!-)#()!"!%Ji)3"!I!J$TNk!!#"m#!+ QN!!"!!L8)IZ`N!"K"'L`J34ZN!#K"(!iB3!iJ)%%F%J!2kPJ!!!!1'%!1%J!54f !33!8J'%%D+L""'iiS34!1-%%4$MK"$K)!%NCJ%%!&)"K"%3iJ3!i5!"*)B""!"5 !!34B1#%%8(`)!kC1J!!JI!J#TT!!!3!)P#(lX*!!B34SX)%%ET!!S34`J'%%D+L ""'iiS34!1-%%4$MK"$K)!%M&J%%!&)"K"%3iJ3!i5!"*TB""!"3iB3!i5!"*XB" "!"5!B34`1)%!1%J!2`&J!!!!J!%%@$JK"&"m#!1Q6S!!)(`)!UD6iIrmNm(rq*1 Krr56JIr`N!!"!!L8)IqJI(`EH(bH)hKm[5YiS(i!!#`$!!0"JJ!BS*i!!#`%!!9 "JJ!-1'!!!%J!!1b![J!#9,m'2L`I!!e"JJ!J3)!!%#`I!!0"JJ!85!!!b#`I!"Y "JJ"N5!!![$M!!!'`h3!!Ii2MH$L!!!%iS3")1-%!2$MK!%")!%IaJ%%!&)"K!$` iJ!!+5!")%B""!"3iB!!)1)%!1%J!5"Q!33!8J'%!2$L!!!")!%IaJ%%!&$KJ!!& )!!"N11!!!V$p!!"rJq0i1)!!!MLK!%Ji`3!m11%!3%J!4j@!33!8J'%!2$L!!!T )!%HeJ%%!&$KJ!!JiJ3!i5!"([B""!"5!B3!m1)!!!%J!4j@!33!81'!!!8J!!!J iB!!!J!%!D$JK!'"m#!1QJq(rr)2"rrL$SIrdJi(rm%k!!#"m#!+QN!!"!!L8)Im 31'!!!*!!B3"%1)!!!*!!J3"+1'%!1%J!5$'!33!8I'-(08'#!!`iB2rr5!!!4$L J!!#3!+%!H$M!!!#``3#)U1%!6V$K!))j!!!!N3%!IMKK!'a)!%J0J%%!&(aM"c9 "JJ!-1'$rrdJ!!!L!B3#+J!%!q$JK!2"m#!1Q6S!!)(`)!UD6iIrmNm(rq*1Krr5 3!!%!#*3Krk"mI4Yi1'!!!,"K!%`iB!4-1)!!!$LJrrp)!%C*J%%!&(aq'hJS(J! !3))!$$KJrrp)!!&F1)!!!)#p!!#BK3!!1-!!!)$p!!#Ba`"NIm2cH$L!!!5![3! !5rrmfAr$mhJiJ!!'J4d!!$LS!'4,rrc&J')"d$L!$p!iS!!"5!"%"B""!"4mIaY i1'%!5%J!4Q@!33!8Im2cH%J!4R'!33!8Im2cH$L!!!%iS3"%1-%!1$MK!$a)!%A GJ%%!&$KJ!!-iJ!!$5!"'AB""!"3iB3!m1)$rr$LJrra)!%CKJ%%!&$KK!$`iJ!! 31+!!%%J!4Q@!33!8Iq2lH$L"!%a)!%CYJ%%!&+NK!%`X#3!"3B)!%+P"!%`X#J! #3),rh(rMqhK)!%14J%%!&+PK!%`X#`!"3))!0(r$mhJiJ!!%J,d!!%[rr'&r`r0 i1)!!"S'G!!!iV!"N5rrm68[rrJQ!R3!!N!"N!-Kr`r0i5!"'HB""!"4rSqYi5!" 'KB""!"4rSqYi5!"'NB""!"5SB3"-J!%!D$JK!'"m#!1QJq(rr)2"rrL$SIrd6S! !)(`)!UD6iIrmN!!"!!L8)Ir!N!"K!&LBJ3"I2'"dG$KMG@NiJ!4-5!""6B""!"4 mIaYi+"m!!%##!&`iB!$-5!"%6B""!"4mIaYiIq2lH$b!G(3iK(9T1+!%6$M#!da )!%4&J%%!&)"r!!!iJ!!!1+!!c%J!(39J!!!!Iq2lH%[rrF8X!`!"3B)!4$KJrrp )!!"JL'%!AbJ$!!&"JJ!B5rrp(B#I!!#!K!$)I!3B!%'#!"arirYi5rrpM5`$!!& "JJ!-1'$rrdJ!!#L!B3"BJ*m!!$LJ!-a)!"aPB!!!!(rMqhK)!%*"J%%!&$KJ!!# !!3")1#%!3(`)!kD$iIrm6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(rS(aq'hJiB!! "1)%!3%J!3,'!33!8I(mEH(rM"c9"JJ!FIm2cH$L#!f"rj3Fd5!!jV@!!!!")!!! dU)%!6*!!J3!iIm2cH$L#!hkSS3"!U-%!3UMK!%5T!3"'L5%!5)P"!%P)!$PjB!! !!)!"!'Ji)3"JI!J$TS2Krrb$`Iri6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(r`$a J3e-iBe451)!%6%J!2lf!33!8I(mEH#JI!!""JJ"3Iq2lH%J!2lf!33!8J(m!!%[ rjL9J!!!!I(iEH#JH!!""JJ!8J(i!%)"M!!#!B`!!N!"L!KKrirYi5!"!UB""!"4 rirYi5!""&B""!"5!!3")1#%!3(`)!kD$iIrmJm(rq%k!!#"m#!+Q[`(ri*!!!3! )P#(h`*!!B3KBN!#"#&bBS3KMI2JlH$YJ!!")!$k4J%%!&(ak'hJiJK4mJ'3!!%J !2X@!33!8,"J!!8#"!#4)!$lPJ%%!&(bM`jCmTF(@I+8B88'#!!`iB!!!5!!#i)$ #!KJX"J!!3))!(%[rr[@!iJ)B,!F!!%##!!`iB!!!5!!#[$KK!`K,rrj&1b!!!&F S"Mp"JJ!X1'%(6)L"#'0,rrdY,!-!!%'#!$"r3p0i5!!q4B""!"3iB2rr5!!#J$N J!!#C)3G-18!!!*P""l!jB!!!N@%)&%[rpmf!BJ)J1)!!!$LJ!XK)!"TCB!!!!$Q !!!'!BJ)JXB-!!$L!!!'!SJ)JX)8!!MM!!!'!iJ)JX-F!"&FS"Mp"JJ!-15!!!8J !!!Jj)!!!95N'2S&#!L#a+J!'5!!pmB""!"5"BJ)JN!"V!!JiB3"-1))$b6LK"d` i`3H`11%$#%J!0f&J!!!!JB%)@)"L!Kb4J`!!J)%)A)#L!Kb3!)8!"$M#!p+!iJ) FN!$(!!Jj!J)8J5)#(*%*!!`j33"-J@)#(*&,!"#!BJ)JJ))#(%J!!V9J!!!!I(` EH$KJ!!)iJ!!#1+!!!%[rlZPJ!!!!I(mEH$Q!!!+aJ3!m1'!K0,"K!$k!JJ)BN!# "!%"rirYiJ))#)(q&ihJi`!!!11%!2$N!!"",rr"TB!!!!$ZJ!!!iB3F)1)!!!$L J!#")!"NaB!!!!$LJ!!&AjJEqI+8`-&IRk2Sj!3F)I5Ji,RdT+hKp+$NZ18!!"C& ""b`jB!!!N@%(-$KJ!3!iJ3F)1+!!!$M!!!!ii3FX5rrb[@!!!!"mIKYi,"i!!%# #!#4rirYiJ))#)(q&ihJi`!!!11%!2$N!!"",rqrCB!!!!#`H!!"!JJ!31ld!!5` G!!0"J2pN,"i!!8##!(3jJ!!3NB%!1(rMqhL!JJ)J1+!#b$M!!!!ii3!m13%!1%[ rm49J!!!!N!"K"bJX!`!!J))#)+#%!!BX"!!%3))!0)"L!L!iJ3Fi5!!!N@!!!!# !S3G%L+8!!#`&!&*"JJ!)5!!!#$YJrrq!`3G)N!$""c4rirYi5rrd6@!!!!",rrA 4Id26H%J!1m@!33!8If2EH)!"#%Ji)3K!I!J$TVX"rq"1J!!J5!!!**!!C3!!1+8 !"(`$)%"!J!!8L1-!!$KM!!&mj`Ge3),rl#`'!!!ia[rr3),rf%k!!#"m#!+QNq( rr*!!!3!)P#(r`(ar'hL3!)%!A$Kr!!`iR`,(J+%!A$M!!!9,rrqPJ!%!5$JK!%" m#!1QJq(rr%k!!#"m#!+Q[f(rl*!!!3!)P#(rX(ar'hKmR#0iI,iVH(cG-hKrqrY i5!!!6)"q!!!S!`!!3))!&$L!!!#BR`!!1rm!!8J!!"KrirYiJ*i!!(bri&")!$8 PB!!!!(rMqhJiJ!!!5!!eM@!!!!!li`!"1pi!"#`G!!!l[Irr3),rX(alq&#!!3" B1#%!8(`)!kDlBIrX6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(r`(aq'hL3!)%!A$[ J!!8iIJ!-1,i#b(bI+&#!S3"FIqElH%[rrcNiB`!-J!%!5$JK!%"m#!1QJq(rr)2 "rrK1J!!JI!J#TT2Krrb6`IriNk(rp*1"rr#3!!%!#*3Krl"mI"Yi1q)8I$[!!!" )!$GpB!!!!%J!1G'!33!8I(dEH$KJrrq3!(m!!)#F!!`X"!!"3))!0)"m!"!iJ!! "5!!j`B""!"4mB`FdN!"r!!#![`!!,!Arrd##!"")!$QpJ%%!&(aq'hKrSqYi5!! jaB""!"4r`r0iJ!%!@$JK!&"m#!1QJq(rr)2"rrL$SIrdJi(rm%k!!#"m#!+QN!! "!!L8)Ir!1')8I)"M!!!X!rrr3))!&$L#&(b!C!!!5!!jMB""!"4)!$FKB!!!!)! "!%Ji)3"!I!J$TNk!!#!iBK4iU'-!!%k!!#!iB!!!6S!!)%k!!#!iB!!!6S!!)$K J!!"1J!!JI!J#TT2Krrb6`IriN!!"!!L8)Ir!I(iEH$[L&)JiB!!"5!!)l@!!!!# !!J)N,!!!!%##!"KrirYi5!!@P@!!!!!i!!!"N!!#!L4rirYiIm6cH%J!&X&J!!! !I(mEH$KJ!!&)!!LaB!!!!(rMqhL!!3")1#%!3(`)!kD$iIrmJm(rq%k!!#"m#!+ QNq(rr*!!!3!)P#(r`(ar'hL!!J)N,!!!!%'#!#`iB!!"5!!)C@!!!!!iBK5)Iq6 lH%J!&q&J!!!!1'!!!8J!#%eJ!!!!J!%!5$JK!%"m#!1QJq(rr%k!!#"m#!+QNq( rr*!!!3!)P#(r`(ar'hL3!)%!A$MJ!!#3!2m!!)!"!&`S"J!!N!!I!!5)(`!)81! Z0*JI!!L)(`!)81!QpTJI!!LBr`!-Q2m!$C!!r`!83B)!((bN+hKrirYi1+!!!NJ !!ZeJ!!!!5!!!((rMqhKmj$YiI18lH(cQ1hK)!!,4B!!!!)!I!"JiB!!!N!!I!## 3!(m!*+!I!!48!-qq,!!!!N'#!'"!J!!3,!!!!8#!!"4)!!"3,!!!"%#!!%K)!!! SJ')"0)!#!6#3!(m!0)"L!5b3!"m!1)!#!5L3!(m!2*!!(`"!5!!!))!#!553!(m !0)"L!5#3!"m!1)!#!4b3!(m!2*!!(`"!1!!!!*!!(`"%J!%!5$JK!%"m#!1QJq( rr%k!!#"m#!+QNq(rr*2"rrL6SIrdN!!"!!L8)Iq`1'!!!NJ!"[9J!!!!1k)$q$[ !!!!li!!%S"d!"&3!clp"JJ!FIk2VH%J!#HeJ!!!!S"d!"&2J2I#`(3!%1pi!!6Z p!%JX(J!M3B$rd$KJ!!*)!!DYB!!!!)!"!&Ji)3"3I!J$TS2Krrb$`IriJk(rp%k !!#"m#!+QNq(rr*2"rrL6SIrdN!!"!!L8)Iq`1m!!!$ZL!rKrhr0iS"d!"&3!clp "JJ!FIk2VH%J!#M9J!!!!,!-!!%'#!!Jl`2rr1rm!!6Zp!%JX(`!M3B$rd(r$mhL !!3"B1#%!8(`)!kD$iIrmJm(rq)1Krr41J!!JJ-3!!$L!!!Si!!!05!!!+)LM!!! S"3!03))!$*L$!!")!!!3+!8!#N##!!LB!`!!1'-!!5J'!!!ia[rr3),re%k!!## !!`!BN!!$!##!!`!FN!!$!#5!S`!8J)-!+)!$!#4mT#!iI!3!8*!!!`!NJ!-!&*! !!`!`6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(r`(aq'hKmRb0iJ(i!')!H!#"m!`" 43B)!D*!!(J!NL"i!"93!erp!JJ!3J(i!'$LH!#4,rrp&J(i!!)#H!"L!hJ"%JCi !2$Lq!#4)!$Y"J%%!&#JI!!""JJ!-J"i!**!!(`!!,!-!!%'#!!K)!!!JJ(i!*)! H!"4m!"S8N!!H!"4r`r0i5rrr16KJ!!#!!3")1#%!3(`)!kD$iIrmJm(rq%k!!#" m#!+Q[f(rl*!!!3!)P#(rX(aq'hKmQb0iI,`VH(cI-hL)(J!)S(i!"&3!hhp8Bmq q3))!$#`$!!"!JJ!-1'$rrdJ!!4!X(!!!3B)!(#`F!!&"JJ!8,"`!!N'#!!`iB2r r5!!!m)"q!"JS!`!!3B)!')JH!!K8!1Ir3B)!$%[rqpeJ!!!!L"i!"$L!!!"6J!p mQ"i!")Kq!!Ji(J!38)-QpTKq!!L3!"i!'*!!(J!J1k!!!C1q!"b3!*i!*#`F!!# 3!*i!+%'#!!`S(`!"3)!!')#H!#!i!!!!I!-$H*J%!!")!!"d+"X!!%##!$"rirY i5rrkk@!!!!"mHaYi+"X!!%##!!`iB2rr5!!!6)JH!!K6S#EfQ"i!#*0q!"L!IJ! B1!!!!*!!IJ!JNri!(*!!(J!SS"i!"&3!cliX!!!"3))!&&IJ"Ip!JJ!-1!!"rj! !(J!S1'!!!)!"!&Ji)3"3I!J$TVYKrqa1J!!JI!J#TT2Krrb6`IriN!!"!!L8)Ir !I(iEH(bI)hLJI`!%1!!!!*!!(`!NL"m!$94McliS!!!!3))!$#`$!!"!JJ!-1'$ rrdJ!!A3X!`!#3))!$%J!%0eJ!!!!L"m!#&3!hhp!JJ"FL"m!"&3$lhj8B!Hp3B) !6&4J"hY"JJ!SIq2lH$L!!!!iS!!#5!!2"@!!!!!X!`!!3B)!$$KJ!!")!!%FL"m !#$KJ!!&3B#idIq2lH*JI!!K,rrd"B!!!!)JI!!K8!0pq+!!!!8'#!"`i!!!"Q"m !$6J!!!#3!"m!*$KJrrp)!!$BL"m!"&3!rliS!!!#3B)!()"r!"L!(`!JJ*m!((` $!&"m"!"!3))!0(rMqhJiJ!!!5rrme@!!!!!X!`!!3B)!($J!!!'B(`!01!!!!*! !(`!N1'$rrdJ!!)#!I`!N1!2rrj!!(`!NJ(m!)$J$!!'3!"m!)*[$!!#)(`!%9!2 r[P4J"MiS!!!#3B)!6&4J"Mp"JJ!-,"i!#N##!$4rirYi1)!!!%[rr'9J!!!!,!- !!%'#!"`i!!!"Q"m!$6J!!!#3!"m!*$KJrrp)!!!31!!!!*!!(`!N9m-'2S!"!%J i)3"!I!J$TS2Krrb$`Iri6S!!)(`)!UD6iIrmN!!"!!L8)Ir!J!)#+$[J!!!X!!! "3))!$$KJ!!&)!!"X1'!!!dJ!!B&J!!!!J!)#+#`!!!"!JJ"%5!!2(@!!!!"rirY i5rri1@!!!!"mB!Fe3B)!%$J!!!+3!!)#+%J!!"b!JJ%m1')8J$J!!!'3!)-!!(` I!hL3!!)#+$KJ!!0)!!%YB!!!!(rMqhL!!3")1#%!3(`)!kD$iIrm6S!!)(`)!UD 6iIrmNm(rq*!!!3!)P#(r`(bH)hKm[bYi5rrr35`$!!"!JJ!-1'!!!8J!!%3iBJ2 i1'-!5%J!",9J!!!!Im2cH)#I!!",rrHYB!!!!*!!I`!!J(m!!$J!rrpm!`"!3)) !$$KJ!!&)!!!)1'!!!)!"!%Ji)3"!I!J$TS2Krrb$`Iri6S!!)(`)!UD6iIrmNm( rq*!!!3!)P#(r`(bH)hKm[bYi5rrqZ5`$!!"!JJ!-1'!!!8J!!$4r`r0iJ*m!!%[ rpbeJ!!!!N!"r!!#!I`!!1!$rrh`$!%"!JJ!-1'!!!8J!!!JiB!!!J!%!5$JK!%" m#!1QJq(rr)2"rrK1J!!J1'!!!%k!!#"1J!!J6S!!)(`)!UDr)IrNN!!"!!L8)Iq JI(XEH(bC)hKmfM0iIlNTed'#!"b)'J!0+!!!!%##!"#JHJ!%9'$2[d##!!`iB!! !5!!#`&4JcliX!!!#3))!$%J!$9PJ!!!!L"S!"6[J!!"8!0Ir3B)!,+!D!!48!-q q,!!!!d'#!"b)'J!%9!$r[LJ!!!*"JJ!-+!!!!8##!!Jli!!"L"S!#&3!hhp!JJ" FL"S!"&3$lhj8B!Hp3B)!6&4J"hY"JJ!SId26H$L!!!!iS!!#5!!,4@!!!!!X!`! !3B)!$$KJ!!")!!)SL"S!#$KJ!!&3B#idId26H*JD!!K,rrP"B!!!!)JD!!K8!0p q+!!!!8'#!"`iB!!"1!!!!*Kk!!em!`0iN!!D!#4)!!(N+"d!!(pqfhJlJ!!!3B) "2)"k!##!'J!BI!-!3%##!!`X(`!!3B)"*)#D!"L!HJ!JJ"S!((aN'&"m!`"3N!! D!#5!'J!N1f!!!*!!!3!iJ!%!1(`!k%"!J3!)Nk%!1)JD!!48!2qq+!!!!8##!$L !S3!i+!8!!%'#!#ar`r0i1)!!#NJ!#bPJ!!!!I(XEH#JE!!""JJ!31"X!!A`H!&# 3!!%!1)#K!$JS"3!!3B)!3)"k!#"ra20i5!!+9@!!!!#!J3!iJ"S!)(rH)K4m!#) 8N!!D!##!B3!iJ"S!*(qF)K4m!`"3N!!D!#4rT1K3J"S!*#J!!!""JJ!B+"X!!%# #!"#)'J!%9!$r[d##!$4r3p0i1)!!!%[rq$9J!!!!,!-!!%'#!"`iB!!"1!!!!*K k!!em(30iN!!D!#4)!!!8+"d!!%'#!!`X(`!!3),qr#JG!!""JJ"`,"m!!%##!'L $HJ!BJrS!((`HkK56fJ!BNlS!((p$dhL3!"S!)$L"!$K,rrI0B!!!!#`$!!""JJ! 81!!!!CJD!!di!!!!N!!D!#5!!3!iId26H*0k!"L6qJ!FIj`#&%[rpf9J!!!!1!! !!*!!'J!NL"S!"&3!rliS!!!#3B)!$$J!!!#3!"S!*$JCrrpm(!)8I'$,PS!"!'J i)3"JI!J$TVXKrq41J!!JI!J#TT2Krrb6`IriNk(rp*!!!3!)P#(rX(ap'hJS(3! !3))!$$KJrrp)!!#%S"d!"&3!clp!JJ!-1'!!!%J!!("rSqYi5!!!K@!!!!"mIaY iJ(d!!)'G!%")!$+9J%%!&+!G!!3iJ!!!8)!pm,!G!!53!*d!!)JG!!KmIKYi9!$ Rrd'#!"#!I3!B5rrce@!!!!!X(`!!3))!$#`H!!""JJ!-1'$rrdJ!!!JiB!!!J!% !@$JK!&"m#!1QJq(rr)2"rrL$SIrd6S!!)(`)!UD6iIrmNm(rq*!!!3!)P#(r`(a r'hJS(`!!3))!%%[rpAPJ!!!!5!!!q)JI!!dS!!!!3))!%+!I!!48!-qr3))!$$K Jrrp)!!$BL(m!#&4JhhiS!!!$3B!!&(aJ'hJiB!!#8'!Z0*JI!!L)(`!)9!$IILJ !!!*!JJ!-1!!!!*!!(`!NL*m!#&5!hhiS!!!"3B)!'$KJ!!"mJ#0i8'!Z0*JI!!K )!!"mS"m!"&3!cliX!!!"3))!((rMqhK)!!9KB!!!!(aq'hJS(J!!5!!!#$[!!!" rirYi1)!!!%[rpDeJ!!!!,!-!!%'#!"`i!!!"Q"m!$6J!!!#3!"m!*$KJrrp)!!! JL"m!#$L!!!"3J#idQ"m!#*2I!"4mJb0iN!#I!#5!!3")1#%!3(`)!kD$iIrmJm( rq%k!!#!iSKHd1!!!)h`*!kDSK3!!I'!(0(`%!!"!JJ!-I+-VH%k!!#!iT3")3J$ rj$KJ!!"1J!!JI!J#TT2Krrb6`IriN!!"!!L8)Iq!I,iVH(cI-hJiS!!!N!#K!%5 `B3"3N!#"!&L!(J!!+"m!!*!!!3"FX+%!C%'#!$!iB3!i5!!Y,B""!"4)!!!3Iqc lH%J!-'@!33!8U!%!5#`!!!""JIrX5!!!%$KK!$K)!#dCJ%%!&)!"!'#3!"i!!+J "!%JX!2rC3))!))!H!!!S!!!!3B)!$$KJ!!")!!!J1'!!!NJ!!"JX!!!!3))!$$K J!!")!!!)1'!!!B!"!)Ji)3#!I!J$TS2Krrb$`Iri6S!!)(`)!UD6iIrmNm(rq*! !!3!)P#(rJ(bq+hKmhc0i1+!!!*!!S3"%X'%!8*!!J3"BJ"i!!#JI!!#3!!%!A,# K!'4"JJ!`1'%!1%J!,)Q!33!85!!!%(rXqhK)!#q4J%%!&+J"!%JX!!!!3B(rl%J !!"!iB3!i5!!XGB""!"5!!3"JN!!H!!#S!3"),!!!!%##!!`iB!!!5!!!#$KJ!!' !!3#)1#%!J(`)!kD$iIrmJm(rq%k!!#"m#!+QNq(rr*2"rrL6SIrdNi(rm*!!!3! )P#(rJ(am'hKmRL0iI,dVH(cI-hJi!!!!N!!"!%3X(3!"Xi%!8%'#!$4!J!!3,"d !!%#!!"a)!!!N,"d!!d#!!"`i!!!#X!%!C%J!!"Ji!!!"X!%!C%J!!!`iB!!"5!! "H)!H!!!S(`!!N!!"!'C"JJ!`1'%!1%J!+`'!33!85!!!%(rXqhK)!#kCJ%%!&+J "!%JX!!!!3B(rl%J!!"!iB3!i5!!UlB""!"5!B3"QJ"i!!(`$!&&!J3%!+"m!!(` $!K53!!%!9%'#!$!iB3!i5!!UfB""!"4)!!!3IqclH%J!,N'!33!8U!%!5#`!!!" "JIrX5!!!%$KK!$K)!#V&J%%!&+J"!%JX!!!!3))!$$J!!!")!!!)1!!!!5`!!!" !JJ#B1!!!!*!!!3"%,"d!!E1"!&""JJ!d3)!!%#`G!!"!J!!F5!!!*#`G!!0!J!! F1!!!!V!"!'4)!!!B1!!!!E!"!'4)!!!-1'!!!8J!!'b!(J!!+"m!!*!!!3"Q3B) !-$KK!$K)!#ReJ%%!&%J!!""rl2Yi5!!YMB""!"5S!3"),!!!!%'"rqa)!!!31'% !1%J!+H'!33!8J!%!CT!!(J!!U!%!5#`!!!"!JJ!-1'!!!%J!!!JiB!!"J!%!L$J K!)"m#!1QJq(rr)2"rrL$SIrdJi(rm%k!!#"m#!+QNq(rr*2"rrL3!!%!#*3Krd" mIKYiIm2cH%[rr#&mIaYiXm%!8$KK!$K)!#S9J%%!&(aJ"c9!JJ!`+"m!!%'#!#J i(`!)N!!"!%US(`!#1'%!1,!"!%k!(`!%N!!"!'K)!#RjJ%%!&#JI!!""JJ!-1!! !!,!I!!"mB!Fe3))!$$KJ!!")!!!)1'!!!B!"!-Ji)3$!I!J$TS2Krrb$`Iri6S! !)+!$!!48!-qq+!!!!8'#!!`S!!!#3))!%)J$!!dS!!!!3B)!'$KL&l!i!!!MN!! $!!!iB2rr6S!!))J$!!K8"Ypq9-!'2d##!!b!B`!86S!!)&6!"Mk!S`!BJ)-!)#J !!!1!B`!`I!8J8(aM!K40J!!J1!ErrRaJ'&"1J!!JI!J#TT!!!3!)P#(r`%[rrhQ !!3")1#%!3(`)!kC1J!!JI!J#TT2Krrb6`IriNk(rp*!!!3!)P#(rX(ap'hKm[LY iN!#"!'bJ(3!%1q)AX&3!cliS!!!"3))!%)JG!!dS!!!!3B)!&$J!!#13!"m!!$K Jrrp)!!'%L"d!#&3!hhiS!!!"3))!2(qMkhJiJ!!!5rr[i@!!!!!X!`!!3B)!*$J !!!'B(3!01!!!!*!!(3!N1!!!)j!!(`!!1'$rrdJ!!6`X(J!"3))!)$[!!!"rSqY i5rrqZB!"!'`S!`!!I!!D&*!!!3"X,"i!!N'#!*!!L"d!"&3!lhiS!!!$3B)!J)J G!!K8!0pq+!!!!N'#!!`S!!!$3))!D)#"!'b!(3!8I!3!3%#!!"#!(3!`I!3!3%# !!"L)(3!)1'!!!&"J,M5B(3!)5!!!5)"p!"Km!#"3I!-#&*!!(3!JJ)%!E)!G!"3 iB!!#I!3!8*!!(3!NL"d!#&"J,M5B(3!)5!!!&)JG!!JiB!!!8'!Z0*JG!!L)(3! )9!$IId##!'5"R3!d+!`!!%'#!%5!I3!!J0d!4(r&mhJiJ3"X5!!UAB""!"3X!`! !3B)!*$J!!!'B(3!01!!!!*!!(3!N1!!!)j!!(`!!1'$rrdJ!!"`iB!!!Q(d!$)! "!'b3!"d!&*!!I3!N1'!!!)!"!&Ji)3"3I!J$TS2Krrb$`IriJk(rp%k!!#"m#!+ QN!!"!!L8)Ir!5rrq"B!"!%Ji)3"!I!J$TNk!!#"m#!+QNq(rr*!!!3!)P#(r`(a r'hKmJb0iIq6lH%J!*`@!33!8Iq2lH)!"!%Ji)3"!I!J$TS2Krra1J!!JI!J#TT2 Krrb3!!%!#*3Krm"mIaYiIq2lH%J!!(PJ!!!!Iq2lH)!"!%Ji)3"!I!J$TS2Krra 1J!!J1'2rrcLP!!&)!!!8M!-!!A`!)%"!JJ!)6S!!)$5Prrp!J[rX1'!!!%k!!#" mBbS81+8!!8J!!"5-!rrrI!!J3%##!!K1J!!J0+Arrd##rq`iB!!!6S!!)#J&!#" 8KJBq112rrd'!!*!!I!F!d&3!"lp"JJ!8I+!S8*c(!!%d!2rr3),rq#J'!!""JJ! F9-2!$P6!J"j8a%!ZI'!$H(b!!hKmaJ0i9+$CIcMRrre"JJ!XP-F!"*6(!!58a`! %P-F!"*6(!!58a`!%P-F!"*6(!!3d!2rr3),rh&5Jphp"JJ!3P-F!"$3!rrp!J[r i11F!!e5P"liS"3!!6B)!)*c(!!%dTIrr3),rq%k!!##!!J&%1')8K*!!!`!!6S! !)$M!!!#3!--!"$J$!!53!!-!$*!!!`!)2)!!!B#L!9#3!!-!!)!#!8b3!+-!%*! !!`!81)5!!*!!J`!BN!$$!"b3!--!)*!!``!N6S!!)(`)!UD6iIrmNm(rq*1Krr5 6JIr`N!!"!!L8)Iq`I(`EH#J%!!"rRq0i3B)!%$J!rr4m"!"!3)%!$$KJ!!")!!% X1'3!#i!F!"K8I3!iI"d!3%'!!&b"R!!3+!`!!%'#!&#!(!!F,!!!!%##!%3lh3! 3Im2cH(q%ihK)!#H0J%%!&(r%mhKrKH0i5!!##Aaq'hJS(J!!3))!$$KJ!!")!!$ -J"i!!&3G!$T)!!#N+"d!%%#!!!JlS!!3Iq2lH(qNkhK)!!+&I(iEH#JH!!""JJ! 8Iq2lH(r%mhK)!!)p5!!!A)!F!"!S!!!!3B)!3)"m!"Km(4K!3B%!$$[$!"")!!! )1pd!%)'F!""r`r0iIi6MH%J!*[@!33!8Im6cH(q&ihK)!!&aI(iEH#JH!!"!JJ! -1'!!!%J!!$4rirYiIm6cH(qPkhK)!!)pI(dEH)!H!!!iIJ!%B!!!!C!!(J!!I"l S,Q!!!!*m(ZNZJ!%!@$JK!&"m#!1QJq(rr)2"rrL$SIrdJi(rm%k!!#"m#!+QNq( rr*2"rrL3!!%!#*3Krm"mIaYi+!3!!(rqqhK"JJ$31+6rr)!&!!"r`r0i9!!!2*! !"3!!J!8!!(bN+hK8"`!kI-8k&)!'!!"8!!IkN!!'!!#3!1Err%J!!R9mC4YiJ"m !&)"P!!!S!!!!9'F!1Rc&1K4"JJ"`9'!([8##!'L!"Irm,!!!!%#!!&b!"J!!,!! !!%#!!&!iCIrdJ)-!!#J%!!""JJ!3J!-!"*!!"!!%5!!!$)!$!!53!"m!))#$!!3 S"!!!3B)!$)!$!!#3!!3!!)'I!"4rj2Yi5!!PTB""!"4)!!!3Im2cH(bN+hK)!!# "J!%!5$JK!%"m#!1QJq(rr)2"rrK1J!!J+!-!!%##!!`iB!!!6S!!))$&!#"mCaY i+!B!!(cS1hJj*2r`3B)!#*%'!!!i!!!!N!!)!!#!"3!J1)$rr*!!#!!%N38!)*5 (!!L9*`!%1!Rrr(cR!K54*`!!P)F!"$KM!!a1J!!J1!-!"*!!"!!%J!-!$*!!"!! )J+-!$*!!K3!%N!#$!!a1J!!JJ+-!!(`%+%"!JJ!-J!8!#*!!!`!!J!3!")"N!!L 3!!-!")!%!!L!C!!%N!!$!!K1J!!JI'BEH)#Q!!"mSbYiJ!8!!&3!!$Tm!#"!3B! !%(bM+hL3!+B!!%k!!##!T3!)I!8B3%##rp`iB!!!6S!!)(`)!UDr)IrNN!!"!!L 8)IqJI(mEH(bC)hL$f3!!1!8!"eI$!$TrH4S8JlX!!&3D!$JX(3!!IjSB8%'!!#K AS!Ir3))!)(rMqhKrC0Yi5rrr59HJ!$TrR!)8IhX#&%J!!"!S(!!33)!!#%J!!&K A`!HqId-$H&I!"rq3!(N!!(bCdK4!JJ!)Nd6rr&I!"rp"JJ!-1!!!!NJ!!!Ji!!! !Ii!$H*!!"!!!Nj[rr)!E!!"rirYi9!!(qT!!'`!!5rrq[Ap$dhL!!3"S1#%!B(` )!kDl)IrN6S!!)(`)!UDrBIrXN!!"!!L8)Iq`I(XEH(bF)hL!(!!!9"i!1RrmmK5 !(`!!,!!!!&3G!$T"J!!X9!!(rd##!#4rBpYiIq6lH%[rrRf!(!!!IplU&&3!"lj r`!0iN!!F!!#!(!!!Jlcrr&3!"le!JJ!-,"d!!%#!!"!i([rmIp`",NJ!!$4rrH" 3If2EH(rNqhK,rrieJ"m!!(qpmK48!!HqIk!$H*!!(`!!1"hrr(rmqhKr[`%ZIi2 MH)!"!&Ji)3"3I!J$TVYKrqa1J!!JI!J#TT!!!3!)P#(r`%J!(`@!33!8J!%!5$J K!%"m#!1Q6S!!)(`)!UD3!!%!#*3Krm")!"ljJ%%!&)!"!%Ji)3"!I!J$TNk!!#! i!!!"Q!(rm$J!!!#B!IraQ!(rmTJ"rr1B!IrdN!!"rrL3!!(rr$M$!!'*"J!!1') 0d(d)"h3X#!!P3))!-*N"rr@!JIr`J!(rp$KQ!!'3!)8!!*!!"3!%J)(rq)!"rrb 3!)8!#*!!"3!-6S!!)$J)rq!S!!!315!!!8'"!'3iiJqJ9!!31RcR!#jmk31Q6S! %)$J!!!#B!Ir`5!!!5*NKrr&)!!"!L!(rm5J!!!&"JJ!d1!!!!TJ"rr&)!!!SQ5( rmdJ!!##)!Ir`+!!!!%'#!"3i!!!#Q!(rm%J!!!Jj)!!!,!N!!%'#!"#0"J!"I3J (G%[rrh`X#!!U3))!B)$N!!!ij`!%N!$N!!#!"rrm,!!!!*!!!Iri3)!!'$J!!!# B!Ir`J!(rq(`!!0#3!!(rq)d'!!&p#!Gd5!!!0%J!!##!!Iri(!!!#RcS!K3i"rr 3N!!"rrL0"J!"I3J(G&8!"Mjm!`#Z9!!'pd##rpL!!Iri,!!"r8#"!$3i!!$rQ!( rpB#"rr#!!Ird1'B!!C!!K3!!N!!&!!5!JIriJ!(rr*!!K3!)N!!&!!a1J!!J,!J !,N##!(`i!!!"Q!(rmSd'!!&p#!Gd,!J!+N##!&5!C!!!1'-!"*!!C!!!J!2rr#` !!!#3!!(rr%#!!!`i!!!!Q!(rmSd'!!&p#!Gd5!!!0%J!!##!!Irm(!!!#Rb)!K3 i"2r3N!!"rrb0"J!"I3J(G&8!"Mjm!`#Z9!!'pd##rpJX#!"S15!!!8'#!#"!J!! 3,!J!6%'#!#K)!!!`,!J!E%'#!"")!!!NQ5(rp%J!!#!i!!!#Q!(rp%J!!"3i!!! %Q!(rp%J!!!Jj)!!!,!N!!%'#!!b0"J!"I3J(G$J)rlXS!!!cQ3(rp8'"!5!iBJl 39!!31RaM!#jmD31Q6S!%))J"rr3S!!!%3))!$$J!!!1B!IrdL!(rmLJ!!!"!JJ! 31!!!!C!!!Irm5!!!k)J"rr!S!!!#3))!h$J!!!'B!Ir`5!!!d)!"rr`X!!!!3)) !$$J!!!'3!!(rr)J"rr3S!!!"3B)!$#J!!!*!JJ!31!!!rjJ"rr9)!!#FL!(rmLJ !!!"!JJ#3!$J!!!D3!!(rr%J!!)3i!!!#Q!(rp$J!!!'B!Irc1!!!H*J"rr8i!!! )N!!"rra)!!"JL!(rmLJ!!!"!JJ!3L!(rp#J!!!""JJ")1!!!rjJ"rr9)!!!mL!( rp#J!!!""JJ!`1!!!rjJ"rr9)!!!NL!(rp#J!!!4!JJ!B1!!!!jJ"rr4)!!!-1!! !rjJ"rr@!JIr`J!(rp$KQ!!'3!)8!!*!!"3!%J)(rq)!"rrb3!)8!#*!!"3!-6S! !)*!!S3!JN!$"!#53!1%!+*%"!#`X!`!!11!!!$LNrrpmDKYiI1BlH*MP!!"!JJ! `J3%!,#`)!!"!JJ!NL3%!)bJ)!!""JJ!3L3%!*5J)!'p"JJ!-I+-VH%k!!##*!3! P15MrU#J*!#""J3"F13)2j&8T%$Tp#%JZI3N$TNk!"#!X!`!!1!!!#N#!!$ap5J$ 311!!!8J!!$!i!!!!Q!%!)6J!!!K)!!!J1!!!!*J"!#%i!!!+5!!!%$J!!!#B!3! K1!!!%(d+!jCp#!(@I3K38(e+!jBX#!!+3)!!$$N)!$")!!!JL'%!*6N)rrBS!`" i3))!$$N)!'&)!!!)13J!35J+!!#G"Irr1-B!!8##rlJS!!!)3))!+)KK!#-S!`! !3B)!()KP!!!X!`!`3B)!%$KJ!$#FCIrr1-B!!BKK!#!S!`!#3))!6)"K!#JX"`! !N!"K!#a!JJ!3L'%!)5J$!!""JJ!3J'%!,$KMrrq3!'%!,#J!!""!JJ!FL'%!)bJ $!!""JJ!3J'%!,$KMrrk3!'%!,)%"!#amC5"3I'JD&#`$!Ie!J3!-1'!!!%k!!#! iJ!!`5!!!$*b&rrmiaJ!"J'%!,(`''!""J2r`+!!!%%##!##)!3!M+!!!!%'#!"5 )!3!PR!ArrcJ!!$#F"Irr,!F!!%'#!"!i!!!YR!ArrdJ!!#b)!3!K+!!!!8##!"! i!!!VR!ArrdJ!!"3S!!!#3))!$$J!!##F"IrrI+-VH%k!!#"m#!+Q[Z(rh*!!!3! )P#(rS*!!`3#%N!$K!)L4!3#-I,JVH*%K!*!!1b!!!(mJrR"mKFTiI'!#H$Yirrp mS!0jI*iMH(ar'hKr1XYiQcX!!%##!$#!!3#3!#`!!!"!JJ!NL!%!KbJ!!!""JJ! 3L!%!L5J!!'p"JJ!-If2EH%J!!Nb)S3#*1!ArU#J!!#""J3"i1+)3D&3!%$TmT3! ZI+N$TNk!"#!lS!!!E'@!!'qMJ!"m(5!3I'-T%(aP+4"mB`$41i!!#N'#!%!MhJ! !Irm"N!!l)!!"5!!!-$ZJ!!#ES3#&1i!!#%J!!#!lS!!!Qk%!K6Z!!!T)!!!31k! !!*ZK!)8lJ!!3Iq2lH(r%mhKrTHYiIiEMH%J!&(PmPb0iIq2lH(r%mhKrTHYiIiE MH%J!%h8X&`!+I*iMH(ar'hK!J!!-1[F!-%J!!##)!3#*1[IrpLJ!!(K!JJ!-1[F !B8J!!!Jkp`""1)!!!(r$)RKri#*iI'!$HCllrrml@J!"3),rL$J!!!KrJ`*iIk! LH(aJ!hP!JJ!SL!%!KbJ!!!""JJ!FL"X!!#`!!$""JJ!31!!!-*`Errml@J!"L!% !K#J!!!*!JJ"FJ!%!M#`C!!#3!!%!N!"!JJ!3L!%!K5J!!!""JJ!3J'%!N!!i!rr rN!!"!*!!1'!!%$J!!!"rJaTiIk!#H(aJ!hP!JJ!FL!%!KbJ!!!""JJ!3J'%!N!! i!rrqN!!"!*!!J'%!N!"m'm"3I!-#&#`!!Ie!J3!-1'!!!%J!!*3iB!!`5!!!$*a lrrml@J!"J!%!N!"m'J!!3B$rm$KJ!"!i!!!!Ii-DH(qJ!RKmB!0j3))!))J"!)F S!!!!3B)!&)J"!)QF'rrr1!!!-*`ErrmX'3!!3B)!%$J!!#fF'rrr5!!!,)J"!)8 S!!!"3))!%$J!!#ZF'rrr5!!!&#J!!!*!JJ!-1!!!)*`ErrprBpYiJ!%!D$JK!'" m#!1QZZ(rh%k!!#!X"!!!3)!!*$J!!!#B!`!!X!-!!MJ!!!'B!`!%1!!!-*J$!!9 1J!!JL--!"(`%-!"-J!!JI+-L&$MP!!D-Trrr1+Ard(bJ"h3X!!!&3))!3(bM-K3 iT3!&1+Arrh`&1%"!J3!3L!8!!#`!!$""J[rXI!8i3%##!"#)"rrr9!B(rNJ!!&3 i`!!"5!!!6(`!!#C8"KIq5!!!3)`(rrpmS$)81+Ard(bJ"h3X!!!*I!!!*P3'&rp !JJ!-I+!(G8##!!`iK2rr5!!!%$J&!$#B"`!!5!!!$#`%!!"!J[r!,!B!!%'#!#5 SJ`!#1!!!!6L%!!'`J`!#Q!-!"$J!!$'B!`!&6S!!)#`%!!""J[m!Q)-!"%k!!#" m#!+Qfq(rq*2Krqb6`IrSN!!"!!L8)Iq!N!$"!+6ri!L3!*!!i3#SN3%!V(bq+hL 4)3#`J!%!X#`!!Ie!J3!-1'!!!%J!"36m)2L3!$J!!!#B!3!i1!!!),!"!$SiB3! i1-%!2%J!&E'!33!8L!%!3$[K!%&rr`)85!!!()KK!%!i!rrrQ!%!3+KK!$ii!`! "X!%!2SJ"!%!S!!!"3)%!%)`IrrmX!!!`3B,re)J"!%%X!!"*3B)!-%#!!"!X!!! `3B)!&%J!!(`X!!"13B)!@%J!!(!i!!!!Q!%!2,!"!$j)!!"Jb!)#12`I!%"!J!! F1rlrqcL#%1arirYi5!!,q@!!!!")!!!B1rlrr(rMqhJiJJ)X5!!,i@!!!!"rirY i5!!%+$[qrrarirYi1))#-%J!#m9J!!!!Iq2lH%J!"!b)B3"!U!%!2MKMrrpm!"S 8X!%!2M[qrrmi!!!!Q"m!!)J"!+NX!!"P3B)!p%#!!#JX!!"'3B)$d%#!!"!X!!" &3)!!h%J!!m!X!!")3)!$Z%J!!"3X!!"R3B)!$%#!!kK)!!))L!%!3)#"!,"m!#! !3)%!$$KK!$a,rrdjU)%!2L`%rra"J!!3J'%!X(`%'!""J!"3L!%!TbJ!!!""JJ! 8J'%!X$J$rrq3!!%!X%J!!"#)B3"!1!2rrj!!!3#`L!%!U5J!!'G!JJ!31!!!CCJ "!+P)!!"-1!!!4CJ"!+P)!!"!L!%!TbJ!!!""JJ!81!3!!A`!'!!%!X%J!!A# )!3"!1'3!!A`$!&'3!!%!X%#!!9`i!!!!N!!"!,")!!&3J'%!X)J"!%!iJ`!"I!! J!%#"!!`iB3!m5rrmIDLK!$iii!!V,!8!!%#!!!amT3$311!!,6M!!!!iJ!!+5!! !)(aP)pCmBb(@I'-S8(bP)pBi!`!`R"rrrcM'!!%X"3!!3),ri#`'!!*"J2rBR2r rriJ"!+QF(rrrJ)%!X(`Im&"m"!)8,!!"r8#"!!`iB!!!5!!#A)KK!%!i"!!"I!- !!%#!!#!i"!!#I+-!8$J!!$")!!!)R"rrrc5Prrp!J[riL+%!3$L"!%&mK#S85!! !$)`%rrqF(rrr0+Arrd##rr5!!3#`,!!!!%##!"#)!3#R+!!!!%'#!!`i!!!ZR"r rriJ"!%'F(rrrL!%!2(`!"h9"JJ!31!!!,C`Irrp)!!(-L!%!T5J!!!&!JJ!31!! !+j`Irrp)!!'d+!!!!N##!D`i!!!JR"rrrdJ!!D#S!3!qL'%!3(`!!0!iirrrI1! k&8#!!!Jii!!!J'%!X(`('!"!J3!dL!%!3(b$1&!iB3!mI)3!8%[rqa'S!3!qL'% !3(`!!0!iirrrI1!k&8#!!!Jii!!!U!%!2M5J!!&!J!!)1+!!!(`&1K3X!!(p3)% !$$KJ!!")!!%SL!%!3$L"!%&mK!)81-!!!$KJ!$")!!!-R(rrrcM'!!'!!3#`I!F !8(`'!!""J2rX1-!!!%J!!"#-"2rr1-B!!C`Irrpm"MJ!3)!!%)J"!%"m"J!!3B$ rj$J!!$")!!!-R"rrrcM'!!&m"MJ!3B$rp)!"!,!X!!!!3))!%)J"!+FS!!!!3B) !$$J!!#kF(rrr,!8!!%'#!%3i`!!!1'!!-%J!!!bFIrrr1-B!!BJ"!%"m!#K3I!B !!%'!rqa)!!!3M!6rrcM'!!'F(rrrI!BS!%'!rr")!!!-1!!!-*`Irrq)!3!mI!! (G8'#!"!i!!!YR"rrrdJ!!#b)!3#P+!!!!8##!"!i!!!VR"rrrdJ!!"3S!!!#3)) !$$J!!##F(rrrIq2lH)!"!)Ji)3#!bq(rq(`)!kD$iIrXJm(rk%k!!#"m#!+Q[U( re*!!!3!)P#(pJ(ae'hL3!+%#S(bE)hJlS!!!1q%#0dJ!"QarBpYi1)!!*8J!"m& J!!!!I(`EH#JF!!"!JJ"%If2EH%J!"bPJ!!!!I(iEHAqpmK4"JJC%If2EH(r%mhK qTUYi1+!!!8[rh19J!!!!+!-!!%##"L3iB2rr5!!')(rEi&&r[I)83B)!,(pMfhK ra20iIUDVH$LJ!!&,rpbaB!!!!#J$!!"!JJ!-1'$rrdJ!"HarQq0iIf2EH$L"!U! iS3)i5rr[kBJ"!MemHaYi,!!!D8'#!+4!J!"B,!!!@%'#!@4!J!!S,!!!48'#!L4 !J!!3,!!!*8'#!j!!5!!$S#`!!%G"JJ)-5!!$P#`!!'4"JJ"S3)!!%#`!!'0!J!0 -5!!$I#`!!'K!J!0d5!!"j#`!!(9"JJ%33)!!+#`!!'p"JJ%%3)!!%#`!!'j!J!+ i5!!$6#`!!(0"JJ)85!!$3#`!!2p"JJ-i3)!$0#`!!(K"JJ$85!!$+)J"!M`S!!! #3))!')"K!U!iB`!%N!"K!U#$3rrm5!!!0#J!!!0!JJ!FJ'%#S$KM!!L3!'%#S)- $rrb$)rri5!!!&)"K!U!iB`!%N!"K!U#$3rrmL!%#2#J!!!&!JJ!)IeS(0)J"!M` S!!!$3))!0)$"!ML!i3)mJ3%#3)%K!N4r)mYiI`6$H$LK!MK,rr5aI(FEH#JA!!" "JJ+3!%J!!#b!S3)iJ-%#2)$K!N#"!3*%Id26H$L"!MK,rr*CI(FEH#JA!!""JJ* NIpIi8%J!!U5)!3)m+!!!!N##!"L!B3+J1'-!"*!!B3+JJd2rr%J!!$3S!!!$3)) !()"K!U!iB`!)N!"K!U#$!rrmJb2rq%J!!"5!B3+J1'-!"*!!B3+JJd2rr)J"!M` S!!!"3))!#&GD"$k)!3)m+!!!!d##!$5!`3)iJ1%#2)%"!N#")3*%Ib2,H(m%`hJ iS3)i5rrcjAah'hJS&`!!3B)"a%J!!#b!S3)iJ-%#2)$K!N#"!3*%Id26H$L"!MK ,rr'0I(FEH#JA!!""JJ'BIpIi8%J!!GL)!3)m+!!!"%##!"L!B3+J1'-!#*!!B3+ Jb#2rq%J!!"5!B3+J1'-!#*!!B3+Jb#2rq)$"!ML!i3)mJ3%#3)%K!N3iS3)i5rr h5Aah'hJS&`!!3B)"2(rAq&")!!&mJ'%#S$KM!!53!'%#S),Mrr`S&`!!3))!#$V L!M5)!3)l+!!!!%'#!#b)!3)kLpF!!#J!!!!kp`!"3B)"3)!"!N4m(J!!3)%"0(` H!hK)!!%XL!%#1LJ!!!""JJ!XJm%#4(lMZhKraI0i1)!!!%[rjK&J!!!!+!-!!%' #!3"reaK35!!!q(lMZhK)!!0jB!!!!(aq'hK)!!$NJ'%#S)J"!M`iB`!%N!"K!U! X!!!#JZ2rr%'#!$4!J!!8,!!!!%'#!"K!J!!F5!!#A#`!!!4!J!*85!!!(*1h!!" )!!*)XlF!!%J!!N#6Y`!!5!!#1*1h!!4rS2j`N!!A!!")!!)SJ'%#S$VK!$JiB`! %N!"K!U#!!rrm1m!!!CJA!!")!!"J1Z%!1$J!!#@B&`!!1m!!!8J!!%arJq0i5!! #c@!!!!"mIKYjIlhb&%'#!#arJq0iIm6cH(kQUhJiS!!"5rrBL@!!!!!S!`!!3)) !$$KJrrp)!!(%Ik2VH%J!!Eb)!3)iIpccH#J!!!""JJ$i+!!!!N##!!`k`!!`5!! !#$V!!##)&`!!I!!(G#`!!#Y"JJ!-,!!!,8##!-"q`!Gd,!!!-%##!,5!G3!N+!- !!$J$rrq3!"8!*%'#!##!G3!JL*F!!$J$!!'3!"8!)*L$!!"8J`Bq5!!!')Kh!!" qT+YiI'-(G%[re'&J!!!!,!2rrd##!!`iB2rr5!!")$Vh!!%lh[rr5!!!9)"e!#3 S!`!!1!2rrj!!&3!N3B)!()#9!#"@``Bq1!3!!C!!&3!JQX3!!%J!!"4q``GdIU5 VH%[re!PJ!!!!,!2rrd##!!`iB2rr5!!!b$ZF!!'!!3*!I"`!!%'!rkJX(J!!3B) !,(lMZhKra20iIUDVH$LJ!!&,rpG0B!!!!#J$!!"!JJ!-1'$rrdJ!!)L)!3)i+!! !!%##!'Jk`!!J5!!!9)"e!#3S!`!!1!2rrj!!&3!N3B)!()#9!#"@``Bq1!3!!C! !&3!JQX3!!%J!!"3iB!!JIU5VH%[rdfPJ!!!!,!2rrd##!!`iB2rr5!!!+$ZF!!' !!3*!I"`!!%'!rkKr[H)8L"X!!(`!"h9!J[Q3!(qMkhL!!3+)1#%#J(`)!kDkSIr 86S!!)(`)!UD6iIrmNm(rq*1Krr53!!%!#*3Krh"mI4YiI*iMH(br+hKrT1Yi1'% !1$LJrrmi`!!"5!!"L@!!!!"ra20iIqAlH$KK!$K,rrN&,!-!!%'!!!`i!!!!I"d CVS!"!*Ji)3#3!(`)!kD$iIrmJm(rq)1Krr41J!!JI!J#TT!!!3!)P#(r`*!!S3" JN!$"!'53!1%!D*%"!'b4)3"`N8%!G*!!J3"FJ)%!A$LK!'",rrpCJ!%!5$JK!%" m#!1Q6S!!)$L!rrmiBrrrM!-!!6L%!!%S!!!!3),rp(b$)hK1J!!J1+6rrcM$rrq -K3!"9)!'2jb'!!&!J[rd6S!!)$M%rrmiirrr1+8!!8J!!#b-KJ!"9)!'2jb(!!& !JJ!F1!!!!%J!!!LF"`!"0+Arrd##rrK1J!!J0+Arrd##rp41J!!J1'2rre5%"Mj )!!!3I!!J3%##!!K1J!!JM!-!!93!"Mp!J[rX+!3!!%f#!#!iB!!!6S!!)$LMrrp 8K!Bq1'!!!%J!!""m!#"!3))!#(bM+hL-"3!"9!!'2d##rq`S!`!!3B)!#%k!!#! S"!!!3B)!$$KJ!!"1J!!JI+-VH%k!!#"m#!+QNq(rr*2"rrL3!!%!#*3Krm"mIKY iI)FMH(bJ+hKmhc0iJ))#3(r$mhKmj6YiI!B$H%[rc(PJ!!!!L"i!#(r$mhK6i#i dQ"i!#%[rcX9J!!!!1'!!!)!"!%Ji)3"!I!J$TS2Krrb$`Iri6S!!)$KJ!!*1J!! J1'!!!%k!!#!iB!!!6S!!)(`)!UD6iIrmNm(rq*1Krr53!!%!#*3Kr["mI4Yi,"d !!%'!!"3X(3!#3B%!$$KJ!!")!!#3!$[J!!#ci3"8Xk%!8*2K!%SiB3!i5!!*bB" "!"4mIKYiIm!(08##!%#S!3"11'%!H,!"!)kcS3#3!%J!"`@!33!8I(iEH(r!"c9 !JJ!FU!%!6T2K!)U`!3#11'%!H%J!#CQ!33!8Im!(08'#!"!iBKH`Im!(0*!!!`! !Im!(08##!!`iB!!!5!!!#$KJrrq!!3%B1#%"%(`)!kD$iIrmJm(rq)1Krr41J!! J18)KM$PJ!!!i!!!JI!N$TS!+!!JS!!!!3))!+*!!DJ!)N!#+!!b3!+S!%*!!bJ! 8N!$U!!#4#J!%I@0EH*%U!"K1J!!J1@X!!6P+!"a#!2r)1'$rrdk!!#!X!`!!6B! !)#`$!#"-J!!J('-!($L#)B`i!!!!I'3D&*!!!`!)N!!$!!b3!!-!%*!!!`!8N!! $!!#3!!-!"*!!!`!B6S!!)(`)!UD6iIrmN!!"!!L8)Ir!1q)P$%J!!##!"3!!1)$ rrj!!(`!!J'8!#)'&!!4)!!LpJ%%!&)#r!!!S"3!!3),rh)!"!%Ji)3"!I!J$TS2 Krra1J!!JI%-6H%k!!#"m#!+QN!!"!!L8)Ir!5rrrlAaT'hL!BJ&`J))"E$LL!!! i`L83J1)"B)%#!9a,rrlPB!!!!)##!I#3!'3!!%[rSiPJ!!!!1'!!!)!"!%Ji)3" !I!J$TNk!!#"m#!+QN!!"!!L8)Ir!5rrr3@!!!!#!BJ(`J'-!!%[rr[&J!!!!J!% !5$JK!%"m#!1Q6S!!)#`$!!"mB!!dI)N!0%##!!Ji#3!J,!8!!(bT!$4mbJ!d3)) !#$NU!#"m!%J!)8!!3%'"!,!j+3!")5N!3(`!5K4p+9"3I5N$TL`*!#!ikIrJ3B! !%(aS2$!ii!!!5!!!'(b)6$!Jk3!JI'Fi-(d)1hKmCd``,!!!)$%Jrq""J!!3I)0 )-$L!!!")!!!BI'-!-#%J!#"mL8``I'0,H(b%!$!j32rr-1F!!(b%)44mBaN8I3K "&(cR144m"N!3I58j%8'!!""m#!0iI5G,H$!+!!&#!2rBI)3K&(aM'441J!!J1)! !!$KJ!!"1J!!J,!-!!(aJ!$4mL3!d3))!#$J*!#!X"3!!I+N!0(c+!$4!JJ!)15S !)(`!5!!K3!"!3B%!X$NT!!%K+3"!I!"+&(dT8&"p+31Q,!N!)$MTrq""J!!3I'J m-$MJ!!")!!!BI)K--#$T!#"mCcJ`I3JlH(aR6$!X!!!J-5$ri%'!!""mJdJ`1)! !!%J!!"KmB`!`)5!!)(b*6$"mBdYiI)3!-$P!rrm`j`!!I)3K&(aM'44p#%%8I1F j&(`'3""p*6N43B!!%(`)!hKp*dYi-!S!!8)!rpKp"%0iI1-lH%k!!#"1J!!JJB) !k*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!1#3!%%!&)!-!!#!6!!%I!N$TNk!"## "JJ$%N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!,*!!33!8J!`!!)"-!!4m#31Q6S! %))'#!*!!N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!5*!!33!8J!`!!)"-!!4m#31 Q6S!%))'#!(53!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ$dN!""!"5!$!!!J%`!"(` *!kC1J!3JJB)!d*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!-b3!%%!&)!-!!#!6!! %I!N$TNk!"##"JJ!3N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!"*!!33!8J!`!!)" -!!4m#31Q6S!%))'#!-L3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ$NN!""!"5!$!! !J%`!"(`*!kC1J!3JJB)!Z*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!$53!%%!&)! -!!#!6!!%I!N$TNk!"##"JJ"!N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!$*!!33! 8J!`!!)"-!!4m#31Q6S!%))'#!#53!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!8N!" "!"5!$!!!J%`!"(`*!kC1J!3JJB)!q*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!)# 3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ#XN!""!"5!$!!!J%`!"(`*!kC1J!3JJB) !B*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!,b3!%%!&)!-!!#!6!!%I!N$TNk!"## "JJ%!N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!9*!!33!8J!`!!)"-!!4m#31Q6S! %))'#!-#3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ$8N!""!"5!$!!!J%`!"(`*!kC 1J!3JJB)!H*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!$#3!%%!&)!-!!#!6!!%I!N $TNk!"##"JJ!)N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!'*!!33!8J!`!!)"-!!4 m#31Q6S!%))'#!*L3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ$FN!""!"5!$!!!J%` !"(`*!kC1J!3JJB)!L*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!,#3!%%!&)!-!!# !6!!%I!N$TNk!"##"JJ#8N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)""*!!33!8J!` !!)"-!!4m#31Q6S!%))'#!$L3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ"SN!""!"5 !$!!!J%`!"(`*!kC1J!3JJB)!C*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!+#3!%% !&)!-!!#!6!!%I!N$TNk!"##"JJ"-N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!E*! !33!8J!`!!)"-!!4m#31Q6S!%))'#!!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ" %N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!M*!!33!8J!`!!)"-!!4m#31Q6S!%))' #!)53!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ$XN!""!"5!$!!!J%`!"(`*!kC1J!3 JJB)!r*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!!#3!%%!&)!-!!#!6!!%I!N$TNk !"##"JJ!FN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!A*!!33!8J!`!!)"-!!4m#31 Q6S!%))'#!$b3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ#FN!""!"5!$!!!J%`!"(` *!kC1J!3JJB)!+*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!,53!%%!&)!-!!#!6!! %I!N$TNk!"##"JJ#NN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!m*!!33!8J!`!!)" -!!4m#31Q6S!%))'#!(b3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!JN!""!"5!$!! !J%`!"(`*!kC1J!3JJB)!U*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!(#3!%%!&)! -!!#!6!!%I!N$TNk!"##"JJ"BN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!f*!!33! 8J!`!!)"-!!4m#31Q6S!%))!-!!#3!%%!&(`*!kD!6!!%6S!%)!!!!"b!!!"N#!# 3"TL!!!#N'!#3"3%mJ!!!G"!!N!8"X)!!!-!B!*!&!R#!!!$S+!#3"30BJ!!!k!J !N!8%3)!!!3`3!*!&"8b!!!"S!*!'"E5!!!#8%!#3"3C)J!!!2!J!N!8'K)!!!$` !N!B'`)!!!'33!*!&"b5!!!%8'!#3"3JiJ!!!`"!!N!8)q)!!!33S!*!&#JL!!!" B%!#3"3TJJ!!"C#!!N!8,a)!!!-33!*!&$)L!!!%F'!#3"3fNJ!!!I!J!N!81))! !!)`)!*!&$V#!!!#d#!#3"3pNJ!!!G!J!N!83*)!!!'`)!*!&%*!!J!!"C$!!N!8 4p)!!!&J)!*!&%Nb!!!'!3!#3"42-J!!"1$!!N!89")!!!P4S!*!&&eL!!!%i+!# 3"4L3!)!!!&3!N!BBj)!!!&`!N!BC3)!!!(!!N!BCX)!!!(!!N!BD))!!!9!J!*! &'h#!!!#)!*!''rL!!!(!'!#3"4fiJ!!"!!J!N!8HZ)!!!*33!*!&(db!!!#B%!# 3"4rNJ!!$@%!!N!8MF)!!!%!)!*!&)l#!!!#8+!#3"54%J!!!9"!!N!8NQ)!!!,! J!*!&*8L!!!"%!*!'@q#!!!"8#!#3"9`mJ!!!@!#3"Pb8J!!!0!#3$B)+)K2dJJ) A&(JAX"4m&)J#i!,S![!#X!,!!XJ#Z!2i!SJ8J!+3!"5%!Y!#f!h3*3aR+'6F*4! %)QFS"L)4r))#(a(d!I`3m3*)%Z!#!!*3![d5H!,i%K!8@"3i&"J6q!-$!PJ$dJ2 *!hi$B!0-!Q!AY"$X%'J2j!l3$k!KM!*%(L%r&b0*EQB")djK6JdL(F!))JS)KJ) 8#I`4p"SJ(q3P5#5B*B`PS#H`,VJZ3#fi0k!eP$6N0""#"%(J@QKDB#*D@!3J-`3 Z59"3"@K[Fh4c*h0[BfYPG&pPGQ9ZG&pSB@jNE'9b1L"cEf0VCA3JEQpd)'PZ)(9 cC3%MU[i(#b,Ap3%K!3%K"!)L!QJ))$%69'9cG&4bB@0V)&9cCA)J5@jQEd9bFQp b)#9N)%GPG(4TEQFJ8hPc)%9ZGQPbEfjc!5"+4@jf9Q9b)#9N)'eKBfK8HA"P)#9 N)(0jFeCPFL!PC#"`FQpM)#9N)%C395!PC#"$Efa[FP&%)#9N)'YLC#!PC#"KG&C PFR-J*@3"+#9c1L9c1L9c!590B@028`%MU[i($#%P!5%"!5%%!L)#J!`K#a8L&,! #)3%$)K5`&L)#U!)L!U!#)J+B##%6&5)9X!)K!3-L&E!@)J+S!L)#S!)L!TJ))4% 9)KD`!L%"!b)@X"BL!UJ#)J+J!L)#Q!#5"##"I`'3#3+3"3'3%J3)N!m`N!S)N!H JN!D!N"3)N!CJN!C!N"3)N!3"J*!(3*!C#*!(3!L3"S#!#*!13%!)N!Z!N!4!#*! )3)!)N!4!3!L3"B#3#`L!N!3)N!S$)N8JJJ+""8A343a&d%A34G"&d%A34G"&d%A 34G"&d%A34G"&d%A34G"&d%6)4G"&d%A34G"&d%A34G"&d%A34G"&I%6)45"&)%8 -4G"%b%A34G"&d%A34EK%b%9B4G"&d%@J4G"%b%A34G"%b%,)3`"$!%,J3`"$!%- !3`"$!%-!3`"#`%-!3V4$!%-!3ZK'Y%E!4X"'`%E!4X"'`%E!4X"'`%E!4X"'I%E !4X"'`%E!4Ra'`%E!4X"'`%E!4T4'`%E!4X"'`%E!4U4'`%E!4V4*)%NX55a*,%N X55a*,%NX55a*,%NX55a)c%NX55a*,%NX5-a*,%NX55a*,%NX53"*,%NX55a*,%N X54"*,%NX*NNJ,8PZCJ'j&J!!!3!!!!(p!!!!r3!!!&S!N2-4GQ9bFfP[ER-ZE@P d,Q9NG3#3"%J!3B!!!!!&-#id,M%l-#id,M%X)%0[F(PbD@GSG#!a16Nh)%eKFh0 KBfKeFf9dG(-J5@jcG'PdGA4P)'pQ)&4PBfKZEfa[ChN!!!#B!*!,!3#3%`*Y0MK V!*!6!3#3"PES!*!*2"&0594IT94PFh48FQ&MDdaTBR"hF'-!N"-"!!"@m!!!F8d !N!Nm%8e*9&qP9'9cG&4bB@0V6'PL!!!"!!!!!Id!!!$p!!!!@JG,jj!!64i!!!! F!&S!!N069&)!!!!DGQ9bF`!!!#CMCR*R!!!!-J4-rrm!N!N"rrm!!!!9!*!'rrm !!!"K"e'ZQ+%S: \ No newline at end of file diff --git a/src/mac/TestTrack/ShlibTestTrack.c b/src/mac/TestTrack/ShlibTestTrack.c deleted file mode 100644 index 01c69f69b..000000000 --- a/src/mac/TestTrack/ShlibTestTrack.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 1997 by the Massachusetts Institute of Technology - * All rights reserved. - * - * For copying and distribution information, please see the file - * COPYRIGHT. - */ - -short MacOSErr; - -#include -#include -/* sarac 02/19/98, added Sound.h for SysBeep() */ -#include - -#include "TestTrackLib.h" - -#define TBALERTID 135 -#define TB30ALERTID 136 - -struct VersionResourceRecord { - Byte majorRev; /* Major revision in BCD*/ - Byte minorRev; /* Minor vevision in BCD*/ - Byte releaseStage; - Byte nonReleaseRev; /* Non-final release # */ - short countryCode; /* Region code */ - Str255 shortVersNumStr; /* Short version number */ - Str255 longVersNumStr; /* Long version number */ -}; - -typedef struct VersionResourceRecord VersionResourceRecord, *VersionResourcePtr, **VersionResourceHandle; - -OSErr ShlibTestTrack(CFragInitBlockPtr ibp); - -OSErr ShlibTestTrack(CFragInitBlockPtr ibp) -{ - OSErr err = noErr; - short fileRefNum, saveRes, processResFile; - ProcessSerialNumber thePSN; - ProcessInfoRec thePIR; - FSSpec currAppSpec; - VersionResourceHandle versResource; - char versionString[256]; - char processSignature[5]; - short len, i; - - if ( (Ptr) test_track != (Ptr) kUnresolvedCFragSymbolAddress ) { - /* Start our hack by saving the current resource ref*/ - - saveRes = CurResFile(); - -/* if (ibp->fragLocator.where == kDataForkCFragLocator) - { - fileRefNum = FSpOpenResFile(ibp->fragLocator.u.onDisk.fileSpec, fsRdPerm); - - if ( fileRefNum == -1 ) - err = ResError(); - }*/ - - /* We assume that the current process is the one calling us. Good bet */ - err = GetCurrentProcess( &thePSN ); - - if ( err == noErr ) - { - /* fill in required fields for the ProcessInfoRec */ - thePIR.processInfoLength = sizeof(ProcessInfoRec); - thePIR.processName = nil; - thePIR.processAppSpec = &currAppSpec; - - GetProcessInformation( &thePSN, &thePIR ); - - /* copy the processSignature into a string */ - BlockMoveData (&(thePIR.processSignature),&processSignature,sizeof(OSType)); - processSignature[4] = '\0'; - -/* processResFile = FSpOpenResFile(&currAppSpec, fsRdPerm); - err = ResError();*/ - - if (err == noErr) - { - versResource = (VersionResourceHandle)GetResource('vers',1); - - if (versResource != nil) - { - /* Make a local C-string copy of the short version number string (a Pascall string) */ - HLock((Handle)versResource); - len = ((**versResource).shortVersNumStr)[0]; - for (i = 1; i <= len; i++) - versionString[i-1] = ((**versResource).shortVersNumStr)[i]; - versionString[len] = '\0'; - HUnlock((Handle)versResource); - - ReleaseResource((Handle)versResource); - } - } - - if ( thePIR.processType == 'APPL' ) - { - if (test_track(processSignature, versionString, true, true, 0) == -1) { - SysBeep(10); - SysBeep(10); - - ExitToShell(); - } - } - } - /*if ( fileRefNum != -1 ) - CloseResFile( fileRefNum );*/ - - UseResFile( saveRes ); - - } - - return err; -} diff --git a/src/mac/TestTrack/ShlibTestTrack.h b/src/mac/TestTrack/ShlibTestTrack.h deleted file mode 100644 index 12e656b1a..000000000 --- a/src/mac/TestTrack/ShlibTestTrack.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1997 by the Massachusetts Institute of Technology - * All rights reserved. - * - * For copying and distribution information, please see the file - * COPYRIGHT. - */ - -#ifndef __SHLIB_TESTTRACK__ -#define __SHLIB_TESTTRACK__ - -#include - -/* Special version of TestTrack for shared libraries -- uses calling application's - version information */ - -OSErr ShlibTestTrack(CFragInitBlockPtr ibp); - -#endif /* __SHLIB_TESTTRACK__ */ \ No newline at end of file diff --git a/src/mac/TestTrack/TestTrackLib.h b/src/mac/TestTrack/TestTrackLib.h deleted file mode 100644 index b005b1c09..000000000 --- a/src/mac/TestTrack/TestTrackLib.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1992 by the Massachusetts Institute of Technology - * All rights reserved. - * - * For copying and distribution information, please see the file - * COPYRIGHT. - */ -/* - * Function prototypes for testtrack routines - shared library version - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if GENERATINGCFM - -#define InitializeMacAthenaLib() -#define TerminateMacAthenaLib() - - #if defined(__CFM68K__) - #pragma import on - - extern int test_track(char *appl_name, char *appl_vers, Boolean edit_flag, - Boolean do_logging, int check_probability); - extern short GetBSDMacOSError( void ); - - #pragma import reset - #else - - int test_track(char *appl_name, char *appl_vers, Boolean edit_flag, - Boolean do_logging, int check_probability); - short GetBSDMacOSError( void ); - - #endif /* endif __CFM68K__ */ - -#else /* else GENERATINGCFM */ - - typedef int (*test_trackProcPtr) (char *appl_name, char *appl_vers, Boolean edit_flag, - Boolean do_logging, int check_probability); - typedef short (*GetBSDMacOSErrorProcPtr) (void); - - extern test_trackProcPtr gtest_trackGlue; - extern GetBSDMacOSErrorProcPtr gGetBSDMacOSErrorGlue; - - #define test_track(appl_name, appl_vers, edit_flag, do_logging, check_probability)\ - ((gtest_trackGlue)(appl_name, appl_vers, edit_flag, do_logging, check_probability)) - #define GetBSDMacOSError()\ - ((gGetBSDMacOSErrorGlue)()) - - OSErr InializeMacAthenaLib (void); - OSErr TerminateMacAthenaLib (void); - -#endif /* endif GENERATINGCFM */ - - -#ifdef __cplusplus -} -#endif diff --git a/src/mac/TestTrack/testtrack.h b/src/mac/TestTrack/testtrack.h deleted file mode 100644 index 167340b66..000000000 --- a/src/mac/TestTrack/testtrack.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 1992 by the Massachusetts Institute of Technology - * All rights reserved. - * - * For copying and distribution information, please see the file - * COPYRIGHT. - */ -/* - * Function prototypes for testtrack routines - */ - - -OSErr tt_open_MacTCP(short *drvrRefNum); /* Pass NULL if you feel like it*/ - - -/* function prototypes from tt.c */ -void tt_acknowledge(char *control, ...); -void tt_fatal_error(char *control, ...); -void tt_ensure(OSErr errcode, char *message); -int tt_edit_user_info(struct tt_user_info **user); -void tt_install_callback (int (*callback)(struct v_pkt *)); -int test_track(char *appl_name, char *appl_vers, Boolean edit_flag, - Boolean do_logging, int check_probability); - - -/* function prototypes from vlib.c */ -void v_parse_pkt (struct v_pkt *pkt, struct v_info *info); -int v_read_pkt (int sock, struct v_pkt *pkt, struct v_info *info, - struct sockaddr *sa, int *sockaddr_len); -int v_assemble_pkt (struct v_pkt *pkt, struct v_info *info); diff --git a/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.68K b/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.68K deleted file mode 100644 index c87625249..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.68K +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :&%0$B@0SC8GXEf*KE(0-D@)Z0MK,!(0SE')rN!3!N!3"#J!!!CBl&%T[H5&`C@C QE6BiD`!!!!'b#cB`!*!0!`!#!*!EP!!"!J#3"!8!N!G)!!!!5!!!!!m!!!#8!J% #!*!%$J#3$fB!!!#N"!%#!%eKD@i!*8%e9fpbE'3!6'pKC'9b!*!&+L)r2!%M"UR `!L,rr443rj!%!*!%rj!%!*!%rj!%!*!2!3!!!%3!!!"%!!!!8!!!!!%!!!!"!!% !N!TR3fjdFQa#E'pMD`!!"!#3"3%!#eP3!3#3"J3!!Ble!!!"!!!!!@3!!!"N!!! !-J#31'!!!!""F("X!*"!B!!!!%e06%)!N#"-D@)J5@e`Eh*d)&"33`#3&Ne36%B !N#0J!*!,!3#3%`&Y0MKV!*!6!3#3%8!968P8Ak9$3f&MD'9(E'pLB@ac6'PL!!! "!!!!!@3!!!"N!!!!-J9@1G!cb!!!!"`!-J!!BfCbC`!!!!S!!2rr!*!)q0d: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.PPC b/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.PPC deleted file mode 100644 index 67940ed6e..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheGlobalsLib.PPC +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :&%0$B@0SC8GXEf*KE(0-D@)Z8&"$!(0SE')rN!3!N!A`!!!"PU")5Qpj)A"PCQC `Gh"M!!!!!E*6cT3!N!d$!!)!N!6rN!3!N"2`!!3%!2q3"!#3"`J!N![`!J3%!2q 3"!#3$fB!!!#!"!3%!*!&rj!%!*!%rj!%!*!%rj!%!*!2!3!!!%3!!!"%!!!!8!! !!!%!!!!"!!%!N!TR3fjdFQa#E'pMD`!!"!#3"3%!#eP3!3#3#!%!N!T+,`!!!3! !!!&N!!!!C!!!!$)!N%`3!!!!,`)!!!!#!!!6!!F"!!%!N"!(!3!"!*!3!3%!N!S (!3!"!3!"!3!!!!%!!!d!!3#3"4&KER0TAh"bC@CTH#jYB@-ZD!#3%!%"!!!!!3! !!!%!N!3"!*!&"3'3"`#3"J%!!!P0CA*R!!!!B!#3#`%!N"-"F(G`B`#3%`%!N"& !&8e*9&qP3d0KBfKP4fa[BQ&XFdaTBJ!!!3!!!!&N!!!!C!!!!$)&9MR30#B!!!! F!$)!!'0QFQF!!!!+!!$rr`#3"!9EF&$%G`: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/bin/CCacheLib.68K b/src/mac/libraries/CCache API/bin/CCacheLib.68K deleted file mode 100644 index ba927ec34..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheLib.68K +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :$80$B@0SC8aTBLif1%X!FfKXBN0"*%J"!!!!(ei!!!'5RAj+EhNKF'9QCQdf1'X !!!!"XJXf03#3$3-!!J#3$KM+!!!BbJ!!'-S!!!#8!!%#!*!%"3#3"J*i!!!#H!! !!D-!!"PJ!J%#!*!%$J#3$J4D!!!E"!3"!J"0B@PZ!#9"09G[FQaN!%a[B@4PFJ# 3"#T451FB1#4[!"JS,`!F*Lm!)#K[!#3JEIpi*P!J#fBb5(J!%'(r!!!-1#5!*P) J#fB%F!CJ2N+V!!3J8N+3!#"53UJ!##"53UJ!$#"YrhJJNQ!#*)Y`!EL!E`4`#@! @5S0R"L"$F!%JJ#!-C`BJEIrm+*!!F!"-ha`B6R3!%#T451F!-#4[!!`J#QFB*P) J#fF5,`YKr`!!&L![%Q(r!!!+Z'!%F!TJ"%+5F!"-h``!6R3!"#T451FH1#C[!#! Q,`!N,#m!+#K[!#`U,`!`+#m!0#!,CJC`#Q!!!0C+K'B'F!aJ!!$-5(J#*Q(r!!! ,G#4!)!TQ"R!'B!!!YNU$Ca)J3h$r8S"+''Ek$)!!!!$rC3C`!@!!!*SJ5L*$)!J 3f@Em)!aR%L"-F2p5J%SBC[S-J!!!!2pP"(!-B(4"kJ%%)N`J#"$CC[`P43)-3QS #"#9'!3!9I!!#!K"`C#9!!K)[#Q(r!!!,1L9!!JK+UJ))CJ4`"Q!k5UX!#'B33US #)N+U!KiQLLG+!!4J&L"V!!3K5J)H*@X!"!)L3US#(LG+!!45U`!)8UX!$#"%))T `!%cI((K1G!!B+P&19[ri51FH2#SZ!!JSEJ!-+#i!%#CZ!"Kf!%U&CJC`#Q!!!*S J#fB'F!aJ!!#3!#!-CN`JEIq),""`!Eb!CKj`!5m!5(J!UbmYrr3[,Iri)QhrM#" C6T!!+Qlrp'!LF!5mJ'BFF!%[!%Ki!+X[,Ird,bhrq#*Yri`J@8k3!#TZrr3J454 3B#)[#Lm-)QhrJ#"C6T!!+Qlrp%U!CJUiUJ%!CJ4f!@!%*'S#(L!+C`4+!fI@5J0 R"LD+F!"J"%+6F!T-haai6Pj1G!!8+P&19[ri51F32#KZ!!JNEJ!-)!aQ"(!+B(` J#QB%F!aJG%U5CN`JEIq)*K"`!ED!CKj`!5m!5(J!c5mYrr3[,Ir`)QhrM#"C6T! !+Qlrp'!LF!5fJ'BFF!%[!%Ki!-d[,Ird,bhrm#*Yri`J@8k3!#TZrr3Q8J`V!!% #%'F%F!jJ&Lm,,`aKr`!!%&3[#f(r!!!)5%+5F!"-ha`)6Pj1G!!)+P&19[ri51F B2#CZ!!JSEJ!-)!YQ"R!+B!!!hL!-CJC`$'!!!04+P'C-)'hrL#B3F!'fJ'BHF!% [!%Ki!1X[,Ird,bhrm#*Yri`J@8k3!#TZrr4J)R!%YS"Q((!",`")H!$V,bhrp#m Yrr!LEIq-)&P1N!!UE[rd*&4`C,#U!K*R%#m+BIm!!"155J"Q"(!)B'K+UJ)LCK! QUJ)H*LS#(QF')%0#U!)L5US#(QB5*fS#)J!%*LS#)QF')%0#U!)H+#S#)QF@*LS #(QF3)%-K4!)L)'S#)L&U!Ki#(K9m!!%#%#m-,`XLEIrX)&P1N!!UE[rd*J"5U`! -)!0-ha`B6Pj1G!!)+P%LE`!%)'m!##!*CJ4`#Q!1)!KR###T!!a`!'!#F!a1G!! )+P&)ja!`*Qm!%#4[!"3J#fB%F!TJ5#!+CJ4`#Q"!*LS#%R"NYS"R&R"QYS"Q$#m +BIm!!"+q5J"Q"(!)B#![,`!F,bm!(#m+BIm!!!dJ*J"+JfB%8UX!#&+V!!`J!dc I$!K1G!!3+P&)ja!`*Qm!%#4[!"3J#fF%)!TQ"(!+B$BQ+J)5F'5fJ'F@F'DfJ'B -,`TKr`!!%Pa+!'B%F!KJ&Lm[!"`[,`!F,`TKr`!!$E*5U`!-F!"-h``)6R3!%#T 46PErq%MR'$`QEJ!)*'i!$#JZ!"!SEJ!8)!YR"#!+CJC`#Q!!!*JJ$'C-)'hrL#B 3F!'fJ'BHF!%[!%Ki!@X[,Ird,bhrj#*Yri`J@8k3!#TZrr4J)R!%YS"Q((!",`" )H!&V,bhrp#mYrq3LEIq-)&P1N!!UE[rd*LS#%R"NYS"R&R"QYS"Q$#m+BIm!!"' Q5J"Q"(!)B#DiUJ%!C`4`#Q!F5(J!rbm-5'S""#*Yrh`J@8k3!#TZrr45U`!-F!" -ha`B6Pj1G!!3+P&)j`!i*'m!&#C[!"JJ#QB%F!TJ3("QX+S#%QB3,`TKr`!!%8K +!'B%F!KJ+#!,Cb*)H!$rBIm!!!88*S!S8b!-CJ4`"Q!1)%a$kJ%%)!J3f@EmF!" -ha`!6R3!$#T451F!-#4[!"!QE`!8)!TQ"(!+B#C`CV#U!K*Q%#m+BIm!!"$U5J" Q"(!)B!iJ#fB%F!CJ"LDU!3"`!%cI$!"1G!!-+P&)j`!`*'m!%#C[!"3J#QB%F!T J0("QX+S#%QB3,`TKr`!!%+C+!'B%F!KJ(#!,CaC)H!$rBIm!!!4b*S!J8b*+)!J 3f@EmF!"-h``!6R3!$#T451FB1#J[!"JSE`!F*'m!)#!-C`JJ#QF%5S4Q"(!+B%K +NQBD5(J!#'(r!!!%,#5!*K*Q"(!'B$!J4#*$)T!!)&)Q%'B3,a*Kr`!!"%a#NN+ 8F!0J&#m-,`0Kr`!!$GSQ8L"6*UJ#(R!!60mF'%jd!!`U88MR($K46bB[!#3QE`! S+'m!,#4[!$!J#fF))!TR"%U$CJC`#Q!!!6`J$'B'F!CJ!!%bF'D`U`)5CK)[#f( r!!!2a%S!CJC`#'!!!4K+NQBN5(J!#'(r!!!$ML5!*K*Q"R!'B!!!rL"$3UJ!"'! ')%05U!!%1LX#"$!&5-!Q%L"$+#J!",L!E")J"1@))'X###"`#!"`Bl#3!'I8-!9 )`,L!E4)[%Q(r!!!$I%+83T*`!f!!!,!J"1@))'X###S`#!!J45B3F!'fJ'CS5(J !#'(r!!!$&#L!5T4Q"R!'B!!!K%Ki(AjKr`!!![iJ9#&!!!3J9#BS!!4Q"(!'B'B J8L!S!!6PL#"V!JJJF!J!)'J!"#*$)$`!!"eqFL#`J@8%SLjJ$NU!C`SL#4,B8i" QqL*"B#K`!VD!CK`[D!!%!!4`!Lk!,``[,`!),bm!#'(r!!!(KQ!'3T4`%'!))&* 5U!!%F!"36dcI($K1G!!3+P&19[ri51FB2#KZ!!JNEJ!-H!!J$'B'F!TJ!!#F)!T Q"R!'B!!!NL!X!!K5J1@),`!LEIqX)&P1N!!UE[rd*)"+NQB%F!CJF#C8B'K)H!) #)QhrV#"C6T!!+Qlrp#"5)B!i!#K55V3i!'B%F!CJ5L"d1!!L5b!)%0PQr#"5)(! i!%(S!2p$k`%%)!J3f@Em)&)JF$J!)@X"!!(q*QX#(P+%@)-J#fDQ)!6PL#"53V! )!(!!B!4f!'$U60mF'%jH6R3!##T4,`SNE`!-)!TQ"(!'B!S[#Q(r!!!"i(!!*&p 1G!!)+P%[#L4[!!`J#QB%F!CJ#Lm+BIm!!!(!F!!NAdjd!!JU85m+*'m!$#!+CJ4 `#Q!8,a*Kr`!!$MJ[%Q(r!!!"Q%+5F!!NAdjd!!JU88j@rrK)jaJd*'i!$#!+CJ4 `#Q!iH!"J-#mc1!!LEIqF)&P1N!!UE[rd8S4BJbC55V-i!'EN,a)LEIqF)&P1N!! UE[rd3T*`!'!%GJ"Ji%cI$"K1ANjd!!JU88j@rqa)ja!N*'i!$#BZ!"!J#QB'F!a J!!$15'lrm#*YrkJJ@8k3!#TZrqK`C,#U!K*R'%KZrqp)DJ)@5'lrm#*Yrk3J@8k 3!#TZrqJJ!e1!C`a6J'F58i"R0Q!!!)C`C#9!!K*J!!#!*LS#%R"NYS"Q&("P*8! #%L9Zrr!#&L9Zrr3#'Q"JF'DfJ'CDF!KJ@#BU!K*`C,D!CK4`CL9!!K)PE[r`!KB PE[rd!KTJ1("QYS"Q#NSZrqpQ"(!)B#T`CED!CL*+,[r[Ca4`CL9!!K)PE[r`!KB PE[rd!KTJ#(!)B!C`$'!#F!"-h`3)6Pj1G!!-+P&19[ri51F3*#BZ!!J[!b*Yrk` J@8k3!#TZrr3N3#!+Ca![!bm+)QhrQ#"C6T!!+Qlrp#!+60m%#%jH6R3!"#T46PE rq%MR'#3NEJ!),`SLEIqJ)&P1N!!UE[rd*J!J#QC-)'hrL#J3F!'iJ'BHF!%[!%K i!#F[,IrB,bhrh#*Yri`J@8k3!#TZrr4J)R!%Z)"Q((!",`")H!!R,bhrf#mYrp` LEIq-)&P1N!!UE[rd5S0Z6#"YriJS%(!"Z)"Q(R!",`")H!!S,bhrf#mYrp3LEIq -)&P1N!!UE[rdB#*`",L!CKa`!5m!5(J!+#mYrpJ[,Ir8)QhrM#"C6T!!+Qlrp#m $3UF[#L*Yri3J@8k3!#TZrr3[!d+R,`SLEIq%)&P1N!!UE[rd,`-[#L*Yrj3J@8k 3!#TZrr3[#L*Yrj`J@8k3!#TZrr4-h`3B6Pj1G!!%+P&19[ri51F3*#BZ!!J[!b* Yrj!!)&P1N!!UE[rd*%!J#QF3,`-[#L*YrjJJ@8k3!#TZrr3J#NcI"!K1ANjd!!3 U88j@rrK)ja!N*'i!##!+CN`JEIq)*K"`!ED!CKj`!5m!5(J!8#mYrpJ[,Ir3)Qh rM#"C6T!!+Qlrp'!LF!5fJ'BFF!%[!%Ki!&![,IrB,bhrd#*Yri`J@8k3!#TZrr4 #DJ)%0A`!#J)'5(J!+'(rN!4@*8!###!U!JK-h`3)6Pj1G!!%+P&19[ri51F30#4 Z!!JJ#QC-)'hrL#B3F!'fJ'BHF!%[!%Ki!&i[,IrB,bhrc#*Yri`J@8k3!#TZrr4 J)R!%YS"Q((!",`")H!"H,bhrf#mYrm`LEIq-)&P1N!!UE[rd*+i!$#9Z!"!!"%U Z!"4Q#%+U!!K`!'!q,bi!%'(rrrrqa#9!!!JQDJ!))!YQ"(!'B#3L5b"Z!"3J,J! 3FL#`J@8%SLjJ$NU!C`SL#4,B8i"QqL*"F!"-h``)6Pj1G!!3+P&19[ri51FH2#K Z!!JNEJ!-H!!J#QC-)'hrL#S3F!'kJ'BHF!%[!%Ki!(3[,IrB,bhrb#*Yri`J@8k 3!#TZrr4J)R!%ZS"Q((!",`")H!"d,bhrf#mYrmJLEIq-)&P1N!!UE[rd*N`J$'B )3T*J!!'`8S4+QfEk)!45J1@),`"KrrrrrJ)NJ#S!5S9Q6#"YriJX%(!"[)"Q(R! ",`")H!"m,bhrf#mYrm3LEIq-)&P1N!!UE[rdB#*`",b!CKa`!5m!5(J!I#mYrpJ [,Ir%)QhrM#"C6T!!+Qlrp%U&C`!"3LC-B!!"+NKi!!aKrrrrrCJJ8L#!)&*+N!" Q6#"YriJX%(!"[)"Q(R!",`")H!#$,bhrf#mYrm!LEIq-)&P1N!!UE[rdB#*`",b !CKa`!5m!5(J!JbmYrpJ[,Ir!)QhrM#"C6T!!+Qlrp#"5,""R!!$8)NBJ9(!-FL# `J@8%SLjJ$NU!C`SL#4,B8i"QqL*")&)J8#mS!!4Krrrrr3iJ8L"3)8!!##"5)&" +U!!)CN`JEIq),""`!Eb!CKj`!5m!5(J!LbmYrpJ[,Iqm)QhrM#"C6T!!+Qlrp'! LF!5mJ'BFF!%[!%Ki!)X[,IrB,bhr[#*Yri`J@8k3!#TZrr3J8L"3,#J!#'Fq*K3 J3b!S!!3L4L"$)'J!#()JX)&P"+)ZB!j+J'F+)JN5f&1!C[SL39L+@)Y+NfB!rY3 J"1@))%9#X!J!*)9-haai6Pj1G!!)+P&19[ri51F!2#KZ!"!QEJ!-)!aQ"R!'B!! "%%Ki!!KKrrrrr$JSJ%U8CJC`"Q!!!2T)H!"-BIrrrr`L*%!J#QB'F!CJ!!$N5(J %iQ(rrrrm$#5!5T*Q"R!'B!!!cNKi"1*KrrrrqrBP3!!%5US!"'B'F!CJ!!#d5(J %hbm6,a)LEIpm)&P1N!!UE[rd5(J%hbmV!!3[+J!%)QhrI#"C6T!!+Qlrp#mV!"! [+`!-,bX!#%KU!!KKrrrrr'BPD`!8!"3PD`!B!"JPD`!F!"`PD`!J!#!PD`!N!#3 PD`!S!#K)DJ!X,bX!,'(rrrrmmLmV!$J[+`!d,bX!-%KU!$"Krrrrr"i[+`"%,bX !3#mV!$a)DJ!mBIrrrr`)3US!5#"8F!)JJ#"8)8S!"(!!60mF!%jH6R3!$#T451F !-#4[!"3J#QB%F!CJ@NKi!!KKrrrrq`iNJ#C5)!YQ"(!'B%4`!5D!5(JGIQ(rrrr kp#C!)!YQ"(!'B#`L5b"[!"!J2!!!(Ajb),#"C35L,Q!15S"R#L)*%YK6J'Ek)N% J8L&,!!4`!%cI$!"1G!!-+P&)j`!`@8mNE`!33TFJ#QB'F!TJ!!$8F!'`V`!8C`j `!V#[!"4R"R!3B!!![P*U!J3`+J)%X'S#"QCL-#S#"Y"!08!#"M!U!JC)`1@),`" KrrrrqQ!Q3#!,CJC`"Q!!!)S`+J)'5-"-I!J!N!3#jBJL5b"U!JKb),#"C35L,Q! 15S"R#L)*%YK6J'Ek)N%[+J))BIrrrrN5*8X##(!"X+m!&'B55&F[,`!F,bm!('( rrrrqh'!HF!+`V`!8CK*)9bm[!"`[,`!FBIrrrrf1B!4`%'!8-#S#"%M!8i$PL#" U!JJKP`J!F!"B6dcI$!"1G!!-+P&)ja`i*'m!(#!+CJC`#Q!!!*af!'!!!*)[,`! N,bm!*#"U!JJJF%J!,bJ!"#mS!!"Kr`!!!6a+!'G8)!2PL#"U!JJSF!J!,`aKr`! !"3![$'(rrrriB#J$B%JQDJ)))!45J1@)*l-)!&J!8S4BK6!U!J4)`&1!*J#iJ'h H)!2PL#"U!JK#X!J!8fS#"'!38S0BK$!U!J4)`,D!E3$rI(!!B!SU!q@0B-Ci!'$ Q60mF1%jd!!`U88j@rr4)jaJd*Qi!##4Z!!a#V[rd)!TQ6#"YriJQ%(!"YS"Q(R! ",`")H!&),bhrf#mYrlJLEIq-)&P1N!!UE[r`B#*`",D!CKa`!5m!5(J"5#mYrpJ [,Iqi)QhrM#"C6T!!+Qlrm#!+CJ4`$'"!H!"J1#"U!JJYF$J!rr4)E[rd,`XLEIr J)&P1N!!UE[r`8S4BJc!U!J4)`,L!EGB[+J))BIrrrrGFF!"J"(B!B14-h``B6Pj 1G!!)+P&19[ri51F!0#4Z!!`J#QF)*Qi!&#!,CJC`!'!!!,`J,J!)X+i!%'F'F!" J!!#XF!'`VJ!)CPT)D`!"5'S!!5*Yri!J@8k3!#TZrr4+J'Bq5'X%idKU"1-LEIq !)&P1N!!UE[rd5S"Q*NKV%iP)DK1*)QhrJ#"C6T!!+Qlrp%U!CJiJ+KKmX+XBI'B %F!&J6(!!B%K`!V#Z!!KQ2Lm6,a)LEIq!)&P1N!!UE[rd5S"Q*LmV!!3[+J!%)Qh rJ#"C6T!!+Qlrp%U!CJiJ+J!BX+X!''B%F!&J"R!!B!*`!%cI$!"1ANjd!"!U88M R($JQE`!F+'m!)#!-CJC`"Q!!!@j)H!)QBIrrrrB'+)!N9#!+CJC`"Q!!!9BJ5L* ,)!J3f@Em*@X"!!%!3HS""%2V!33J#"$CC[`eD`)%!J3eD`)'!JB9I!!"!K!`+J) '5-$PL#m!BIrrrr@i*8!##%UU!JKQ"R!'B!!""RJ!B!!!r#"V!JJSF$J!+K4`!EU !CJ!!K%Ki!!KKrrrrpBBJDJ)))B!i!#"U!JJSF$J!)!aQ"R!'B!!!bR!"+)")H"e qBIrrrr9H)'S###"`1!!K3!!%)'S###"`1!!SD!!%)!aQ"R!'B!!!QL*-)'X###" `1!!JD!!%)$`!!"eqFL#`J@8%SLjJ$NU!C`SL#4,B8i"QqL*"B%T`!VU!CKJJDJ) )5(!i!#mX!!3[,!!!BIrrrrRLB#a`BlU!CLC)H!!)BIrrrr6J)'S###'!1!!JDJ) )+(!i!#!-CJ4`"Q!NF'-SJ&+%@)-`+J)%5-#iJ'd!ra4#UJ)L3US#(R!!B!4f!'$ N60mF1%jd!!JU88MR!$JSE`!3*%`J$'B1B"S[+`!)BIrrrr5q@)SQ8L!,CZi[$'( rrrrdVNcI(!"1G!!%+P&19[ri51F3*#4Z!!JJ#QCH)'hrL#B3F!'fJ'BHF!%[!%K i!F)[,IrB,bhrY#*Yri`J@8k3!#TZrr4J0(!%YS"Q,R!",`")H!(#,bhrf#mYrl3 LEIq-)&P1N!!UE[rdB"![#Lm+)Qhrk#"C6T!!+Qlrp%U5CZa`!%cI"!K1ANjd!!3 U88j@rqa)ja!N*'i!##!+CN`JEIq)*K"`!ED!CKj`!5m!5(J"dLmYrpJ[,Ir3)Qh rM#"C6T!!+Qlrk'!LF!5fJ'BFF!%[!%Ki!G)[,IrB,bhrd#*Yri`J@8k3!#TZrqK )E[rZ)QhrU#"C6T!!+Qlrk$B!-!0)`'F%F!"J0("NX+S#%QFN5'lrpdKU!KC)E[r Z)QhrT#"C6T!!+Qlrk$B!-!0)`'F)F!"J#%)ZrrF3,[rh60m%#%jH6R3!"#T46PE rq%MR%$`QEJ!))!YQ6#"YriJQ%(!"YS"Q(R!",`")H!(R,bhrf#mYrl!LEIq-)&P 1N!!UE[rdB#*`",D!CKa`!5m!5(J"jbmYrpJ[,Iq`)QhrM#"C6T!!+Qlrp(!#X*0 QCL4V!!3[%Q(rrrrbrLmU!!4Krrrrm[4+UJ!3C`S[+J!3BIrrrr,N5US!1'F+,bS !1'(rrrrbe%UU!%4R#LmU!%4KrrrrmX3SDJ"))!aR##m-BIrrrrhJ+'S!,#!-C`J [$'(rrrrpd#mV!!4KrrrrmTT`!%cI(!K1ANjd!!4PF`3Z68P8)%N[8b"0B@0%CAB &,J3-)5KZB@eP)#%p)$!T!5N)3d0KBfKP,Q-")$d2)5JUD'&ZC'aP)#%p)$!T%5% SF(*TEQ0TF'&X)#%p)$!T$5%SFf&QC9!J)6dJ-#N-3d0KBfKP9A4TE#jM!5d-)5K cDATP)$iJ-%`T!5X+)5KZBb!K25!`+3%j#b%SEf*U)#%p)$!T$#%SC'9cG#!K25! `+3%r$h*PG'4PFh3J26dJ6P9-6!iU+Q4PFh3J26dJ6P9-6!%h&LJU+Q4PFh3T,6j NBA4K)$dp)%j96%`"+`TZBb!p25"198a-!6-5)5KMER4bE%*XEf0V)#%p)$!T!5i 0)5KMFQ9NFb!K25!`+3!l)IU#!K-!jJ$D!-)!XJ#L!*3!L!"m!'i!B!"5!GJ!3!* !!NJ!-!!Q!"J!&!!J)Mmm!5-'UI!#)[rp$L)+)S)#*`'3!!R+!C!!#D!"N!!*J!' 3!!PJ!C!!#*i"N!!(-!'3!!Dq!C!!"Q`"N!!'+!'3!!A+!C!!"3)"N!!%UJ'3!!4 %!C!!"#!"N!!$(J'3!!*q!C!!!EB"N!!!XJ'3!!"m!C!!"#)"N!!)C2q3"!#3"2q 3"!#3"2q3"!#3"`3!!!!1!!!!!3!!!0`!!!$S!!!#p!!!!!3!!!!9!*!2!3#3#b) !N!X$!!!!!3#3"d8!!!!"!!!!!3!!!!)!!!!%!*!(FJ#3#`J!!!!'!*!%!3!!&J) !!#m#!!!h!J!!2J%!!&F#!!"N!J!!I`)!!)N#!!#@!J!!S3)!!+`#!!#h!J!!``) !!08!!3#3"3B!N!3"3B$[5Je#%i!h4K40594IT80$B@0SC8GXEf*KE(0-D@)!Cd0 ZG(*X3Qa[BfX!68P8Ak90594$6'PL!(0dFQjMF(N!Fh4bBfe`!'ePEA0PG!"0594 IT84PBR9RCfPZCdaTBJ"R4'9LG@G6D@GZB@`!3@aPFR46D@GZB@a"G!"*ER4PFQC KBf9-D@)!6Q9h8(4b8hPc!&9ZD'pXC%ePE@pbH3")EfaN6@9YEh*j!%4TFh"[Ff9 3G()!4f9d8(4b8fPkC3"6B@eP8(*[Bf9cF`"(CA4$GA*bC@jd8(*[Bf9cF`"1CAG 3G()!Bf0ICf9dAf0bC@4IGQ9bFfP[EJ"MBepQFQ9PAdj$AfPZCQm!Bf0ICf9dAf0 SB@jRC9pdD@eP!'0MAf4PFh4bEhN!Bf0IBfa[Ff8!Bf0IBh*PBA4P!'0MAfCbC@9 IBh*PC(-!Bf0ICf9dAfjKE@8!Bf0ICR*PC9p`FQPZBfP`B@`!Bf0IFQ9YEhCPAf0 bC@3!Bf0IEh"PEJ"MBepRCA4I6N0ID@jQE`"MBepcCA&ICQ9dBfKI6N0c!'0MAh0 PG&p`FQPZBfP`B@`!Bf0IFfKeG'4[Gfi!Bf0IFf9aAfCPG'0SAf0bC@4c!'0MAfG PG&p`FQPZBfP`B@`!Bf0ID@jTG'PKE'PkC3"MBepcG'pbC3"MBepXEf0VAh*PFA9 PFh3!Bf0ICR*PC9pZB@eP!*!*"!!!!!`!!3!)!!3!!!!'!!J!"J!)!!J!!!!+!!3 !#J!!!!X!%!!,!!`!$`!!!")!"!!5!!!!%`!)!"-!%qq*!!mc9`!569F!#TVI!!J Qc`!*6#%!$Fk[!!XfqJ!4q!B!$ZC6!!F66!!1ZFB!%)+a!"#-#J!,2Ad!%JKH!"$ -#`!0b18!##F0!!mB(J!-CeS#!!$F!!!#%!!"!J!!m!!!!G!!!3)!!3!!!!)i!!% #!!%6!!!#3!!"!J!"(J!!!NJ!!3)!!5F!!!*B!!%#!!%a!!!"f!!"!J!"2`!!!JJ !!3)!!8X!!!(S!!%#!!&G!!!#+!!"!J!"E!!!!P!!!3)!!A3!!!(`!!%#!!'$!!! #!!!"!J!"P!!!!L!!!3)!!D8!!!*J!!%#!!'a!!!"q!!"!J!"a!!!!KJ!!3)!!G8 !!!*S!!%#!!(M!!!#-!!"!J!"l!!!!FJ!!3)!!I`!!!(J!!'qG3!!!3!!!!&J!!! !B!!!!$)[Fh*M,feKBbpdC@aZCA30Eh9d)'CPC5"TFb"SCA*PBRNJCh*KER4PC#` JF(*[GQPNC@3JG'KKG#"dD'8JB@*[GQ8JBfp`HA*TCfKd$5!U)'j[G'PMC5"KF(" PBA)JD@iJB@aX)'0[F'PPFb"KEQ3JG'KKG#"LEh4S)(4SBA3JBfp`HA*TCfKd)'j [G'PMC5"KEQ30)#SJG'KTFb"`CA*YDA0cD@pZ)'j[G'PMC5"KF("PBA)JD@iJFh9 `F'pbG'PZCb"NEf0eE@9ZG'&dD@pZ,#"KEQ3JG'KKG!dJ+L"dD'8JEQ&YC5"[CL" 0,NNZ9#i!!!"F!*!,!3#3%`&Y0MKV!*!6!3#3%6`168P8Ak9$3f&MD'9-D@)!N!8 "!!!!!@!!!!"J!!!!-J9@1G!cb!!!!"`!-J!!BfCbC`!!!!S!!2rr!*!)H,J: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/bin/CCacheLib.68K.debug b/src/mac/libraries/CCache API/bin/CCacheLib.68K.debug deleted file mode 100644 index 36bdabc3c..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheLib.68K.debug +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :%d0$B@0SC8aTBLif1%XZC'9LG@F!FfKXBN0"*%J"!!!!*fB!!!'@B"K+EhNKF'9 QCQdf1'X!!!!"XJXf-3#3$3-!!J#3$L!B!!!J'!!!)"J!!!#8!!%#!*!%"3#3"J, `!!!#m!!!!G%!!##X!J%#!*!%$J#3$J6Q!!!LJ!3"!J"0B@PZ!#9"09G[FQaN!%a [B@4PFJ#3"#T46PErq%MR!$JNEJ!)+'i!%#CZ!"3JEIpJ5T!!CM*)H!!3BIm!!!p `*)"+NQB%F!CJ4#"53UJ!"#"53T!!)&*#U!!))&*#U!!-)'hrB##5B!BJEIpJ**! !F!'`VJ!-E!4`#@!8)!aR"(!"+)!J#fF')'hrr#D3!(!!60mF!%jH6R3!%)eMBep TEQPdD@&XDATP!!!U88j@rrJ[#L4Z!!JJ#QF@5T*R%Lm5BIm!!"[),a*Kr`!!$9K J"(!+B!4#NR!!*&p1ANjd!!5,Bf0IFfKeG'4[Gfi!!#T46PErq%MR'$JQEJ!)*Li !$#KZ!"3S,J!FPFSJ#fB'F!TJ!!$D5S4Q"R!-B!!!d%Ki!LCKr`!!$SSN3#!+CJC `"Q!!!,T+JfF5)%0`re+!5KKQqJb!!!!!rf8'F!&J!!#H)%SL3b!)%0PQr#!-Ca) J6($r8S"+''Ek$)!!!!$rC34`$'"i3HS""#*-)!J3f@Em*@i!'!)-3QS#"#9Z!"! "!"9m!!)#%("N*8!#%Lm+BIm!!!jD*8!##%UU!JKQ"(!'B$T+U`!)CK"#UJ)L3US #(LD+*dS!"'!@)'X!"#&+!KiPD`!%!L*#UJ)H*dS!"&+V!!K5U`!-)%3JLR!!60m F'%jH6R3!')PMBepMFQ9KG'8!!#T46PErq%MR($`U,J!)*Qi!$#JZ!"!SEJ!BPFT f!%U&CJC`#Q!!!0)J$'B'F!aJ!!$))!YQ!!#%)'hrM(!"X*!!CKj`!#m!5(J!Ubm Yrr3[,Iri)QhrN!!J@8k3!#TZrr4J@L"Yria`!V#3!'B5,bhrq#*YrhJJ@8k3!#T Zrr4J2L"Yria`!l#3!'B1)QhrC#"C6T!!+Qlrp'!Q)'hrM(!%X*!!CKa`!5m!5(J !UbmYrr3[,Iri)QhrN!!J@8k3!#TZrr3J4543B#)[#Lm,)QhrQ#"C6T!!+Qlrp%U !CJUiUJ%!CJ4f!@!%*'S#(L!+C`4+!fI@5J0R"LL+F!"J"%+8F!T-ha`i6Pj1G!! 8Kf0MAfp`C@i!!#T46PErq%MR!$`SEJ!)*'i!$*I,)!aQ"R!+B!!!ZL!+CJC`$'! !!,"+NQB!!)3JEIq-F!'`N!"Q(R!!,`")H!$0,bhrp#mYrr!LEIq3!#"C6T!!+Ql rp'"D)'hrM(!#X*!!CK)[,Ir`)QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*!!CJiLEIp N)&P1N!!UE[rdB#BJEIq-F!5`N!"Q((!",`")H!$0,bhrp#mYrr!LEIq3!#"C6T! !+Qlrp#"5$#J!!3)3C`4`$Q!B*P)[#bm-BIm!!"5i,`YKr`!!#NC#NR!!60mF!%j H6R3!#)KMBepME'pcC3!!!#T46PErq%MR%$`SEJ!)*Qi!$*A+)!aQ"R!+B!!"(L! ,CJC`$'!!!44+NfB!!)3JEIq-F!'`N!"Q(R!!,`")H!$V,bhrp#mYrr!LEIq3!#" C6T!!+Qlrp'"D)'hrM(!#X*!!CK)[,Ir`)QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*! !CJiLEIpN)&P1N!!UE[rdB#BJEIq-F!5`N!"Q((!",`")H!$V,bhrp#mYrr!LEIq 3!#"C6T!!+Qlrp#46F'5`UJ)5Ca![#Q(r!!!BPNS!CJ4`#'"`5US#)QB5++S#(NU U!KjR##"U!Kj#U!)L5US#(QB8+@S#)J!%5US#)QF))'S#)N+S!Kj+UJ)LCaT+UJ) HCa3JDJ)H)@S#)J)L)'S#)L&U!Ki#(K9m!!%#%#m,,``LEIrX)&P1N!!UE[rd*J" 5V!!-)!0-ha`)6Pj1G!!)LQ0MAf4PFh4bEhN!!!!U88j@rrK+VJ!)CJ4`#Q!B5Ui !$'F3)'i!##*Z!!`LU!!-F!"J!R!-6Pj1G!!)NQ0MAfGPG&pMD'&ZCf9IG'PYC3! !!#T46PErq%MR%$!QEJ!)*'i!$(B!)!YQ"(!+B%JJ#QB%F!TJ3("NX+S#%QFBF'D `UJ)5CJ`[#Q(r!!!AKNS!CJ4`#'!J,bi!&#mZ!"![#Q(r!!!3e#B!5S0Q"&+V!!K 5U`!-)!0-h``)6Pj1G!!3L'0MAh0dEh*P!!!!+P&19[rd51F!-#CZ!!JNEJ!-3Ul rp#!,C`3J#QB%F!TJ0R"NX+S#%QFBF'D`UJ)5CJ`[#Q(r!!!A$NS!CJ4`#'!@,bi !&#mZ!"![#Q(r!!!4GP+V!!a`!%cI$!"1ANjd!"#1Bf0IFQ9YEhCPAf0bC@3!!!! U88j@rrK)j`!m+'i!##CZ!!`NEJ!8)!aR"#!,CJC`#Q!!!03J#QB!!)3JEIq-F!' `N!"Q(R!!,`")H!&V,bhrp#mYrq3LEIq3!#"C6T!!+Qlrp'"D)'hrM(!#X*!!CK) [,IrN)QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*!!CJiLEIpN)&P1N!!UE[rdB#BJEIq -F!5`N!"Q((!",`")H!&V,bhrp#mYrq3LEIq3!#"C6T!!+Qlrp("NX+X#%QFBF'D `U`)5CJ`[#f(r!!!@%%S!CJ4`#'!U)#X"!,#Z!""R"(!+B"a)H!$r,`T)D`%%)Qh rP#"C6T!!+Qlrp&+X!!a`!%cI(!"1ANjd!"#3!'0MAh0PG&p`FQPZBfP`B@`!!!! U88j@rrK)j`!`*Qi!$#4Z!"!J#fB%F!TJ2R"QX+X#%QB3,`YKr`!!&CC+!'B%F!K J*L!+Cb")H!$rBIm!!!B+*)"+NQB%F!CJ$L"53qX""#!)%0PQr(!!60m-!%jH6R3 !$*!!Bf0ICf9dAh"bD@jMDA"KE!!!!#T46PErq#m+*'i!$#!+CJ4`#Q!XF'D`UJ) 5CK![#Q(r!!!9*NS!CJ4`#'!85Ui!%'B%F!CJ#L"Z!"!JUJ%!F!!NAdjH6R3!$*0 MBepRCA4IBh*PC&pfCA*cD@pZ!!!U88j@rrK)j`!`*'i!$#CZ!"!J#QB%F!TJ0(" QX+S#%QB3,`TKr`!!&-*+!'B%F!KJ(#!,CaC)H!$rBIm!!!8f*S!J8b*+)!J3f@E mF!"-h``!6Pj1G!!-Lf0MAfGPG&pZB@eP!!!U88j@rrK)j`!i+'i!##CZ!!`NEJ! 3)!YR##!+C`3J$'B%F!TJ5NU5CKK)H!!)BIm!!!6F*)"+NQB%F!CJ-L"5)*3J8NU 3!'B3,a*Kr`!!"3T#NN+6F!0J'#m,)&)[%'(r!!!49L"5)&!L8L+S!Kj`!%cI(!" 1ANjd!!b3!'0MAh0PF9pQCA4MD&p13h-!!!!U88j@rr")ja!i*Qi!$#KZ!"!NEJ! 8)!YR#L!+C`C+VJ!)CJC`#Q!!!9!J$'B'F!CJ!!&'F'D`U`)5CK)[#f(r!!!6Y%S !CJC`#'!!!5a+NQBN5(J!#'(r!!!%*L5!5T*Q"R!'B!!"%L"53UJ!"'!')&*5U!! %-#X#"%M!)&+`U!!%Ea3J8L*V!JJJ+!!%)R%-!("MX*&Rf$!V!J4)`#"5X+J!"'i 5,a*Kr`!!""j#P%+5F!0J!!$#)&)LD`)))#J!"#*a$!!Q%A!"YS"QDNKi!!KKr`! !!kSSJ%U8CJC`"Q!!!*C)H"eqBIm!!!18)&3K3!!%)&4+U!!%CJ4`"Q"i)&)LD`) ))#J!"#*a$!!JD3!%)P3LD3!%)$`!!"eqFL#`J@8%SLjJ$NU!C`SL#4,B8i"QqL* "B$K`!VD!CL`J8L*V!JJJ+!!%)R%-!#eT!!6rp(!#,8$rm#m-,blrp#mZrr"Kr`! !#LCJ"N+8F""J##"58UJ!"(!!60mF#%jH6R3!%**MBepcCA&ICQ9dBfKIBh*PC(- !!!!U88j@rrK)ja!m+'i!##CZ!!af!*A+)!aQ"R!+B!!!NL!,CJC`"Q!!!)JJ,!! )8S$PL#m!)QhrL#"C6T!!+Qlrp#D!5T0Q"(!'B'BN9'"@5(J#!L*YriJJ@8k3!#T Zrr3J8b'!2!!J8dU`2!"Q"(!'B%!J8b"`2!!L5L!)%0PQr#"6)(!m!%(S!2p$kJ% %)!J3f@Em)&-JF$`!)@S"!!(q*'S#(P+$)!TQTL"63V!m!(!!60mF#%jH6R3!#)j MBepRCA4I6N0ID@jQE`!!!#T46PErq%UZ!!aQ"(!'B!`[,J!-BIm!!!*1F!"1ANj d!!L4Bf0ICR*PC9p`FQPZBfP`B@`!!#T46PErq%UZ!!aQ"(!'B!`[,J!-BIm!!!) BF!"1ANjd!!L-Bf0ICR*PC9pZB@eP!!!!+P&19[ri,`SNEJ!-)!TQ"(!+B"3[%Q( r!!!5$Lm5BIm!!!(F3T*`!#4I6Pj1G!!)M@0MAfCbC@9IBh*PC(-!!#T46PErq%M R%#3NEJ!-)!TQ"(!+B$4f!'!8)&)[-$`!)QhrG#"C6T!!+Qlrp&+$)&*+X$`!CZ3 [%L*Yrh3J@8k3!#TZrr4#NTA+F!"-h`3)6Pj1G!!)Mf0MAfCbC@9I6N0ID@jQE`! !+P&19[rX51F!*#4Z!!`J#QB'F!aJ!!$D5'lrm#*Yri3J@8k3!#TZrqJp32rXF'5 `UJ)5Caa)E[r[5'S#&NKZrr!LEIq!)&P1N!!UE[rS28$rl#!Z!""6J'F-8i"R%P1 !CcCJ!!#)F'3P3!)5B!!!JR"NX+S#%QB8F'8P3!)5*@lrm!)@*@lrp!)DB'4`CV# U!K*QA(!)B&T`C,#U!K*Q&("Q*8!#%L9Zrr!#&L9Zrr3#'Q!mF'D`UJ)5CJT+,[r [CJ4`#'!XF'@`UJ)5CL*+,[r[Ca4`CL9!!K)PE[r`!KBPE[rd!KTJ#(!)B!C`$'! #F!!NAdjH6R3!$)pMBepXEf0VAh*PFA9PFh3!!#T46PErq%MR!#3[,J!))QhrL#" C6T!!+Qlrp#4!)!TR%LmZ!!J[#L*Yrh!J@8k3!#TZrr3J#L4I6Pj1G!!%LNjPGe0 KCQ93G()!!!!U88j@rrK)ja!N*'i!##m+)QhrI#"C6T!!+Qlrp#B!)!TQ!!#%)'h rM(!"X*!!CKj`!#m!5(J!*bmYrpJ[,IrF)QhrN!!J@8k3!#TZrr4J@L"Yria`!V# 3!'B5,bhrh#*YrhJJ@8k3!#TZrr4J2L"Yria`!l#3!'B1)QhrC#"C6T!!+Qlrp'! Q)'hrM(!%X*!!CKa`!5m!5(J!*bmYrpJ[,IrF)QhrN!!J@8k3!#TZrr4+Jfi!!)3 JEIq-F!'`N!"Q(R!!,`")H!!S,bhrf#mYrp3LEIq3!#"C6T!!+Qlrp'"D)'hrM(! #X*!!CK)[,Ir8)QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*!!CJiLEIpN)&P1N!!UE[r dB#BJEIq-F!5`N!"Q((!",`")H!!S,bhrf#mYrp3LEIq3!#"C6T!!+Qlrp#m$3UF [#L*Yrj`J@8k3!#TZrr3[!d+R,`SLEIqF)&P1N!!UE[rd,`-[#L*Yrf`J@8k3!#T Zrr3[#L*Yrh3J@8k3!#TZrr4-h`3)6Pj1G!!%MN4TFh"[Ff96B@CP8(4b!!!!+P& 19[ri51F!*#mZ!!JLEIpS)&P1N!!UE[rd*%!J#QF5,bi!##m+)QhrF#"C6T!!+Ql rp#!+*&p1ANjd!!506Q9h8f&QC9"dFP0jF`!!+P&19[ri51F!*#4Z!!JJ#QB!!)3 JEIq-F!'`N!"Q(R!!,`")H!"3,bhrf#mYrp!LEIq3!#"C6T!!+Qlrp'"D)'hrM(! #X*!!CK)[,Ir3)QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*!!CJiLEIpN)&P1N!!UE[r dB#BJEIq-F!5`N!"Q((!",`")H!"3,bhrf#mYrp!LEIq3!#"C6T!!+Qlrp%*U!J3 eI!!+!JC)H!!SBIq3""!P3!)))#S###4I6Pj1G!!%M@jPGd0bC@4#G@CQCA)!!#T 46PErq%MR!#3NEJ!))!TQ!!#%)'hrM(!"X*!!CKj`!#m!5(J!ALmYrpJ[,Ir-)Qh rN!!J@8k3!#TZrr4J@L"Yria`!V#3!'B5,bhrc#*YrhJJ@8k3!#TZrr4J2L"Yria `!l#3!'B1)QhrC#"C6T!!+Qlrp'!Q)'hrM(!%X*!!CKa`!5m!5(J!ALmYrpJ[,Ir -)QhrN!!J@8k3!#TZrr3NVJ!-*@i!%!!%5Ui!&'B)3US!#(!!B$i[,J!3BIrrrri i*8!!#%UU!!KQ"(!'B#BLDJ!))'i!&#!Z!""b),#"C35L,Q!15S"R#L)*%YK6J'E k)N&`!#4I6Pj1G!!3Lf0[F(P%BA4K6f*U!!!U88j@rrK)jaJm+'i!##4Z!!ai!*I ,GJ!J#QB!!)3JEIq-F!'`N!"Q(R!!,`")H!"d,bhrf#mYrmJLEIq3!#"C6T!!+Ql rp'"D)'hrM(!#X*!!CK)[,Ir))QhrH#"C6T!!+Qlrp'!q)'hrM(!$X*!!CJiLEIp N)&P1N!!UE[rdB#BJEIq-F!5`N!"Q((!",`")H!"d,bhrf#mYrmJLEIq3!#"C6T! !+Qlrp#C-)!YQ#%+5B!!#@P+%5TYQqL!%8S$PL#m!BIrrrrdZ*)!Q!%U$CJ!!K#" Yria`!E#3!'BHF!![!%Ki!(`[,IrB,bhra#*Yrj!!)&P1N!!UE[rdB&SJEIq-F!+ `N!"Q%LmYrm3LEIpi)&P1N!!UE[rdB$iJEIq-F!1`N!"Q$L*Yrf3J@8k3!#TZrr4 J*L"Yria`",#3!'BFF!%[!%Ki!(`[,IrB,bhra#*Yrj!!)&P1N!!UE[rd5S0R!!' d*NaJ!!'J5(J!$'(rrrrmM#"5))!J8NU3!'B!!)3JEIq-F!'`N!"Q(R!!,`")H!# $,bhrf#mYrm!LEIq3!#"C6T!!+Qlrp'"D)'hrM(!#X*!!CK)[,Ir!)QhrH#"C6T! !+Qlrp'!q)'hrM(!$X*!!CJiLEIpN)&P1N!!UE[rdB#BJEIq-F!5`N!"Q((!",`" )H!#$,bhrf#mYrm!LEIq3!#"C6T!!+Qlrp#"55T!!C`!"$L*5)P%J9(!-FL#`J@8 %SLjJ$NU!C`SL#4,B8i"QqL*")&)J8#mS!!4KrrrrqmJJ8L"3)8!!##"5)&"+U!! )CJ!!K#"Yria`!E#3!'BHF!![!%Ki!)X[,IrB,bhr[#*Yrj!!)&P1N!!UE[rdB&S JEIq-F!+`N!"Q%LmYrl`LEIpi)&P1N!!UE[rdB$iJEIq-F!1`N!"Q$L*Yrf3J@8k 3!#TZrr4J*L"Yria`",#3!'BFF!%[!%Ki!)X[,IrB,bhr[#*Yrj!!)&P1N!!UE[r d)&)J8%US!!KR2L"8)#J!"#*5)P%LD3!))&3JD!!)FL#`J@8%SLjJ$NU!C`SL#4, B8i"QqL*"@)TBLdU6CJ$qAL"$3V"-!#5$60mF'%jH6R3!#)eMEh"j4'&dB8&bFQ& j!!!U88j@rrK)j`!m+'i!%*A+PmXQEJ!-)!aQ"R!'B!!"%%Ki!!KKrrrrqUBSJ%U 8CJC`"Q!!!2T)H!"-BIrrrrU3!#4!)!TQ"R!'B!!!j%Ki"1*KrrrrqRSNJ%U5CJC `"Q!!!-j)H!6LBIrrrrTN*8!!"%UU!!4Q"R!'B!!!Y%Ki"0m[%bm5)QhrP#"C6T! !+Qlrp%Ki"0m[+`!%,bS!"#*Yrj3J@8k3!#TZrr3[+`!3,bX!$#mV!!K)DJ!)BIr rrrXS*@X!&!!8*@X!'!!B*@X!(!!F*@X!)!!J*@X!*!!N*@X!+!!S5'S!,#mV!#a KrrrrqrJ[+`!i,bX!0#mV!$")DJ!`BIrrrrVJ,bX!4#mV!%![+`!m5'S!2'(rrrr kbN+U!%JJ9(!#))!J9#&+!!4`!%cI(!"1ANjd!!b+Bfp`H9Be3h*PC!!!!#T46PE rq%MR!$!QEJ!3PFSJ#fB%F!CJ@NKi!!KKrrrrq@JQJ%U6CJ4`"Q"')&0`!5#!5(J GIQ(rrrrj6L4!)!TQ"(!'B#`L5L"Z!!`J2!!!(Ajb),#"C35L,Q!15S"R#L)*%YK 6J'Ek)N%J8b&+!!4`!%cI$!"1ANjd!!b+Bfp`H9Bd3h*PC!!!!#T46PErp%MR!$! NEJ!)PmY#V[rd)!TQ"R!+B!!!i(!"X+i!$'F1F!+`VJ!-C`C`%'!!!-T5DJ)%-#S #","U!JCQDM!U!JE33$9!!JB`+J)'5-$PL#m!BIrrrrLN*N!J#fB'F!CJ!!#@-#S #"NM!)J$JLH#*i)RZLG+!iS(PL5!")NXJDJ))FL#`J@8%SLjJ$NU!C`SL#4,B8i" QqL*",bS##'(rrrrfc#9,!JK`!E#Z!!aQ&%KZrr3[,J!3,bi!$'(rrrrqYQ!JF!+ `VJ!-CK4)E[rd,bi!%#mZ!!aKrrrrr94J"(!3B"3`+J)%5-"6J#"U!JJKV[rd$!" `!%cI$!"1ANjd!!b3!'0bC@4#G@CQCA**ER0PFR3!!!!U88j@rrK)jaJ`*'i!#*I ,)!TQ"R!+B!!!L(J!B(B[,J!3,bi!$#"U!JJJF%`!,bJ!"#mS!!"Kr`!!!B4+!'G 5)'S###C`6!![#f(r!!!'0#m,BIrrrrB#*J4J&#!$8S!JDJ)))QS###1`$!!m!&+ $-#S#"%M!8i#fJ'hJ-#S#"%M!8i!JDJ))3V!-!&0U!J4J$&+%-#S#"%M!Z)"YJ(! !60m-'%jH6R3!$*!!Bh*PC%*eCQCPFP*PE@pfC3!!!#T46PErp%MR%$3QEJ!)*'i !$%+Zrr3J#QB!!)3JEIq-F!'`N!"Q(R!!,`")H!&),bhrf#mYrlJLEIq3!#"C6T! !+Qlrm'"D)'hrM(!#X*!!CK)[,Iqi)QhrH#"C6T!!+Qlrm'!q)'hrM(!$X*!!CJi LEIpN)&P1N!!UE[r`B#BJEIq-F!5`N!"Q((!",`")H!&),bhrf#mYrlJLEIq3!#" C6T!!+Qlrm#!+CJ4`$'!iGJ"J(L"U!JJYF$`!rr4)E[rd,`XLEIrJ)&P1N!!UE[r `8S-`+J)%5-#fJ'hB,bS##'(rrrrd`(!!60m-#%jH6R3!#*&NDA0`Eh0P3h*PC%* eCQCPFJ!!+P&19[ri51F!0%UZ!!aR"NUZ!"4Q"R!!B!!!c#!Z!!L`VJ!3C`C`!'! !!,a`!E#Z!!KQBL4Z!!`QEJ!85'X!!8KU!!%LEIqB)&P1N!!UE[rd5S"Q2NKV"10 )DJ6M)QhrQ#"C6T!!+Qlrp%U!CLC)Da1*5'S6L5*YrjJJ@8k3!#TZrr4+J'B1)#S BI,#V'(aQ"(!"B&4`!'"3F!+`VJ!)CNBNEJ!-*Qi!&#m6,a)LEIqB)&P1N!!UE[r d5S"Q*LmV!!3[+J!%)QhrQ#"C6T!!+Qlrp%U!CJiJ+J!BX+X!''B%F!&J"R!!B!* `!%cI$!"1ANjd!"#(Bh*PC'0YF!!!+P&19[ri51F31#CZ!!JSEJ!-PFSJ$'B'F!C J!!'3!%Ki!LCKrrrrmc3SJ%U8CJC`"Q!!!ASN9#"+)NXJ#"$CC[`PD`%!!3""kJ% %3qX""#!)%0PQr$9V!J3#"$9V!JB#"K9m!!%#%$!U!JC)`1@),`"KrrrrmZBP3!) )5US##'B'F!CJ!!%SGJ"J!!%-)'X###"`2!"`!E#3!'B!!**)H!!)BIrrrr+f)'S ###'!2!!JDJ))5V!m!'B'F!CJ!!$`)'S###"`2!"`!5#!5(JGIQ(rrrrbL#"U!JJ JF$`!)8!!"#"U!JJJF$`!5UJ!"'B'F!CJ!!#k)QS###*a2!!LD3!%)'X###"`2!! JD!!%)$`!!"eqFL#`J@8%SLjJ$NU!C`SL#4,B8i"QqL*"B'JJD`)))(!m!(!#X*! !CL!JDJ))5(!m!#"V!JJJF$`!,bJ!"#mS!!"Krrrrq4"J1L"V!JJJF$`!F'1`N!" Q,%Ki!!KKrrrrmHSJDJ)))B!m!#"U!JK+X$`!CJ4`"Q!N)'S###"`2!"`Bb#!8S- `+J)%5-#fJ'd!rZa#UJ)L3US#(R!!60mF#%jH6R3!#)9NGA"13`!!+P&19[ri,`S NEJ!))!TR(Q!1)&)[+!!)BIrrrr(+@)T+NQEZ,bi!#'(rrrraZL4I6Pj1G!!%N!" NDA0`Eh0P4'&dB8&bFQ&j!!!!+P&19[ri51F!*#4Z!!JJ#QB!!*BJEIq-F!'`N!" Q(R!!,`")H!(#,bhrf#mYrl3LEIq3!#"C6T!!+Qlrp'"X)'hrM(!#X*!!CK)[,Iq d)QhrH#"C6T!!+Qlrp'"3)'hrM(!$X*!!CJiLEIpN)&P1N!!UE[rdB$JJEIq-F!5 `N!"Q,R!",`")H!(#,bhrf#mYrl3LEIq3!#"C6T!!+Qlrp'!3,`S[#L*YrqJJ@8k 3!#TZrr4+NQEXF!!NAdjH6R3!")TQFQ9P6N0-DA0d!!!!+P&19[rX51F3*#4Z!!J J#QB!!)3JEIq-F!'`N!"Q(R!!,`")H!(5,bhrf#mYrp!LEIq3!#"C6T!!+Qlrk'" D)'hrM(!#X*!!CK)[,Ir3)QhrH#"C6T!!+Qlrk'!q)'hrM(!$X*!!CJiLEIpN)&P 1N!!UE[rSB#BJEIq-F!5`N!"Q((!",`")H!(5,bhrf#mYrp!LEIq3!#"C6T!!+Ql rk%KZrqiLEIq%)&P1N!!UE[rS0J!`!dM!C`4`!'!dF'5`UJ)5Cb4)E[rh5'S#&NK ZrqiLEIq!)&P1N!!UE[rS0J!`!dM!C`K`!'!)3Llrpa!ZrrG-h`3)6Pj1G!!%LQP c6'pMDdpeFR-!!!!U88j@rrK)j`!d*Qi!##!,CJ!!K#"Yria`!E#3!'BHF!![!%K i!HF[,IrB,bhrX#*Yrj!!)&P1N!!UE[rdB&SJEIq-F!+`N!"Q%LmYrl!LEIpi)&P 1N!!UE[rdB$iJEIq-F!1`N!"Q$L*Yrf3J@8k3!#TZrr4J*L"Yria`",#3!'BFF!% [!%Ki!HF[,IrB,bhrX#*Yrj!!)&P1N!!UE[rdF!+`NfCQ*'X!"#m5BIrrrqmd,bS !"'(rrrr[+NUU!""R#LmU!""KrrrrlaT+UJ!iC`S[+J!iBIrrrqm+5US!4'F+,bS !4'(rrrrZqNUU!%KR#LmU!%KKrrrrr3K+UJ!XC`S[+J!XBIrrrrci,bX!"'(rrrr Zd(!!60m-!%jH6R3!"*CMBepQFQ9PAf0bC@4ID@jdCA*ZB@ac!!!!+P&19[ri,`0 f!#mZ!!KKr`!!!&if!$!$5-"R"$!$B!JJEIpJ3T!!-!-Q(djH6R3!"***EQPdD@& XDATP3f&MD'9-D@)!!!!U88j@rrKKr`!!!%j1ANjeN94PFQeTEQ&dC80KBfKP6'P L!!"1G5T46PErq#m0)!d[!#mYrk`LEIqN)&P1N!!UE[rd+d$rA'(rN!6FF!"1ANj d!!3U88j@rrJ[$5mYre`LEIqJ)&P1N!!UE[rd6Pj1G3JZ68P8)%N[8b"0B@0%CAB &,JJ-)5KZB@eP)#%p)$!T!5N)3d0KBfKP,Q-")$d2)5JUD'&ZC'aP)#%p)$!T%5% SF(*TEQ0TF'&X)#%p)$!T$5%SFf&QC9!J)6dJ-#N-3d0KBfKP9A4TE#jM!5d-)5K cDATP)$iJ-%`T!5X+)5KZBb!K25!`+3%j#b%SEf*U)#%p)$!T$#%SC'9cG#!K25! `+3%r$h*PG'4PFh3J26dJ6P9-6!iU+Q4PFh3J26dJ6P9-6!%h&LJU+Q4PFh3T,6j NBA4K)$dp)%j96%`"+`TZBb!p25"198a-!6-5)5KMER4bE%*XEf0V)#%p)$!T!5i 0)5KMFQ9NFb!K25!`+3"1)J(SJJ)9!UJ!rJ$U!0i!aJ#f!+B!Q!#-!)!!FJ"N!&B #%!"%!RJ#J!!d!#S!(!!B!#!L2c`")`DTm!)Lrrd5)J'`JJ)X(kJ"X"pL!E!-XJ' `$%`"X!`-!E!,fJ'`#k3"X!VB!E!*3!'`#,)"X!K-!E!(lJ'`"hJ"X!CN!E!&m!' `"AB"X!8b!E!$i!'`![3"X!(S!E!!e!'`!*!!!E!%)J'`JJ)%!9JJ'!%B!#!B)ar 1!3%K#!-M(r`"!5%)!b)J'!`!!!$rN!3!N!F"!!!"q!!!!!%!!!(`!!!!"3!!!") !!!!"!!!""!!!!43!!!1!!!!!"!!!!"8!N!m"!*!,)J#3#`S!!!!"!*!(RJ!!!!% !!!!"!!!!!J!!!!X!N!I4!*!,!`!!!!d!N!Ik!*!,!J!!!"!!N!3"!!!@!J!!,`) !!$J#!!"#!J!!6`)!!&S#!!"P!J!!EJ)!!(N#!!#&!J!!P`%!!,B#!!$$!J!!j!) !!1`#!!$c!J!"%`)!!5N!!3#3"3F!N!3"JB$c5K&#&B!h4KG#!!!!68P8Ak9$3f& MD'9(E'pLB@ac6'PL!'G$ER4bE%*XEf0V!%PZG'9bCQ&MC8aTBJ"6HA0#FQ9KD`" 1CAG3G(*6HA-!9@jSEfaN6@9YEh*j!%K[E'40C@e[FRN!4'PcF'pcC9"dFJ"%C@* eCe0dFJ"(CA43G(*6DATP!&0KE@93FQpMCA0c!%GPG%0eFR*PER43FQpMCA0c!%j PGe"dFJ"0594IT84PBR9RCfPZCdaTBLjNC@*eC`"R4'9LG@G6D@GZB@`!3@aPFR4 6D@GZB@a"G!"0594IT8e*9%0-D@)ZC'9LG@F!Fh4bEQ0`H3"cG(*MEA!!E@9YFf9 d!%e*9&qP68P88R9ZG'PYC8aTBLjNC@*eC`"IAh9ZFQ9RDA0dCA*ICR*KCfePER3 !AepbC@GTFh4PFPpQFQ&RE@9ZG!"MBepRCA4IBh*PC&pfCA*cD@pZ!'0MAfCbC@9 I6N0ID@jQE`"MBepRCA4IBfKKEQGPAh4TE@8!Bf0IC'9cG(*[H3"MBepME'pcC3" MBepMFQ9KG'8!Bf0ICR*PC9pMFQ9NF`"MBepRCA4IEQ&YC3"MBepQFQ9PAh"bD@j MDA"KE!"MBepbC@e[GQ9IBh*PC!"MBep[F'9Z!'0MAfGPG&p13epTEQC[!'0MAh0 PF9pQCA4MD&p13h-!Bf0IFf9dAh"bD@jMDA"KE!"MBepcD(9dC'phEJ"MBepcCA& ICQ9dBfKIBh*PC(-!Bf0ICf9dAh"bD@jMDA"KE!"MBepTEQPdD@&XDATP!'0MAh0 dEh*P!'0MAfa[BfYIFQ9aG@9cG!"MBepQFQ9PAfjKE@8!N!J%!!!!$!!"!!J!"!! !!!B!#!!'!!J!#!!!!!S!"!!+!!!!#`!3!!X!$!!2!!!!%J!%!")!!!!6!!J!%`! 6liN!$c0A!"*09`!+QYm!##E2!!P-)3!0cUm!#cEk!"(i"J!1jP-!"a0-!!kjaJ! 3JV%!%)`+!!XpI3!5#&i!%-`,!!h)j3!)*`d!$aJH!!aR@J)!!6d!!!*)!!%#!!& 4!!!##!!"!J!"B3!!!R!!!3)!!A3!!!*i!!%#!!&r!!!#J!!"!J!"L!!!!T!!!!% #!!'5!!!#%!!"!J!"S!!!!N!!!3)!!D`!!!)J!!%#!!'q!!!#B!!"!J!"c3!!!SJ !!3)!!G8!!!)S!!%#!!(N!!!#1!!"!J!"p3!!!PJ!!3)!!JB!!!+B!!%#!!)5!!! #-!!"!J!#*3!!!P!!!3)!!MB!!!+J!!%#!!*%!!!#D!!"!J!#63!!!J!!!3)!!Pd !!!)B!!%Bd`!!!3!!!!&N!!!!C!!!!$)!N20J!*!,!3#3%`&Y0MKV!*!6!3#3%8! 868P8Ak9$3f&MD'9-D@)ZC'9LG@F!!!!"!!!!!@3!!!"N!!!!-J9@1G!cb!!!!"` !-J!!BfCbC`!!!!S!!2rr!*!)5'8: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/bin/CCacheLib.PPC b/src/mac/libraries/CCache API/bin/CCacheLib.PPC deleted file mode 100644 index 98e665770..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheLib.PPC +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :$80$B@0SC8aTBLj38%-!FfKXBN0"*%J"!!!!-#J!!!'5'R*+EhNKF'9QCR"hF'- !!!!"XP21U`#3$3-!!J#3"2q3"!#3"LPX!!!TE!!!+@`!!!93!!3%!2q3"!#3"J* K!!!#A3!!!@J!!#l!!J%%!2q3"!#3$J6'!!!!J!3%"!#3"Iq3"!#3"`%!!!&J!!! !!3!!!9J!!!!&!!!!%`!!!!%!!!%)!!!"'!!!!f!!!!!%!!!!&3#3$`J!N!X0!*! ,!3!!!!J!N!FM!*!,"J!!!!N!N!F`!*!,!J!!!!m!N!G$!!!!!3!!!!%!!!!#!!! !%3#3"!)!!&8#!!"I!J!!E!)!!(F#!!##!J!!M3)!!*N#!!#V!3!!XJ)!!,i#!!$ &!J!!c!)!!03#!!$E!J!!iJ)!!1N#!!$r!3!"%`)!!5!!!3#3"3J!N!4+%N!"3J& !!8)33J#!!dB@5@jdCA*QB@0P6'PL!%e*9&qP3d0KBfKP4fa[BQ&XFdaTBJ"0594 IT8e*9%0-D@)!68P8Ak905945G@jdD@eP6'PL!%e*9&qP4'9LG@GRD@jR6'PL!%j PGe"dFP0jF`"9EQK[E'40C@e[FRN!5'pXC%ePE@pbH3"%DA0`Eh0P8(4b!%GPG&" dFP0THQ8!8f&YC9"bEf0PFh-!4f9d3h9bFQ9ZG&"bEf0PFh-!6Q9h8(4b!'G$ER4 bE%*XEf0V!(0dFQ0YF!"YC@eMF(N!Fh4bEQ0`H3"cG(*MF(N!Fh4bE'9Z!'ePEA0 PG!"IAh9ZFQ9RDA0dCA*ICR*KCfePER3!AepbC@GTFh4PFPpQFQ&RE@9ZG!"R4'9 LG@G6D@GZB@`!3@aPFR46D@GZB@a"G!"MBepRCA4IBh*PC&pfCA*cD@pZBf0IC'9 cG(*[H@0MAfGPG&pMD'&ZCf9IG'PYC@0MAfCbC@9I6N0ID@jQEf0MAf0bC@&dC@0 MAf0XEh0PBf0ICf9dAfjKE@9MBepQFQ9PAf0bC@4cBf0IFQ9YEhCPAf0bC@4MBep QFQ9PAh"bD@jMDA"KE'0MAfp`C@jMBepcD(9dC'phEQ0MAh0PG&p`FQPZBfP`B@a MBepcCA&ICQ9dBfKI6N0cBf0ICf9dAdj$AfPZCQpMBepTEQPdD@&XDATPBf0ICf9 dAh"bD@jMDA"KE'0MAh0PF9pQCA4MD&pMFQ9NFf0MAh0dEh*PBf0ICR*PC9pZB@e PBf0IE'pMDepbCA&eCA0d!*!("!!!!!`!!3!)!!3!!!!'!!J!"J!)!!J!!!!+!!3 !#J!!!!X!%!!,!!`!$`!!!")!"!!5!!!!%`!)!"-!%qq*!!UDh`!569F!$c0A!!P -)3!)*Xm!#cEk!!h1V`!1jP-!%IJ'!!F66!!,2Ad!%)`+!"##X3!1ZFB!$FMP!"$ -#`!5#&i!##F0!!aR@J!2'"i#!!%Z!!!!q!!"!J!"33!!!5J!!3)!!8X!!!%J!!% #!!&G!!!!Z!!"!J!"E!!!!8!!!3)!!A8!!!%`!!%#!!&p!!!!m!!"!J!"L!!!!-! !!3)!!C8!!!%3!!%#!!'M!!!!d!!"!J!"Y!!!!6J!!3)!!EX!!!&)!!%#!!('!!! "#!!"!J!"eJ!!!1J!!3)!!HB!!!$B!!%#!!(d!!!"8!!"!J!#!3!!!3!!!3)!!K% !!!$J!!%#!!)M!!!"'!!"!J!#+`!!!-J!!3)!!MF!!!#`!!%!N!Tm#!+QN!!"!!L 8)Ir!1#%!3)!"!!Km#!1Q6S!!)(`)!UDrBIrXN!!"!!L8)Iq`I(XEH(bF)hKm[5Y iI0icH)2L!##!(`!!+!!!!%##!&3iB!!35!!9*@!!!!#3!(X!!)"l!!!S!`!!3)) !$$KJ!!C)!!"S1!!!!*!!!`!%J(X!!*!!!`!!J(X!!*!!!`!)J(X!!*!!!`!-J"X !!*!!(`!!5!!!#*!!'`!!,"`!!8#"!!`iB!!*5!!!+#JG!!""JJ!-1!!!!C!!(3! !+"i!!%'#!!b!!J#SN!!H!!!iB!!!J!%!@$JK!&"m#!1QZf(rl%k!!#!!N!BJ3B! &!*!&c!!1,Q0MAfPZDA4TB@aTHQ9m#!+QNq(rr*!!!3!)P#(r`(ar'hJS(`!!3B) !+)"r!!!S!`!!3B)!(%J!)T9J!!!!J(m!!%J!%ZeJ!!!!5!!!$$KJ!!T)!!!-1'! !!*!!I`!!J!%!5$JK!%"m#!1QJq(rr%k!!#!!N!BJ3B!"!*!&C!!-,Q0MAh0SGA4 NEhGZ!!"m#!+Q[b(rj*!!!3!)P#(rS(aj'hKmQL0iI,XVH(cF-hKmrcYiI4e$H#J C!!"!JJ!-1'!!#NJ!!6JS(3!!3))!$$KJ!!a)!!%S1'!#+%J!%jeJ!!!!I(iEH#J H!!"!JJ!-1'!!"NJ!!3JS'J!!3B)!'(p$dhK)!#FpJ%%!&#J$!2p"J!!-1'!!!8J !!14r`r0iId66H%J!*Sf!33!8+"`!!%'#!"KrJq0i5!!R#B""!"3S!`$r3B!!$$K J!!a)!!#`1(i""(q%ihK)!#CCJ%%!&*2q!J`li!!!Xri#"*0q!3!i!!!#Q"i#%$J !!'53!"i#&(r$mhK)!"0PB!!!!*!!IJ))J"i###J!!!"!JJ!-1'!!"NJ!!&b!'3! ),!!!!%##!"L6rJ)NNri#)*2C!!#6f3!%5!!!()"j!!56``)JJ"N!"*!!(J)NNri #)*2C!!5!H3!)1!-!!C!!'3!)J(N!$$J$!!'3!"N!$*2G!!!iB!!!J!%!D$JK!'" m#!1QZb(rj%k!!#!!N!BJ3B!(!*!%!B!!#LjMBepMFQ9KG'9m#!+Q[d(rk*!!!3! )P#(rX(ak'hKmQb0iI,`VH(cp1hJiJJ'%1')"Gi#L!%3li!!!IrllH#JD!!"!JJ! -1'!!#NJ!!,`S(3!!3))!$$KJ!!a)!!#X+"X!!%##!$b!"3!!,!!!!8##!"JiS!# V1-!!!8J!**f!33!85!!!(#`!!!4!JJ!81+!!UcM!!!&)!#5"J%%!&)2k!!")!!! dIf2EH(rNqhK)!#9CJ%%!&#`$!!"!JJ!BJ"m"!(`F!!"!JJ!-1m!!!8J!!!L$r`) J+"m!!%'#!!ar`!Ge3B,ra(r!"h9"JJ!3Nrd!!$KJ!!")!!!31!!!!*!!(3!!1'! !#S!"!&Ji)3"3I!J$TVY"rqK1J!!J!*!')%'!"J#3"!%3!!JZBf0IEh"PEJ!!I!J #TVqKrr53!!%!#*3Krl"mI4YiI*iMH$KL!BdiJJ'%J+)!4#JG!!"!JJ!-1'!!#NJ !!*JS(J!!3))!$$KJ!!a)!!#)J"i!!#J!!!"!JJ!mJ!8!!#`!!!&!JJ!B1+!!c6M !!!&)!#0pJ%%!&%J!!"`X!!!%3))!&$LJ!-di`!!"5!!MBB""!"5!IJ!!L!-#%#` !!!&"JJ!-1'!!$NJ!!#amIaYiIk2VH(rNqhK)!"S*B!!!!(rMqhK)!!mGB!!!!$K J!!#3!(i!!)!"!&Ji)3"3I!J$TVZKrr41J!!J!*!')%'!!`#3"G`!#5jMBepME'p cC3"m#!+Q[k(rp*!!!3!)P#(rX(aq'hKmRb0i1')"M6L#!B5!SJ"%+"i!!%##!!` iB!!+5!!"(#JI!!"!JJ!-1'!!$%J!!3b!(`!!+!!!!%##!$b!"3!!,!!!!8##!"J iS!$V1-!!!8J!)S@!33!85!!!(#`!!!4!JJ!81+!!kcM!!!&)!#*TJ%%!&)1r!!# !(3)8,!!!C%'#!#"rSqYi5!!HP@!!!!"mB!Ge3))!$$KJ!!K)!!#FJ"d#*#J!!!" !JJ!JJ"d#)*!!(J!!J(d#)#J$!!""JJ!-1!!!!*!!!`)NJ"d#)#J!!!"!JJ!JJ"d #**!!(J!%J(d#*#J$!!""JJ!-1!!!!*!!!`)JJ"d#*#J!!!""JJ!JJ(d#)#J$!!" "JJ!8N!!$!L5!(3)JJ(d#**!!!`)J1!!!!CJG!K"r`r0iIq6lH%[rrFf!RJ!-1!3 !!C!!(J!-J!%!@$JK!&"m#!1QZk(rp%k!!#!!N!BJ3B!$!*!%!@!!#bjMBepNCA0 dFQpj!!!!+!-!!%##!!`iB!!+6S!!)#J%!!""JJ!8J!-!$*!!"!!!1'!!!%k!!#! iB!!-6S!!)!#3"L"!!*!(-!!6,Q0MAfGPG&pMD'&ZCf9IG'PYC3!!!(`)!UDr`Ir iN!!"!!L8)Ir!I(iEH(bI)hL3!+%!B*!!`3"N+"i!!%##!!`iB!!+5!!!H#JI!!" !JJ!-1'!!#NJ!!'L!(`)8,!!!C%'#!#JX!!"Q3))!'(rMqhK)!"d"B!!!!(aJ"h9 !JJ!-1'!!#%J!!$KrirYiJ)%!B)#K!'4)!"6eB!!!!#`$!!"!JJ!3J*i!#$J%!!' 3!"i!#)#H!!`i"!!"N!!H!!b!!3")1#%!3(`)!kDl`Iri6S!!)!#3"L""J!)!N!@ i!!NZBf0IFh4[FQ8!I!J#TVr"rrL3!!%!#*3Krm"mIKYiI*mMH*!!S3"JN!$"!'3 S(J!!3B)!$#JI!!"!JJ!-1'!!#NJ!!&L!(`)8,!!!C%'#!#JX!!"Q3))!'(rMqhK )!"`eB!!!!(aJ"h9!JJ!-1'!!#%J!!#KrirYiJ)%!B)#K!'4)!"9jB!!!!)"q!!` i!`!"N!!H!!`iB!!!J!%!5$JK!%"m#!1QZm(rq%k!!#!!N!BJ3B!#!*!&S!!2,Q0 MAh*PE@pfC9pMFQ9N!!!!I!J#TVq"rr#3!!%!#*3Krl"mI"YiI*dMH(bq+hKmhc0 i1')"R6L#!B5!SJ"%+"`!!%'#!!`S(3!!3))!$$KJ!!T)!!#X+"m!!%##!$b!"3! !,!!!!8##!"JiS!&V1-!!!8J!(aQ!33!85!!!(#`!!!4!JJ!81+!"DcM!!!&)!"l pJ%%!&)!G!K3X!!"N3B)!+#`!!'C!JJ!BIk2VH%J!'b9J!!!!I'!(G8##!!`iB!! )5!!!2)!G!3"m!2!!3B)!$$KJ!!T)!!!S1(d""(rNqhJiS!$r5!!IIB""!"5!I!! -1!-!!C!!(!!-1'!!!)!"!&Ji)3"3I!J$TVZ"rr"1J!!J!*!')%'!"!#3"!%!!"% ZBf0IFf9dAh"bD@jMDA"KE!"m#!+Q[m(rq*!!!3!)P#(r`(bH)hKm[bYi+"i!!%# #!!`iB!!+5!!!D)!H!K3X!!"Q3))!)(r$mhK)!"TPB!!!!(aJ"h9!JJ!-1'!!#%J !!%!S(`!!3B)!0$KJ!2p)!!PpB!!!!*!!I`!!J(m!!#J$!!"!JJ!-1'!!"NJ!!"3 iRJ%%5!!H6B""!"3iB!!!J!%!5$JK!%"m#!1QZm(rq%k!!#!!N!BJ3B!#!*!&S!! 4,Q0MAfGPG&p`FQPZBfP`B@`!I!J#TVr"rrL3!!%!#*3Krm"mRL0iI,mVH#JH!!" !JJ!-1'!!#NJ!!%L!(J)8,!!!CN##!#"r`r0i5!!CS@!!!!"mB!Ge3))!$$KJ!!K )!!!J+"m!!%##!!`iB!!'5!!!%)!H!3#3!"m!!$KJ!!#!!3")1#%!3(`)!kDl`Ir i6S!!)!#3"L""J!)!N!@!!"3ZBf0ICf9dAf0bC@4IGQ9bFfP[EJ!!I!J#TVr"rrL 3!!%!#*3Krm"mRL0iI,mVH#JH!!"!JJ!-1'!!#NJ!!&L!(J)8,!!!CN##!#"r`r0 i5!!Bq@!!!!"mB!Ge3))!$$KJ!!K)!!!`+"m!!%'#!#3iB!$r5!!)%@!!!!#3!(m !!)"r!!"ra20i5!!FmB""!"3iB!!!J!%!5$JK!%"m#!1QZm(rq%k!!#!!N!BJ3B! #!*!&N!!!$#jMBepRCA4IEQ&YC3!!I!J#TVqKrr53!!%!#*3Krl"mI4YiI*iMH(b r+hJS(J!!3B)!&#JI!!""JJ!-+"d!!%##!!`iB!!+5!!!M)!I!!!S!!!!3))!-$K J!!K)!!GaB!!!!*!!I`!!J(m!!#J$!!"!JJ!-1'!!"NJ!!&b!(3!!N!!$!!#!I`! !J!-!!#J!!!"!JJ!J5!!(U@!!!!!i!!!!N!!I!!#3!"i!!$KJ!!0)!!!SI!-$H(r %mhK)!"5eB!!!!)#I!!#!C!!!J!-#)*!!"!!!1'!!!)!"!&Ji)3"3I!J$TVZKrr4 1J!!J!*!')%'!!`#3"GJ!%5jMBepcCA&ICQ9dBfKI6N0c!(`)!UDrSIrdN!!"!!L 8)Iq`I*dMH(bq+hKmhc0i+"d!!%'#!"3S(`!!3B)!$#J$!!"!JJ!-1'!!#NJ!!FJ S(J!!3))!$$KJ!!C)!!'iJ"d#&#`!!'C!JJ!JIk2VH%J!&bPJ!!!!I'!(G8##!!` iB!!)5!!"N!#!(`!!+!!!!%##!%3iB!!)5!!'2@!!!!#3!(m!!)"r!!!S!`!!3)) !$$KJ!!C)!!&J1!!!!*!!!`!%5!!!&)#I!!#!C!!%1!-!!C!!"!!%J(m!!)#$!!5 S(3)%I!3!!%#!!"b!I3))9)!31RaM!#k!!`!!,!!!Bd'#rmL!I`!!J)-!"+JG!J4 m"!!!3B!!)%J!"M&J!!!!1!!!!*!!(J!!N!!I!!!iB!!$5!!!k)"p!JK8J"!kI'- !,S!$!!!X!!!"3))!I$KJ!!K)!!@*B!!!!*!!IJ!!J"i!!#J!!!"!JJ!-1'!!"NJ !!+`iB"f!5!!&C@!!!!#!RJ!!N!"N!!5!IJ!!J'-!"#J$!!"!JJ!-1'!!"NJ!!)# ![3))J*m!!)!%!!48!"!kI)8!,S#%!!3iS"f!5!!D4B""!"4)!!"%,!!!!N##!#b !!`!%N!!"!$`i!!!#N!!"!$L!B3!iJ)%!2(r&mhK)!!YYB!!!!%J!!"3i!!!!N!! H!!!iB!!35!!!')#I!!#!C!!%1!-!!C!!"!!%1'!!!)!"!&Ji)3"3I!J$TVZKrr4 1J!!J!*!')%'!!`#3"!)8!"-ZBf0IFf9aAfCPG'0SAf0bC@4c!!!!I!J#TVpKrqb 3!!%!#*3Krl"mI"YiI*XMH$ZJ!!"r[qYi+"`!!%##!!`iB!!+5!!!d#JE!!"!JJ! -1'!!"NJ!!-#!I!!)1!-!!93$%$T)!"N9J%%!&*!!H`!!J"X!!#J!!!"!JJ!-1'! !"NJ!!*5$R!!!5!!!G$KJ!J4)!"MTJ%%!&)#E!!"rr[YiI'6a,S"l!!"mBr!Z+!- !!%##!!`iB!!'5!!!A(q%ihK)!"M4J%%!&)"l!!"mBr!Z1'-!rcLF!34)!"LjJ%% !&)!F!3#!H`!!I'2`,T!!!`)!Jj`#)$Zp!!%lr`!%+"`!!%##ri`iB!!!J*X!!&H J%$TmC!%ZJ!%!@$JK!&"m#!1QZf(rl%k!!#!!N!BJ3B!&!*!%!4!!$bjMBepRCA4 I6N0ID@jQE`!!!(`)!UD3!!%!#*3Krm!S"!!!3))!$$KJ!!C)!!!8I)-MH%J!!k& J!!!!1'!!!)!"!%Ji)3"!I!J$TNk!!#!!N!BJ3B!!N!Bm!")ZBf0ICR*PC9p`FQP ZBfP`B@am#!+QN!!"!!L8)Ir!+!3!!%##!!`iB!!'5!!!&(b$)hK)!!0"B!!!!$K J!!#!!3")1#%!3(`)!kC1J!!J!*!')%'!!*!'2!!0,Q0MAfCbC@9IEQ&YC3"m#!+ QNq(rr*!!!3!)P#(r`(bI)hJS(`!!3))!$$KJ!!T)!!!NJ(m!!%J!&"eJ!!!!J(m !!%J!!Y&J!!!!1'!!!*!!I`!!J!%!5$JK!%"m#!1QJq(rr%k!!#!!N!BJ3B!"!*! &@!!1,Q0MAfCbC@9IBh*PC(0m#!+Q[m(rq*!!!3!)P#(r`(bH)hJS(J!!3))!$$K J!!T)!!"%1!!!!(`I!hK)!!!BJ(i!!(aMq#j)!"C*J%%!&$[r!!5!IJ!!I!2i,LJ !!!"!J[rJ5!!@,B""!"3iB!!!N!"q!!#!!3")1#%!3(`)!kDl`Iri6S!!)!#3"L" "J!)!N!9i!"!ZBf0ICR*PC9p13epTEQC[!!"m#!+Q[m(rq*!!!3!)P#(rX(bI)hK m[LYi+"m!!%##!!`iB!!-5!!"*$KK!$K)!"@*J%%!&)!I!K3X!!"N3B)!'$KK!$J iR`)B1+%!3%J!&B'!33!8,"i!!N'#!#a!J!!3,"i!!8#!!"4)!!$8,"i!"%#!!-a )!!")1!!!C*!!(`)85!!!a)!I!K3X!!"N3))!)$J!!'@3!"m#&)"K!$L!!3!mN!" r!KL3!"m#(%J!!*`X!!"Q3))!P$KJ!!K)!!#3!)!I!K3X!!"N3))!)$J!!'D3!"m #&)"K!$L!!3!mN!"r!KL3!"m#(%J!!'3X!!"Q3))!')J"!%!S!!!!3))!$$KJ!!K )!!"-J"m#&#`!!'9!JJ!mL!%!3#J!!!""JJ!J1!!!CT!!(`)8J'%!1)!"!$b3!(m #'*!!(`)F5!!!&$KJ!!K)!!!31'!!$%J!!!JiB!!!J!%!@$JK!&"m#!1QZm(rq%k !!#!!N!BJ3B!#!*!%!9`!%#jMBepXEf0VAh*PFA9PFh3!!(`)!UDr`IriN!!"!!L 8)Ir!I(iEH%J!&-Q!33!8I(mEH#JI!!""JJ!8Iq2lH(r%mhK)!"6GJ%%!&(rMqhL !!3")1#%!3(`)!kDl`Iri6S!!)!#3"L""J!)!N!93!!XZ6Q9h8f&QC9"dFJ!!!(` )!UDr3IrSN!!"!!L8)Iq`I(SEH$Z#!FSlSJ'p1m)"Vi2L!%4)!"3"J%%!&(al'hJ S'J!!3))!6)!I!!!X!!!"3))!)(r$mhKrT1Yi1+!!*cM!!!&)!"1jJ%%!&%J!!#3 X!!!%3))!((r$mhKrT1Yi1+!!*cM!!!&)!"19J%%!&#`E!!""J3"-J"m!!#`!!!& !JJ!JIi2MH(qNkhJiS!!S1-!!!8J!%fQ!33!85!!!*#`!!!4!JJ!FIi2MH(qNkhJ iS!!S1-!!!8J!%d@!33!8Id26H$L!!!"rCGYi5!!6BB""!"4r3p0i1)!!!(pPfhK )!"00J%%!&(p$dhKrC0Yi5!!69B""!"4r3p0i5!!5kB""!"5!!3"B1#%!8(`)!kD l3IrS6S!!)!#3"L""J!B!N!3"+!!2,N4TFh"[Ff96B@CP8(4b!!!!I!J#TVr"rrL 3!!%!#*3Krm"mIKYi5!!6EB""!"4mIaYi+"m!!%'#!"4rirYiIm6cH%J!%b'!33! 8Iq2lH)!"!%Ji)3"!I!J$TV["rrK1J!!J!*!')%'!!J#3"9!!$Lj1CAG6B@CP8(4 b8hPcI!J#TT2Krrb3!!%!#*3Krm"mIaYi1')"ecL#!Ef!SJ"%+"m!!%##!$b!"3! !,!!!!8##!"JiS!"31-!!!8J!%K@!33!85!!!(#`!!!4!JJ!81+!!8$M!!!&)!"( jJ%%!&$J!!!#`(`)%1!!!#V!I!JBiB!!S5rrr(C!!I`))J(m##)!"!%Ji)3"!I!J $TS2Krra1J!!J!*!')%'!!3#3"C3!$LjZCAG$FQ9N3R9QCQ9bI!J#TT2Krrb3!!% !#*3Krm"mIaYiN!#"!&b3!+%!B*!!`3"N1')"iML#!Ef!SJ"%+"m!!%##!$b!"3! !,!!!!8##!"JiS!"H1-!!!8J!%9@!33!85!!!(#`!!!4!JJ!81+!!AMM!!!&)!"% jJ%%!&)!"!&b3!"m!!)!"!'#3!"m!")!"!'3S!!!!3))!%$KJ!!#3!(m!#%J!!$L !B3"J5rrq4C!!I`!)J(m!##J$!!"!JJ!-1'!!"NJ!!"L!J3"NJ+%!B%J!%BQ!33! 81'!!!)!"!%Ji)3"!I!J$TS2Krra1J!!J!*!')%'!!3#3"G`!$#jMEh"j4'&dB8p LDJ!!I!J#TVl"rpL3!!%!#*3Krk"mGaYiI*JMH$Z#!KSlSJ),1X)"qcKL!Hil`J' pJq)!4$YJ!!!S'!!!3))!4)!I!!!X!!!"3))!((r%mhJiS!"d1-!!!8J!%%f!33! 85!!!)#`!!!4!JJ!BIm6cH$LJ!(3i`!!"5!!3,B""!"4qqVYi+"S!!%##!"Ji!!! !N!!B!!")!!(F5!!!#$Yl!!'!'J!!1eS!"#J!!!"!J[r`1"X!!93$%$T,rrdYN!" i!!"mH4Yi+"N!!%##!%b!(`!!,!!!!8##!#"q`l0iIm6cH$LJ!(`i`!!"5!!2[B" "!"4)!!!N,!!!"%##!"aq`l0iIm6cH$LJ!(`i`!!"5!!2QB""!"3S'3!!3B)"@(l kZhK)!!%d1'!!$%[rr,f!Q!!!N!"N!!#!H!!!J!-!!#J!!!"!JJ"-J"m!!#`!!!& !JJ!JIk2VH(r%mhJiS!#$1-!!!8J!$d@!33!85!!!*#`!!!4!JJ!FIk2VH(r%mhJ iS!#$1-!!!8J!$b'!33!8J(J!!)"M!!!S!`!!3B)!f)#A!!!iS!!-5!!2UB""!"5 !H!!!J'-!!)"M!!4,rr`YJ*J!!)#%!!#3!'3!#)"i!!#!B`!!J!-!##J!!!"!JJ" -J"m!!#`!!!&!JJ!JIi2MH(r%mhJiS!#,1-!!!8J!$Uf!33!85!!!*#`!!!4!JJ! FIi2MH(r%mhJiS!#,1-!!!8J!$SQ!33!8J(J!!)"M!!#!B`!)+!-!!%'#!$b!Y`! !J)8!#)#P!!4)!!m*J%%!&$XB!!3l@J!%J"S!!#J!!!"!J[l)1'!!!&GJ%$TmH3% ZNcJ!!)!"!'Ji)3"JI!J$TVV"rpK1J!!J!*!')%'!#J#3"!+!!!iZBfp`H84KG'& "FR*KHA`)!UDrSIrdN!!"!!L8)Iq`N!"K!'L3!)%!E(bp+hL$`3"X+"d!!%##!!` iB!!'5!!"2$KJ!!K,rrX0N!"p!!#!(3!!+!!!!%##!!`iB!!'5!!"($KJ!%a,rrV YI(mEH#JI!!"!JJ!-1'!!"NJ!!3!iB!6L5rrkdC!!I`!!J"m!!#J!!!"!JJ!-1'! !"NJ!!1!iB!6L5rrkXC!!I`!%J"m!"#J!!!"!JJ!-1'!!"NJ!!-#!I`!!J*i!!$L J"0p)!!iKJ%%!&)"r!!5!RJ!%1+!%hdJ!$Jf!33!81(m!#)#H!!L![J!-J0i!%%[ rqi'!(J!8N!!I!"5!(J!BN!!I!"L!(J!FN!!I!"b!(J!JN!!I!##!(J!NN!!I!#5 !(J!SN!!I!#L!IJ!X1*m!,%[rr%%iI`!`J*i!-)#q!$5!hJ!i5rrl-6Kr!$b!RJ! mJ,i!3)$H!%4,rrXG1'!!!*!!I`")1!!!!S#G!!#3!!3!!)#G!!#6j!!%J!%!@$J K!&"m#!1QZk(rp%k!!#!!N!BJ3B!$!*!%!A`!#bjMEh"j9M9$FQ9N!!!!I!J#TVr "rrL3!!%!#*3Krm#3!'%!@*!!J3"FI,iVH#JH!!"!JJ!-1'!!"NJ!!'JiB!!)5rr jGC!!IJ!!J(i!!#J$!!"!JJ!-1'!!"NJ!!%Ji!!!"N!!$!!!iB"f!5rrj6Aar'hJ S(`!!3))!$$KJ!!C)!!!NIq2lH)#"!&`iS"f!5!!-NB""!"5!IJ!!Nq-!"$KJ!!# !!3")1#%!3(`)!kDl`Iri6S!!)!#3"L""J!)!N!@N!!XZBfp`H9Bd3h*PC!!!!(` )!UDr`IriN!!"!!L8)Iq`I(iEH*!!J3"XN!#K!(!li!!!Nq%!1#JH!!"!JJ!-1'! !#NJ!!1L!!3"X,!!!!8'#!"3X!!!#3B)!$$KJ!"")!!$-U(i#"$J$!!'`(J)%U(i #"+JH!JCm!`!!3))!@&3!#$b`(J)'U"i#"P3$%$T,rrKPI(mEH#JI!!"!JJ!-1'! !"NJ!!)KrirYiJ*i##+JH!JCm!!j`I!!"P&3&%$T)!!ZGJ%%!&)"q!JK,rrEGNri ##)"K!'`X!`!"3))!&)#"!(!iS3!i5rrqD8J!!#3X!`!#3))!&)#"!(!iS3!i5rr mY8J!!!`iB!!35!!!))#K!$L!RJ))U(i#"$J$rrp8!"!kI+3",MKJ!!#!!3"B1#% !8(`)!kDl`Iri6S!!)!#3"L""J!)!N!3",!!4,Q0bC@4#G@CQCA**ER0PFR3!I!J #TVqKrr53!!%!#*3Krl"mIaYiN!#"!'b3!+%!F$[!!!!S(`!!3))!$$KJ!!T)!!$ !IphcH%J!!+L!I`))I)2`,S"N!!#!K!!%J+%!E)$"!(")!!(4B!!!!(aJ"h9"JJ" iJ(m##(r$m#jr`r0i5!!('@!!!!"r`r0i5rrecAqPkhK8Sa!k5!!!))#I!JJi"3! "9!!31R`%!#jm""NZ1+8!!6KM!!5SR`)%1!6rrh`&!!""J2rB1)!!!)"r!JK8!"! kI)-",UKr!J3i!rrrX"m#"%J!!"Jl[3!"1pi!"+JI!J4m(3!!3B$r9$KJ!!#!!3" B1#%!8(`)!kDlSIrd6S!!)!#3"L""J!-!N!3"!!!4,Q0bC@4#G@CQCA*5C@e[GQ8 !I!J#TVq"rr#3!!%!#*3Krl"mI"YiI*dMH$KL!M%iJJ'pJ+)!4$J!!!#3!!%!1#J G!!"!JJ!mJ!8!!#`!!!&!JJ!B1+!"5$M!!!&)!!MPJ%%!&%J!!"`X!!!%3))!&$L J!8Ji`!!"5!!)bB""!"3S(3!!3))!$$KJ!!a)!!"-1m!!!(rImhK)!!!SJ(d##(` $q#k3!!%!1(q$ihJiJ3!i5rraJ@!!!!!lhJ!"1rm!"+JG!J4m(J!!3B$re)"p!JK ,rr4P1'!!!)!"!&Ji)3"3I!J$TVZ"rr"1J!!J!*!')%'!"!#3"GJ!%LjNDA0`Eh0 P3h*PC%*eCQCPFR`)!UDr`IriN!!"!!L8)Ir!N!"K!&L3!)%!A*!!S3"JN!$"!'5 $`3"F+"i!!%'#!"#$i3"N+"m!!%##!!`iB!!!5!!!k)"K!&L!!3"JI!-!!%'#!!` iB!!!5!!!d#`$!!&!JJ"X1(i!!6LI!!&)!!LjJ%%!&#`$!!"!JJ"-1(i%icLI"10 )!!LKJ%%!&#`$!!"!JJ!d1(i6L6LI%iP)!!L*J%%!&#`$!!"!JJ!FJ(iBI)!I'(a m!`!!3))!$$KJ!!&)!!"S1'!!!%J!!'!X!`!#3))!9)"q!!#!R`!!5!!)5B""!"3 X!`!!3))!0)"q!!5!R`!%5!!)-B""!"3X!`!!3))!()"q!"L!(`!BI!-!!%##!!` iB!!"5!!!%$KJ!!")!!!)1'!!!)!"!%Ji)3"!I!J$TV["rrK1J!!J!*!')%'!!J# 3"!%i!!JZBh*PC'0YF!!!I!J#TVq"rr#3!!%!#*3Krl"mI4YiI*`MH#JF!!"!JJ! -1'!!"NJ!!C`iB!)S5rrb0C!!I!!!J"`!!#J!!!"!JJ!-1'!!"NJ!!Aam(`0iIq2 lH(qNkhK)!!F"J%%!&)!G!3#3!"m"!$Kr!33iR3%%5!!'kB""!"5S(3)%X"m#"+J G!JD`(`)'1!!!!CJI!K#S(`)'9!-31N[rmFf3!(m##)!I!JJS!!!!3))!$$KJ!!C )!!%81m!!!(rFmhK)!!$`J(d##(b$i#k!C!!!,!-!!8##!)!iB!!)5rraMB#I!JK mC1%ZJ(m##(aMi#iS!`!!3))!$$KJ!!C)!!$-1!!!!C!!!`!!1'!GJ%[rm9f!R`) )I)6J,T!!C!!%J(m##(aMi#k!B`!%+!-!!%##!!`iB!!'5!!!P)#G!JKmK1!ZJ)3 !"$LJ(B")!!C&J%%!&%J!!&JX!`!#3))!')#%!!5!(`))I+$L&%[rphe)!!!m,!- !Bd##!$3iB!!)5rr`lB#I!JKmC1%ZJ(m##(aMi#iS!`!!3))!$$KJ!!C)!!!X1!! !Bj!!!`!!1pi!!6ZF!!5S(`)%I"i!!%'!r``iB!!!N!"r!L53!(m#))!"!&Ji)3" 3I!J$TVZ"rr"1J!!J!*!')%'!"!#3"!(8!!BZC(9`6N0m#!+Q[m(rq*!!!3!)P#( r`(aq'hKrhr0i+"m!!%'#!#a)!!!8J(m!!)"M!!K,rr#j1rm!")!I!!!S!!!!3), rk(r$mhK,rr#KJ!%!5$JK!%"m#!1QZm(rq%k!!#!!N!BJ3B!#!*!&A!!4,Q4TFh" [Ff9%BA4K3A*bBAN!I!J#TT2Krrb3!!%!#*3Krm"mIaYi1')#2$L#!Ef!SJ"%+"m !!%##!&#!"3!!,!!!!8##!"JiS!(#1-!!!8J!"$@!33!85!!!-#`!!!4!JJ!S1+! "`MM!!!&)!!3CJ%%!&%J!!"4rirYiIq6lH%[ri4eJ!!!!J"m!!#J!!!"!J[rS1'! !!)!"!%Ji)3"!I!J$TS2Krra1J!!J!*!')%'!!3#3"CJ!#bjQFQ9P6N0-DA0d!!! !I!J#TT2Krrb3!!%!#*3Krl"mIaYi1')"ecL#!Ef!SJ"%+"m!!%##!$b!"3!!,!! !!8##!"JiS!(51-!!!8J!!hf!33!85!!!(#`!!!4!JJ!81+!"dMM!!!&)!!0KJ%% !&$KK!$K)!!-0J%%!&(aJ"c9"JJ!-1'!!!%J!!%#!(`)8,!!!C%'#!#JiB3!i1*m #'$LK!%")!!,eJ%%!&(aJ"c9"JJ!81'!!!%J!!"!i!!!!Q!%!3)KK!%#!!3"B1#% !8(`)!kD$iIrm6S!!)!#3"L""J!%!N!A-!!XZDA0-Ef0V6h9bF`!!!(`)!UDr`Ir iN!!"!!L8)Ir!I(iEH$KL!NmiJJ'pJ+)!4#JH!!"!JJ!mJ!8!!#`!!!&!JJ!B1+! "jcM!!!&)!!+4J%%!&%J!!"`X!!!%3))!&$LJ!HFi`!!"5!!#GB""!"5!(J!!,!! !!N##!'L$rJ!%J(m!!%[rlNf!I`!%5rrZ4B"r!"!S!`!!3B)!#%[rlM@!I`!i+!- !!%'#!!K,rqiPJ(m!4#J$!!""JJ!)5rrZ&B"r!%JS!`!!3B)!#%[rr5'!I`!X+!- !!%'#!!K,rrd4J(i!"%[rlHdiB!!!J!%!5$JK!%"m#!1QZm(rq%k!!#!!N!BJ3B! #!*!&m!!A,Q0MAfCbC@9IBh*PC&pTER4PFQjKE(-!!!"m#!+QN!!"!!L8)Ir!5!! !U@!!!!"mB!Fe3B)!#%J!!"!i!!!!J))!)*!!"!!!J!%!5$JK!%"m#!1Q6S!!)!# 3"L""J!#3"M`!%bj*EQPdD@&XDATP3f&MD'9-D@)!!!"m#!+QN!!"!!L8)Ir!5!! !R@!!!!#!!3")1#%!3(`)!kC1J!!J!*!')%'!!*!'*!!5,P4PFQeTEQ&dC80KBfK P6'PLI%-6H%k!!#"m#!+QN!!"!!L8)Ir!5rrrlAaT'hL!BJ"JJ))!A$LL!!!i`J* GJ1)!8)%#!%a)!!"CJ%%!&)##!+53!'3!!%[rf)eJ!!!!1'!!!)!"!%Ji)3"!I!J $TNk!!#"m#!+QN!!"!!L8)Ir!J')!T)"M!!")!!!aJ%%!&)!"!%Ji)3"!I!J$TNk !!##"JJ"!N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!2*!!33!8J!`!!)"-!!4m#31 Q6S!%))'#!"L3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!8N!""!"5!$!!!J%`!"(` *!kC1J!3JJB)!$*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!%L3!%%!&)!-!!#!6!! %I!N$TNk!"##"JJ!3N!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!1*!!33!8J!`!!)" -!!4m#31Q6S!%))'#!!53!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!FN!""!"5!$!! !J%`!"(`*!kC1J!3JJB)!-*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!!L3!%%!&)! -!!#!6!!%I!N$TNk!"##"JJ!SN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!!*!!33! 8J!`!!)"-!!4m#31Q6S!%))'#!#b3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!NN!" "!"5!$!!!J%`!"(`*!kC1J!3JJB)!0*!!33!8J!`!!)"-!!4m#31Q6S!%)!!!*cL !!!"B!*!'*j!!J!!!,!#3#8iL+@`#)LP8!L)#ABB#!5PX)J'GJJ)4!Bd"K!&h!Nm #2!)a!KS##`(l!Hi"iJ(A!FS"[3'[!+`"D!3L%ML'!K84R"%N%-J3D!md$2J,r!Y -#U3*i!Lm"rJ(*!E-"8`%9!-S!B`"#!!F*ZJL*S3%,Ne*9#"*,e-J6@&M4'9f!5# "CJ`K+'jKE@8J)6dJ-#N)3d0KBfKP,Q-2)5JUD'&ZC'aP)#%p)$!T%5%SF(*TEQ0 TF'&X)#%p)$!T$5%SFf&QC9!J)6dJ-#N-3d0KBfKP9A4TE#jM$#%SFfPkC5!q)$" -+3SK+'jM)#%p)$!T#b%SEf*U)#%p)$!T$#%SC'9cG#!K25!`+3pbCA4NCA0d)$d p)%j96%`1+LTNCA0d)$dp)%j96%`@+#SUC'9cG#NY2Q4KG'%J26dJ6P9-6!TZBb! p25"198a-%L%SBfjdFQa#E'pMDb!K25!`+3dK+'0bC@4c)#%p)$!TFGB!!!%!!!! "B!!!!'!!!!!b!,V"!*!%2S!!CL!!ZZ%!N!3qK3#X)!$p1`#3"B!!E!!!Z[d!N!@ !!(J!!,X2!*!%2S$rr`!!Zam!N!3qMIrr!!#l3`#3"$k-rrm!!,Yr!*!%2SArr`! !qmF!N!3qJ2rr!!#lZ`#3"$k0rrm!!,[[!*!%2Scrr`!![#-!N!3qKIrr!!$lN`# 3"$k!!))J!,aA!*!%2S!!M3!![&m!N!8"rrm!!2Xr!*!%2SArr`!!r*d!N!Err`! !r@N$VL"F!d0@8`T8BA0V)%jKE@9c$%0A3eC6)&"KEQ9XF`i!!!"F!*!,!3#3%`& `Gh"M!*!6!3#3%6`168P8Ak9$3f&MD'9-D@)!N!8"!!!!!@!!!!"J!!!!-J9@1G! d*J!!!"`!-J!!BfCbC`!!!!S!!2rr!*!%"9Bi[&YF: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/bin/CCacheLib.PPC.debug b/src/mac/libraries/CCache API/bin/CCacheLib.PPC.debug deleted file mode 100644 index c72e54adb..000000000 --- a/src/mac/libraries/CCache API/bin/CCacheLib.PPC.debug +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0) :%d0$B@0SC8aTBLj38%-ZC'9LG@F!FfKXBMq3"!#3"$LS!!!"PV5C5Qpj)A"PCQC `Gh"M!!!!!E*6cTi!N!d$!!)!N!6rN!3!N!Ba`!!!-F!!!$(!!!!&J!!%"!$rN!3 !N!B#D3!!!Q8!!!&S!!!h3!)%"!$rN!3!N!i%mJ!!!)!%"!3!N!ArN!3!N!F"!!! "D!!!!!%!!!&J!!!!"3!!!"8!!!!"!!!"%!!!!5!!!!1-!!!!"!!!!"8!N!m+!*! ,$3#3#`%!!!!+!*!()`!!!!%!!!!"!!!!!J!!!!X!N!Fl!*!,!J!!!!d!N!G8!*! ,"J!!!!m!N!3#!!"R!J!!F!)!!(S#!!#(!J!!NJ)!!*d#!!#Q!J!!X3)!!,d#!!$ 2!3!!eJ%!!1)#!!$[!J!!r3)!!4-#!!%R!J!",J)!!68#!!%p!J!"4!)!!8X!!3# 3"3J!N!4+&%!"3J&!!8)33J#!!dB@5@jdCA*QB@0P6'PL!%e*9&qP3d0KBfKP4fa [BQ&XFdaTBJ"0594IT84PBR9RCfPZCdaTBLjNC@*eC`"0594IT8e*9&*eER4TE@9 -D@)ZC'9LG@F!68P8Ak90594$6'PL,Q4PBR9R!&0jFd*bC@&V!%jPGe"dFP0jF`" 9EQK[E'40C@e[FRN!5'pXC%ePE@pbH3"%DA0`Eh0P8(4b!%4PBR9R8h4b!%GPG&" dFP0THQ8!8f&YC9"bEf0PFh-!4f9d3h9bFQ9ZG&"bEf0PFh-!6Q9h8(4b!'G$ER4 bE%*XEf0V!'G%C@*eCe0TCfjKE!""E'9bG&0TCfjKE%&d!&pIG@jbC@GTFh4PFPp QFQ&RE@9ZG!"IAh*PCfPcG'9bAfCbB@GYC@jd!(0dFQ0YF!"YC@eMF(N!Fh4bEQ0 `H3"cG(*MF(N!Fh4bE'9Z!'ePEA0PG!"MBepRCA4IBh*PC&pfCA*cD@pZBf0IC'9 cG(*[H@0MAfGPG&pMD'&ZCf9IG'PYC@0MAfCbC@9I6N0ID@jQEf0MAf0bC@&dC@0 MAf0XEh0PBf0ICf9dAfjKE@9MBepQFQ9PAf0bC@4cBf0IFQ9YEhCPAf0bC@4MBep QFQ9PAh"bD@jMDA"KE'0MAfp`C@jMBepcD(9dC'phEQ0MAh0PG&p`FQPZBfP`B@a MBepcCA&ICQ9dBfKI6N0cBf0ICf9dAdj$AfPZCQpMBepTEQPdD@&XDATPBf0ICf9 dAh"bD@jMDA"KE'0MAh0PF9pQCA4MD&pMFQ9NFf0MAh0dEh*PBf0ICR*PC9pZB@e PBf0IE'pMDepbCA&eCA0d!*!("!!!!!`!!3!)!!3!!!!'!!J!"J!)!!J!!!!+!!3 !#J!!!!X!%!!,!!`!$`!!!")!"!!5!!!!%`!)!"-!%qq*!!UDh`!569F!$c0A!!P -)3!)*Xm!#cEk!!h1V`!1jP-!%IJ'!!F66!!,2Ad!%)`+!"##X3!1ZFB!$FMP!"$ -#`!5#&i!##F0!!aR@J!2'"i#!!&5!!!"!!!"!J!"C3!!!6!!!3)!!@m!!!%S!!% #!!'"!!!!`!!"!J!"N!!!!!&)!!%#!!'C!!!"1!!"!J!"S3!!!2J!!3)!!D`!!!$ )!!%#!!'j!!!"'!!"!J!"a`!!!0J!!3)!!GJ!!!&!!!%#!!(I!!!"8!!"!J!"kJ! !!4!!!3)!!IS!!!$`!!%#!!)+!!!!i!!"!J!#'!!!!9J!!3)!!L8!!!%)!!%#!!) e!!!!k!!"!J!#4`!!!5!!!3)!!Nm!!!$3!!%#!!*E!!!!Z!!"!*!1I!J#TT!!!3! )P#(r`$JK!%#!!3!)I!J$TNk!!#"m#!+QNq(rr*2"rrL6SIrdNi(rm*!!!3!)P#( rX(ar'hL3!)%!E(bm+hKmh60iJm)!+)"q!!!S!`!!3))!B$KJ!"")!"PeB!!!!*! !I`!!J*m!!#J%!!"!JJ!-1'!!"NJ!!(`iS!!!J0m!!*!!TJ!%J2m!!*!!T`!!13! !!)%r!!#4#3!)18!!!)&r!!#45`!-JCm!!*'H!!")!!!-J(i!!*!!I`!!J)%!E#` %!!&!J3!-1'!!#8J!!#JS(!!!3B)!$$LJ!!'3!,`!!#JG!!""JJ!-J-)!X*!!h3! !1'!!!)!"!&Ji)3"3I!J$TS2Krrb$`IriJk(rp)1"rr"1J!!J!*!')%'!"!#3"IJ !$LjMBepTEQPdD@&XDATPI!J#TT2Krrb3!!%!#*3Krm"mIaYi+"m!!%'#!#b!I`! !+!-!!%'#!##!I`!!5!!U)@!!!!#!I`!!5!!@T@!!!!")!!!-1'!!#NJ!!"!iJ!! !N!#I!!!iB!!!J!%!5$JK!%"m#!1QJq(rr%k!!#!!N!BJ3B!"!*!&E!!-,Q0MAh0 SGA4NEhGZ!!"m#!+Q[f(rl*!!!3!)P#(rX(aq'hKmR#0iN!#K!("mh60iN!$K!(K p'd0i1q!!!#JH!!"!JJ!-1'!!#NJ!!8JS'`!!3))!$$KJ!!a)!!%i1'!#+%J!&m& J!!!!I(mEH#JI!!"!JJ!-1'!!"NJ!!4JS(!!!3B)!'(q$ihK)!#pCJ%%!&#J$!2p "J!!-1'!!!8J!!24rirYiIi6MH%J!,UQ!33!8+"d!!%'#!"KrSqYi5!![*B""!"3 S!`$r3B!!$$KJ!!a)!!$!1(m""(qNkhK)!#jeJ%%!&)"K!(L3!(m#$$L!!!#`R`) %J+%!F*!![`%!1-!!!TMI!K!ii!"NN!$r!K4rirYi5!!AM@!!!!#3!(m##)%I!JJ S#!!!3))!$$KJ!!C)!!"NJ6i!##`*!!"!JJ!F18!!!*&I!L54A`)JNri!!*2q!!4 )!!!JJAi!"*2V!L#"RJ!%NCm#*$KJ!!#3!(m#)*2q!!5!RJ!)1)3!!C!!RJ!)J,i !$$LP!!'3!,i!$*2l!!!iB!!!J!%!@$JK!&"m#!1QZf(rl%k!!#!!N!BJ3B!&!*! %!C3!#LjMBepMFQ9KG'9m#!+Q[Z(rh*!!!3!)P#(rS(ah'hKmQL0iI,NVH(ci1hJ lSJ'-1m)"Ii2L!#`lJ!!!1f!!!#JA!!"!JJ!-1'!!#NJ!!3`S'!!!3))!$$KJ!!a )!!$m+"S!!%##!)5!I`!!,!-!!8##!#"r`r0iIk6VH$LJ!+Xi`!!!5!!XFB""!"4 )!!"FJ*m!!#`%!!*!JJ!8Im2cH%J!,'f!33!85!!!3)#r!!!X"3!$3))!%%J!,'f !33!85!!!+)$I!!!X"J!%3))!((r$mhKrT1Yi1+!!UcM!!!&)!#`9J%%!&)1A!!" )!!!dId26H(q%ihK)!#dGJ%%!&#`$!!"!JJ!BJ2`"!(`C1!"!JJ!-1f!!!8J!!!L $R!)J+"`!!%'#!""rD!Gd,!J!!%'#rm"rD3Gd,!N!!%'#!"#6Q!!!1'!!!%J!!"! j3!!!N9J!!$KJ!!U!!3"S1#%!B(`)!kDkiIrF6S!!)!#3"L""J!N!N!3"B!!),Q0 MAfp`C@i!!(`)!UDr3IrSN!!"!!L8)Iq`I(SEH(bF)hJl`J'91k)"M)2L!#`lB!! !+"S!!%##!!`iB!!+5!!!k#JF!!"!JJ!-1'!!$%J!!0L!I!!!+!-!!%##!)5!R`! !,!3!!8##!#"r`r0iIk6VH$LJ!-di`!!!5!!UrB""!"4)!!"FJ,m!!#`&!!*!JJ! 8Im2cH%J!+[Q!33!85!!!3)$I!!!X"J!$3))!%%J!+[Q!33!85!!!+)$r!!!X"`! %3))!((r$mhKrT1Yi1+!!c6M!!!&)!#UKJ%%!&)%F!!#*#!)3I3J(G#`)!!&"JJ! -1'!!$NJ!!$#$I!!!Id26H(pNfhK)!"r0B!!!!(pMfhK)!")GB!!!!$NJ!!#42!! !1'!!!)!"!&Ji)3"3I!J$TVY"rqK1J!!J!*!')%'!"J#3"!%`!!NZBf0IBfa[Ff8 !I!J#TVmKrq53!!%!#*3Krk"mHKYiI*XMH$[#!C8lSJ'-Jq)!,$Z!!!!S'J!!3)) !$$KJ!!T)!!'!+"X!!%##!!`iB!!-5!!"F)"l!!!S!`!!3))!K)#I!!!X"!!"3)) !)(r$mhKrT1Yi1+!!kcM!!!")!#QaJ%%!&%J!!&b![`!!,!8!!N##!"4r`r0i5!! TVB""!"4)!!"!J0m!!#`'!!0!JJ!35!!TVB""!"4)!!!SJ2m!!#`(!!4!JJ!FIm2 cH(qNkhJiS!$V1-!!!8J!+9@!33!8JjX!!)%F!K3X#!"N3B)!*(q$ihK)!#9jB!! !!(aM"h3X!`!!3))!$$KJ!!K)!!#dJ6`#*#J*!!"!JJ!NJ9`#)*&D!!#"I!)J+!X !!%'#!"!jJ!!!J(`#)*'$!L5!R!)J+!3!!%##!#5![!)NN!#k!!5!h!)N+!B!!%' #!"!ii!!!J4`#**!!k!)JJ6`#*#J*!!""JJ!SJ9`#)#J+!!""JJ!FJA`#*)'F!L# 4E!)NJ(`#))#F!L53!'3#)$LJ!!'B[!)3Id26H(pNfhK,rrdCI(NEH)$D!!`iaJ! "N!$D!!ar)mYiJ!%!D$JK!'"m#!1QZb(rj%k!!#!!N!BJ3B!(!*!%!FJ!#bjMBep NCA0dFQpj!!!!+!-!!%##!!`iB!!+5!!!)#J%!!""JJ!8J+-!$*!!T!!!1'!!!%J !!!JiB!!-6S!!)!#3"L"!!*!(-!!6,Q0MAfGPG&pMD'&ZCf9IG'PYC3!!!(`)!UD 6iIrmNm(rq*1Krr53!!%!#*3Krl"mI4YiI*mMH*!!S3"`N!$"!(3l`!!!+"d!!%# #!!`iB!!+5!!!L#JI!!"!JJ!-1'!!#NJ!!(L!I`)8,!-!C%'#!$#!R`)8,!3!CN# #!"arirYi5!!MZ@!!!!"mB`Gd,!-!!%##!!`iB!!)5!!!3(rMqhL!J3"`J+%!G%J !'HeJ!!!!I(iEH#`H!!"!JJ!3J,d!#$LP!!'3!,d!#)$G!!`iaJ!"N!$G!!ar`r0 iJ!%!@$JK!&"m#!1QJq(rr)2"rrL$SIrd6S!!)!#3"L""J!-!N!AF!!NZBf0IFh4 [FQ8!I!J#TT2Krrb6`IriN!!"!!L8)Iq`I(iEH(bI)hL3!+%!F*!!`3"d1'!!!*! !B3!i+"i!!%'#!!`S(`!!3))!$$KJ!!T)!!"JJ*m#&#`%!'4"JJ!`J,m#&#`&!'C !JJ!FIq2lH%J!)XPJ!!!!I'-(G#`$!!"!JJ!-1'!!#%J!!#KrirYiJ)%!F)#K!(4 )!"TaB!!!!)$H!!`iaJ!"N!$H!!`iB!!!J!%!@$JK!&"m#!1QJq(rr)2"rrK1J!! J!*!')%'!!J#3"EJ!$bjMBepbC@e[GQ9IBh*PC!!!!(`)!UDr3IrSN!!"!!L8)Iq `I(SEH(bE)hL3!+%!F(cF-hJl`J'P1k)"M)2L!#`S'J!!3B)!$#JE!!"!JJ!-1'! !#NJ!!3!S(!!!3))!K)"r!!!X!`!"3))!)(r$mhKrT1Yi1+!"DcM!!!")!#@PJ%% !&%J!!&b!R`!!,!3!!N##!"4r`r0i5!!PSB""!"4)!!"!J,m!!#`&!!0!JJ!35!! PSB""!"4)!!!SJ0m!!#`'!!4!JJ!FIm2cH(qNkhJiS!&V1-!!!8J!*8Q!33!8J2X #&#`(!'4"JJ!`J4X#&#`)!'C!JJ!FIf2EH%J!)@9J!!!!I'-(G#`$!!"!JJ!-1'! !#%J!!%#"1`%!J8%!F(`*8!""JJ!-1'!!#NJ!!#JiH`%%Ii6MH$LJ!2p)!#AYJ%% !&)&k!!`jD`!"NAS!$$KJ!!#!!3"B1#%!8(`)!kDl3IrS6S!!)!#3"L""J!B!N!3 "9!!4,Q0MAh0PG&p`FQPZBfP`B@`!I!J#TT2Krrb6`IriN!!"!!L8)Ir!I*iMH(b r+hJS(J!!3))!$$KJ!!T)!!"`J(i#&#`$!'C!JJ!NIm2cH%J!)*PJ!!!!I'-(G#` $!!"!JJ!-1'!!#%J!!%3S(`!!3B)!1$KJ!2p)!!YYB!!!!*!!I`!!J*m!!#J%!!" !JJ!-1'!!"NJ!!"L!I`!!1*i""%J!*,'!33!81'!!!)!"!%Ji)3"!I!J$TS2Krrb $`Iri6S!!)!#3"L""J!)!N!@`!"%ZBf0ICf9dAh"bD@jMDA"KE!"m#!+QNq(rr*2 "rrL3!!%!#*3Krm"mRb0iI,iVH#JI!!"!JJ!-1'!!#NJ!!%b!I`)8,!-!CN##!#4 rirYi5!!Ia@!!!!"mB`Gd,!-!!%##!!`iB!!)5!!!)#JH!!"!JJ!-1'!!"NJ!!"# !R`%!N!#H!!!iB!!!J!%!5$JK!%"m#!1QJq(rr)2"rrK1J!!J!*!')%'!!J#3"B` !&#jMBepRCA4IBh*PC&pfCA*cD@pZ!!"m#!+QNq(rr*2"rrL3!!%!#*3Krm"mRb0 iI,iVH#JI!!"!JJ!-1'!!#NJ!!&b!I`)8,!-!CN##!#4rirYi5!!I%@!!!!"mB`G d,!-!!%##!!`iB!!)5!!!-#JH!!""JJ!N1'!!rdJ!#H9J!!!!N!"q!!#!IJ!!Iq6 lH%J!)cf!33!81'!!!)!"!%Ji)3"!I!J$TS2Krrb$`Iri6S!!)!#3"L""J!)!N!@ F!!`ZBf0ICf9dAfjKE@8!!(`)!UD6iIrmNm(rq*1Krr53!!%!#*3Krl"mI4YiI*i MH(br+hJS(J!!3B)!&#JI!!""JJ!-+"d!!%##!!`iB!!+5!!!S)"r!!!S!`!!3)) !0$KJ!!K)!!NjB!!!!*!!I`!!J*m!!#J%!!"!JJ!-1'!!"NJ!!(#![3!!J0m!!*! !TJ!!J2m!!)$R!!!S"`!!3))!+)"r!!")!!PeB!!!!$N!!!#4(`!!15!!!*%q!!! iB!!$5!!!-)&I!!#!DJ!!Im6cH%J!'E&J!!!!JAm!!)&V!!#"D`)JJCm!!*&X!!! iB!!!J!%!@$JK!&"m#!1QJq(rr)2"rrL$SIrd6S!!)!#3"L""J!-!N!Am!"%ZBf0 IFf9aAfCPG'0SAdj$F`"m#!+QNq(rr*2"rrL6SIrdNi(rm*!!!3!)P#(rX*!!B3" SI*iMH(bp+hKmhc0i+"i!!%'#!"JS(`!!3B)!%)"K!'JS!`!!3))!$$KJ!!T)!!) %+"d!!%##!!`iB!!'5!!"p)#H!K3X"!"Q3))!*(r$mhK)!"d"B!!!!(aM"h3X!`! !3))!$$KJ!!K)!!()J,m!!#J&!!"!JJ")1'!!#%J!"p&J!!!!N!"r!!#!h`!!+!B !!%##!!`iB!!'5!!"Q$MJ!!#"(`!!N!$S!!4)!!!8J6m!!)&*!!3j5J!"N8N!")& r!!#"D`!%UCi#"(`,B!"!J!!NJ(i##)#I!!#!K!!%9)331RaM)#k!B`!!,!-!Bd' #rm#![`!!J+8!"+MH!J4m"6!!3B!!+)"r!!")!!I"B!!!!$MJ!!#3!2d!!$N!!!# 4(`!!1'!!!dJ!!3b"2J))J9m!!)&+!!495K!kI5P3,S1*!!!X(!!"3))!K$KJ!!K )!!F"B!!!!*!!I3!!JAd!!#J,!!"!JJ!-1'!!"NJ!!-JiB"f!5!!'h@!!!!#"R3! !N!"X!!5!I3!!J'-!"#J$!!"!JJ!-1'!!"NJ!!*b!R3!!J'3!")#q!JL!h`!!J-B !"&6'%$TmT6!ZJ)8!"$LJ(B")!#!YJ%%!&%J!!&JX(!!#3))!3)$q!JL"(`!!J3J !"&8)%$Tmjd!ZJ1F!"*!!i3!m15!!!T%K!$L!B3!iJ)%!2(qPkhK)!!mKB!!!!%J !!"3j3!!!N9d!!$KJ!"")!!!BJAm!!)',!!3jM!!"NBX!"$KJ!!#!!3"B1#%!8(` )!kD$iIrmJm(rq)1Krr5$JIr`6S!!)!#3"L""J!3!N!3#F!!6,Q0MAh0PF9pQCA4 MD&pMFQ9NF`!!!(`)!UD6iIrmNm(rq*1Krr56JIr`N!!"!!L8)Iq`I(`EH(bG)hJ li!!!1m!!!#JF!!"!JJ!-1'!!#NJ!!1JS(3!!3))!$$KJ!!C)!!$BJ*`!#$L%!!& 8Ja!k5!!HdB""!"53!(d!!)#p!!!S"3!!3))!$$KJ!!C)!!#XJp`!!%J!!)JiB!) %5!!HTB""!"5!h3!!9qF31RaQ15k"(3!!9qN31Rd)5#iS#!!!3))!$$KJ!!C)!!" `J9d!!&IV%$TmDPJZIm6cH%J!(Rf!33!8JCd!!&IN%$TpM#!Z1'`!rcLH!34)!"j KJ%%!&)#q!3#!h3!!9qF31Rc'1#k3!+B#!)2H!L!lr`!"+"i!!%##rhJj!!!!J6d !!&IU%$Tp#9%Z1'!!!)!"!&Ji)3"3I!J$TS2Krrb$`IriJk(rp)1"rr"1J!!J!*! ')%'!"!#3"!&!!!mZBf0ICf9dAdj$AfPZCQm!!!"m#!+QNq(rr*!!!3!)P#(r`(b I)hJS(`!!3))!$$KJ!!C)!!!8Iq2lH%J!"-9J!!!!1'!!!)!"!%Ji)3"!I!J$TS2 Krra1J!!J!*!')%'!!3#3"8J!%LjMBepQFQ9PAh"bD@jMDA"KE(`)!UD6iIrmN!! "!!L8)Ir!I*mMH#JI!!"!JJ!-1'!!"NJ!!"4rirYi5!!%@@!!!!!iB!!!J!%!5$J K!%"m#!1QJq(rr%k!!#!!N!BJ3B!"!*!&5!!0,Q0MAfCbC@9IEQ&YC3"m#!+QNq( rr*!!!3!)P#(r`(bI)hJS(`!!3))!$$KJ!!T)!!!SJ(m!!%J!'EeJ!!!!J(m!!%J !!q9J!!!!1'!!!*!!I`!!1'!!!)!"!%Ji)3"!I!J$TS2Krra1J!!J!*!')%'!!3# 3"9`!$LjMBepQFQ9PAf0bC@4cI!J#TT2Krrb6`IriN!!"!!L8)Ir!I*iMH#JH!!" !JJ!-1'!!#NJ!!&3li!!!5!!!()#H!!"Aj4!kI'3S,NJ!'j'!33!81rm!!B$H!!" Aja!kI-Bi,LJ'!!"!J[rBJ(i!!%J!'ff!33!813!!!*%H!!!l`!!!1'!!!)!"!%J i)3"!I!J$TS2Krrb$`Iri6S!!)!#3"L""J!)!N!@3!!!3,Q0MAfCbC@9I6N0ID@j QE`!!I!J#TT2Krrb6`IriN!!"!!L8)Iq`I*mMH*!!S3"`+"m!!%##!!`iB!!-5!! "1$KK!$K)!"UjJ%%!&(aq'hL!I`)8,!-!C%'#!"`iB3!i1*m#'$LK!%")!"UYJ%% !&(aq'hL!J3"`,!3!!N'#!#a!J!!3,!3!!8#!!"4)!!$F,!3!"%#!!04)!!"-1+! !C*!![`)85!!!c)$I!K3X"J"N3))!)$MJ!'@3!2m#&)%"!$L")3!mN4m#'*%r!Ka )!!#NJ9m#&#`+!'C!JJ#B1'!!#%J!!*5"I`)8,!X!C%##!#!jJ!"QNCm#&)"K!$L !J3!mN!"r!KL3!*m#(%J!!'L![`)8,!8!CN##!"L)`3"!+!B!!%##!!`iB!!)5!! !6)$r!K3X"`"P3))!2)N"!%!S#!!!3B)!)$NJ!'D42`)8J8%!1)&K!$b4A`)BNAm #(%J!!"3iB!!)5!!!%$KJ!!a)!!!)1'!!!)!"!&Ji)3"3I!J$TS2Krrb$`Iri6S! !)!#3"L""J!)!N!3"H!!3,Q0MAfa[BfYIFQ9aG@9cG!!!I!J#TT2Krrb3!!%!#*3 Krm#3!'%!@$[J!!#!B3"B5!!BI@!!!!"mIaYiIq-(0#`$!!""JJ!-Iq2lH%J!!"3 iJ!!!J+)!+*!!K3!!Iq2lH)!"!%Ji)3"!I!J$TS2Krra1J!!J!*!')%'!!3#3"@! !%bj*EQPdD@&XDATP3f&MD'9-D@)!!!"m#!+QN!!"!!L8)Ir!5!!BA@!!!!#!!3" )1#%!3(`)!kC1J!!J!*!')%'!!*!'*!!5,P4PFQeTEQ&dC80KBfKP6'PLI!J#TT2 Krrb6`IriN!!"!!L8)Ir!I(iEH(r$mhK)!"NjJ%%!&(ar'hJS(`!!3B)!&(rMqhK ra20i5!!C6B""!"4rirYiJ!%!5$JK!%"m#!1QJq(rr)2"rrK1J!!J!*!')%'!!J# 3"9`!#bj1CAG6B@CP8(4b!!!!I!J#TVp"rqL3!!%!#*3Krl"mHaYi1i)"dM[#!F8 lSJ'hJq)!,(pMfhK)!"KTJ%%!&(ak'hJS'`!!3))!K)"r!!!X!`!"3))!)(qMkhK ra20i1+!!*cM!!!")!"IaJ%%!&%J!!&b!R`!!,!3!!N##!"4rSqYi5!!AlB""!"4 )!!"!J,m!!#`&!!0!JJ!35!!AlB""!"4)!!!SJ0m!!#`'!!4!JJ!FIk2VH(r%mhJ iS!!R1-!!!8J!&j@!33!8,"S!!%'"!)5!r`!!,!F!!8##!#"rJq0iIm6cH$LJ!#J i`!!!5!!ADB""!"4)!!"FJ4m!!#`)!!*!JJ!8Ii2MH%J!&f@!33!85!!!3)%r!!! X#3!$3))!%%J!&f@!33!85!!!+)&I!!!X#J!%3))!((q$ihKra20i1+!!+$M!!!& )!"F0J%%!&(pMfhJiJ!!!IdA6H%J!&eQ!33!8If2EH$L!!!"r4G0i5!!A4B""!"4 rBpYiId66H%J!&df!33!8If2EH%J!&V'!33!8J!%!@$JK!&"m#!1QZd(rk%k!!#! !N!BJ3B!'!*!%!C`!$bj%DA0`Eh0P8f&QC9"dFJ!!!(`)!UD6iIrmNm(rq*!!!3! )P#(r`(aq'hKr`r0i5!!AAB""!"4mIaYi+"m!!%'#!"4rirYiIm6cH%J!&a'!33! 8Iq2lH)!"!%Ji)3"!I!J$TS2Krrb$`Iri6S!!)!#3"L""J!)!N!9F!!iZ6Q9h8f& QC9"dFP0jFh`)!UD6iIrmNm(rq*1Krr56JIr`N!!"!!L8)Iq`I(`EH$[#!GmlSJ( &Jq)!,#JF!!"!JJ#%J(m!!#`$!!&!JJ!JIm2cH(qNkhJiS!"31-!!!%J!&Ef!33! 85!!!A)#I!!!X"!!#3))!&(r$mhK)!"@jJ%%!&%J!!%#![`!!,!8!!d##!"")!"@ jJ%%!&%J!!#L!h`!!,!B!"%##!"ar`r0iIk6VH$LJ!&!i`!!"5!!9BB""!"3ii!! !X2`#"$N!!!Ua(!)'1'!!+%[rrVf3!(`##)"m!JL!!3"B1#%!8(`)!kD$iIrmJm( rq)1Krr5$JIr`6S!!)!#3"L""J!3!N!Ad!!iZEQ9h3h*PC%*eCQCPFR`)!UD6iIr mNm(rq*1Krr56JIr`N!!"!!L8)Iq`I(`EH*!!J3"XN!#K!(#3!-%!G$[#!HSlSJ( &Jq)!,#JF!!"!JJ#%J(m!!#`$!!&!JJ!JIm2cH(qNkhJiS!"H1-!!!%J!&*f!33! 85!!!A)#I!!!X"!!#3))!&(r$mhK)!"5CJ%%!&%J!!%#![`!!,!8!!d##!"")!"5 CJ%%!&%J!!#L!h`!!,!B!"%##!"ar`r0iIk6VH$LJ!&ii`!!"5!!83B""!"5!i3" XN!$m!!#"!3"`N4`!")%K!(3S#3!!3))!&$P!!!#4A!!)1'!!!%J!!$b!B3"`5rr pJC!!I!!)JA`!##J,!!"!JJ!-1'!!"NJ!!"b!I!!)J)%!G)#K!(")!"5jJ%%!&$K J!!#!!3"B1#%!8(`)!kD$iIrmJm(rq)1Krr5$JIr`6S!!)!#3"L""J!3!N!3"4!! -,Q0[F(P%BA4K6f*U!!"m#!+Q[U(re*!!!3!)P#(rN!"mGaYiI*XMH$Z#!L)lSJ) 61b)#!cY#!IBl`J(&Jq)!,$UJ!!!l!!!!1X!!!#JE!!"!JJ#%J(m!!#`$!!&!JJ! JId26H(r%mhJiS!"d1-!!!%J!%c@!33!85!!!A)#I!!!X"!!#3))!&(p$dhK)!"- aJ%%!&%J!!%#![`!!,!8!!d##!"")!"-aJ%%!&%J!!#L!h`!!,!B!"%##!"ar3p0 iIm6cH$LJ!(3i`!!"5!!5fB""!"4qq,Yi+"J!!%##!"3ii!!!N!$l!!")!!+B1V8 !!B%B!!!l'!!%+!J!!%##rr!j03!"95-31N[rr"@3!(X!!(af'hJS&J!!3))!K)& I!!!X#J!"3))!)(mMbhKra20i1+!!I$M!!!")!"*YJ%%!&%J!!&b"I`!!,!X!!N# #!"4r)mYi5!!5DB""!"4)!!"!JCm!!#`-!!0!JJ!35!!5DB""!"4)!!!SJ(m!!#` $!!4!JJ!FIb2,H(r%mhJiS!"m1-!!!8J!%K'!33!8+"B!!%'#!H"qq,Yi5!!"[$K J!!a,rrYYJ*X!!*!!C!!!J,X!!)#P!!!S"3!!3))!K)$I!!!X"J!"3))!)(qMkhK ra20i1+!!JcM!!!")!"'pJ%%!&%J!!&b!r`!!,!F!!N##!"4rSqYi5!!4ZB""!"4 )!!"!J4m!!#`)!!0!JJ!35!!4ZB""!"4)!!!SJ6m!!#`*!!4!JJ!FIk2VH(r%mhJ iS!#$1-!!!8J!%@'!33!8J9X!!)&+!!!S#J!!3B)"+)&l!!#!D`!!J*F!!$LJ!!a )!")4J%%!&)'E!!#"M!!!J'`!"%[rqTf!Q`!!J)3!!*!!C!!)J,X!!)#P!!#!T3! )+!8!!%##!)5!h`!!,!B!!8##!#"rJq0iIm6cH$LJ!)Xi`!!!5!!3jB""!"4)!!" FJ2m!!#`(!!*!JJ!8Ii2MH%J!%1'!33!85!!!3)%I!!!X#!!$3))!%%J!%1'!33! 85!!!+)%r!!!X#3!%3))!((q$ihKra20i1+!!LcM!!!&)!"#*J%%!&)&E!!#"5J! !J8S!##J+!!""JJ"-JAX!!)&V!!#!D`!)JCF!!)#-!!L!e`!!J+B!"%J!%5Q!33! 81hX!"$XB!!5!q!!!+!F!!%##rN!j!!!!9UN31Rd@55k5f`!!J!%!H$JK!("m#!1 QZU(re%k!!#!!N!BJ3B!,!*!%!i3!$LjMEh"j4'&dB8&bFQ&jI!J#TT2Krrb6`Ir iNk(rp*!!!3!)P#(rX*!!B3"SN!#"!'am[5Yi1q!!!$[!!!#$`3"X+"d!!%##!!` iB!!'5!!"3$KJ!!K,rrNPN!"p!!#!I3!!+!-!!%##!!`iB!!'5!!")$KJ!%a,rrN &I(mEH#JI!!"!JJ!-1'!!"NJ!!33iB!6L5rrikC!!I`!!J*m!!#J%!!"!JJ!-1'! !"NJ!!13iB!6L5rribC!!I`!%J,m!"#J&!!"!JJ!-1'!!"NJ!!-5!I`!!J*i!!$L J"0p)!"!aJ%%!&)"r!!5!RJ!%1+!%hdJ!%"f!33!81(m!#)#H!!L![J!-J0i!%%[ rqJ@!hJ!8N!$I!"5!rJ!BN!$r!"L"(J!FN4m!()%q!##42`!JJ9i!**&I!#5"IJ! SNAm!+)"q!#`iR`!X5rrl,6Kr!$#!RJ!`J,i!0)$H!$K,rrQe1(m!2)#H!$b![J" !J0i!4%[rqD%jJ!!!NCm!5$KJ!!+!R3!!N!"N!!#![3!!Nq8!"$KJ!!#!!3"B1#% !8(`)!kD$iIrmJm(rq)1Krr41J!!J!*!')%'!!`#3"!'B!!XZBfp`H9Be3h*PC!! !!(`)!UD6iIrmNm(rq*!!!3!)P#(r`*!!B3"BN!#"!&am[LYi1q!!!#JH!!"!JJ! -1'!!"NJ!!'`iB!!)5rrhHC!!IJ!!J(i!!#J$!!"!JJ!-1'!!"NJ!!%`iJ!!"J,i !!*!!K3!!1'!GJ%[rpdemIaYi+"m!!%##!!`iB!!'5!!!*(rMqhL!J3"F1+!GJ%J !$SQ!33!8J0i!!*2Q!!3iB!!!J!%!5$JK!%"m#!1QJq(rr)2"rrK1J!!J!*!')%' !!J#3"E3!#bjMEh"j9M4$FQ9N!!!!I!J#TT2Krrb6`IriN!!"!!L8)Iq`I(mEH*! !J3"XN!#K!(!l`!!!1'!!!*!!B3!i+"m!!%##!!`iB!!+5!!"!)#"!'`X"!!"3B) !')#K!'`X"3!#3B)!$$KJ!"")!!$JU0m#"$M'!!'`h`)%U2m#"(cR"c5T(`)'I!G !!%##!&bT2`)'95N)2,%r!JDTA`)'98-31N[rpNemIKYi+"i!!%##!!`iB!!'5!! !P(r$mhL!R`))UAm#"ReV$R"pD`'89@831NJ!$Af!33!8J(m##%[rp&'6h`))JB% !E#`-!!&!JJ!BJ'%!E)#"!(!iS3!i5rrq38J!!#b!B3"X,!-!!N##!"L!B3"XJ)% !F$LK!$K,rraT5!!!$$KJ!"")!!!JJ)%!1)#r!JLSh`)%1-Erre6'%$TmK6%Z1'! !!)!"!&Ji)3"3I!J$TS2Krrb$`Iri6S!!)!#3"L""J!)!N!3"8!!4,Q0bC@4#G@C QCA**ER0PFR3!I!J#TT2Krrb6`IriNk(rp*1"rr#3!!%!#*3Krl"mIKYiN!#"!'b 3!+%!F$Z!!!!S(J!!3))!$$KJ!!T)!!$31k!!!%J!!,L!IJ))9k331RaM)#k!J`! %J'-!!)#K!'b!`3"`5!!#,@!!!!"mB`Gd,!-!!%'#!)5![J))9kB31Rq&-#jrJq0 i5!!)m@!!!!"rJq0i5rrc'AqrkhK)!!!NJ2i##$NI!!&9#"!kI1G!,S%q!JKAkK! kI1P4,M[r!!'TIJ)%1@[rrh`I@!""J2r81B!!!)"q!JLSRJ)%1)6rre5%%$TpJb% ZU,i#"$LPrrq`[J)%5!!!&$Zp!!'ShJ)%I"d`!%'!rd3iB!!!J!%!@$JK!&"m#!1 QJq(rr)2"rrL$SIrdJi(rm%k!!#!!N!BJ3B!%!*!%!5J!%5jMFQ9N3R9QCQ9b8Q9 YEhCP!(`)!UDr3IrSN!!"!!L8)IqJI(SEH(bF)hJl`J)j1k)"aB2L!#`iB!!!N!" K!$JS(!!!3))!K)#I!!!X"!!"3))!)(r$mhKrT1Yi1+!"5$M!!!")!!T9J%%!&%J !!&b![`!!,!8!!N##!"4r`r0i5!!+8B""!"4)!!"!J0m!!#`'!!0!JJ!35!!+8B" "!"4)!!!SJ2m!!#`(!!4!JJ!FIm2cH(qNkhJiS!&)1-!!!8J!#IQ!33!8+"`!!%# #!!`iB!!-5!!!5$YJ!!")!!!SJ4`##>%$Tp#%JZN3%!1(p$dhJiJ3!i5rrYB@! !!!!lH`!"U9`#"(`E8!""J2r8J(`##%[rm9diB!!!J!%!D$JK!'"m#!1QZd(rk%k !!#!!N!BJ3B!'!*!%!4`!%LjNDA0`Eh0P3h*PC%*eCQCPFR`)!UD6iIrmNm(rq*1 Krr56JIr`N!!"!!L8)Iq`N!"K!'L3!)%!E*!!S3"`N!$"!(5!B3"X+!-!!%'#!"# !J3"d+!3!!%##!!`iB!!!5!!"!)#K!'L!`3"`I!8`!%'#!!`iB!!!5!!!k)$K!'J X"`!"3))!G)2K!'b$`3"d1(m!!6LH!!&)!!S&J%%!&#`$!!"!JJ"-1(m%icLH"10 )!!RYJ%%!&#`$!!"!JJ!d1(m6L6LH%iP)!!R9J%%!&#`$!!"!JJ!FJ4mBI)%q'(a m#%J!3))!$$KJ!!&)!!"d1'!!!%J!!'b"33"S,!S!!N##!&b$S3"XJi%!G)"p!!# !R!!!5!!*LB""!"3X!`!!3))!0)"p!!5!R!!%5!!*FB""!"3X!`!!3))!()&p!"L "R!!BI!YJ!%##!!`iB!!"5!!!%$KJ!!")!!!)1'!!!)!"!&Ji)3"3I!J$TS2Krrb $`IriJk(rp)1"rr"1J!!J!*!')%'!"!#3"!&S!!JZBh*PC'0YF!!!I!J#TT2Krrb 6`IriNk(rp*1"rr#3!!%!#*3Krl"mI4YiI*`MH$[!!!!S(!!!3))!$$KJ!!C)!!) 81'!#+%[rlZ'3!(`!!)"m!!!S!`!!3))!$$KJ!!C)!!(dJp`!!(r$mhKrT1Yi5!! )*B""!"5!R3%!N!#H!3!iIJ%%1*d""%J!#!f!33!8U,d#",#q!J5Sh3)'X0i#"MM J!!'BrJ)3U4i#"P8$%$T,rqjjN!"q!JL"2J))+!N!!%##!!`iB!!'5!!"M$[J!!" )!!&SJ9d##&IV%$Tp5PJZJ8S!!#`+!!&!JJ#`1'!!#%[rlMQ"RJ))9q331RaX)5k ![J))9qB31RbP-#iS"3!!3))!$$KJ!!C)!!%m11!!!B%H!JKAk4!kI3K),T!!k!! !1'!GJ%[rlI@"AJ))9qX31Re+@#k3!'S!")'H!JKAia!kIB`B,S'-!!3S$!!!3)) !$$KJ!!C)!!$`J*i##&IP%$TmK#JZJ'3!")$G!JKAja!kI-Bi,S#'!!3iS"f!5!! (1B""!"4)!!#JJ4d##&IT%$Tp#%JZJ3J!!#`)!!*!JJ!XJ9d##&IV%$Tp5PJZJ'S !!)#+!!5"RJ))9qB31RbX-K4,rrBY5!!!B)$p!JKAk"!kI1G!,S$R!!!X"`"M3)) !5$KJ!!K,rqdeJ6i##&IU%$TmD9%ZJAi##&IX%$TpDf!Z+!X!!%##!!`iB!!'5!! !1$KJ!'1!RJ))9q831Rb%+#k3!'3!!$[r!!'ShJ)%I"m`!%'!rT3ii!!!N!$q!L5 3!2i#)$KJ!!#!!3"B1#%!8(`)!kD$iIrmJm(rq)1Krr5$JIr`6S!!)!#3"L""J!3 !N!3#D!!',Q4eF%j$I!J#TT2Krrb6`IriN!!"!!L8)Ir!I(iEH(rImhJS(`!!3B) !,%J!!"5!R`!!J'3!#%[rl1Nlr`!%J,m!!#J&!!"!J[rSIm2cH%[rl0'!!3")1#% !3(`)!kD$iIrmJm(rq%k!!#!!N!BJ3B!#!*!&C!!4,Q4TFh"[Ff9%BA4K3A*bBAN !I!J#TT2Krrb6`IriNk(rp*1"rr#3!!%!#*3Krl"mI"Yi1m)#4$ZL!F@$iJ!X+"` !!%##!*L!I`!!,!-!!8##!#"r`r0iIk6VH$LJ!F)i`!!!5!!%LB""!"4)!!"`J*m !!#`%!!*!JJ!8Im2cH%J!")@!33!85!!!9)#r!!!X"3!$3))!%%J!")@!33!85!! !2)$I!!!X"J!%3))!-(r$mhKrT1Yi1+!"`MM!!!&)!!3YJ%%!&%J!!"4rJq0iIi6 MH%[rfIPJ!!!!J2`!!#J(!!"!J[rS1'!!!)!"!&Ji)3"3I!J$TS2Krrb$`IriJk( rp)1"rr"1J!!J!*!')%'!"!#3"IJ!#bjQFQ9P6N0-DA0d!!!!I!J#TVpKrqb3!!% !#*3Krk"mI"Yi1m)"hcZL!F@$iJ!X+"`!!%##!)5!I`!!,!-!!8##!#"r`r0iIk6 VH$LJ!G)i`!!!5!!$IB""!"4)!!"FJ*m!!#`%!!*!JJ!8Im2cH%J!!hQ!33!85!! !3)#r!!!X"3!$3))!%%J!!hQ!33!85!!!+)$I!!!X"J!%3))!((r$mhKrT1Yi1+! "dMM!!!&)!!-KJ%%!&$KK!$K)!!,0J%%!&(al'hKrC`Fd,!F!!%'#!!`iB!!!5!! !5)%F!K3X#!"N3B)!-$KK!$JiR!)B1+%!3%J!!Uf!33!8I(XEH(pT"c3X#3!!3B) !&$KJ!!")!!!318!!!*P"!%#)B3"!J!%!D$JK!'"m#!1QZf(rl%k!!#!!N!BJ3B! &!*!%!53!#bjTFda[BfY2GA*c!!!!I!J#TVpKrqb3!!%!#*3Krl"mHaYi1m)#9cZ L!F@$iJ!X+"X!!%##!)5!I`!!,!-!!8##!#"r`r0iIk6VH$LJ!HFi`!!!5!!#1B" "!"4)!!"FJ*m!!#`%!!*!JJ!8Im2cH%J!!M@!33!85!!!3)#r!!!X"3!$3))!%%J !!M@!33!85!!!+)$I!!!X"J!%3))!((r$mhKrT1Yi1+!"jcM!!!&)!!(GJ%%!&)$ l!!!X"`!#3))!I)1E!!5!I!!!5rrTHB"m!!4,rqPaJ4`!%#J)!!""JJ!-J(`!%%[ rk9f"2!!i+!N!!%'#!!b!I!!i5rrT5B&F!%3S#J!!3B)!$)"m!%4,rqNeJA`!5#J ,!!""JJ!-J(`!5%[rr!Q"R!!X+!`!!%'#!!b!I!!X5rrlpB"l!!4,rqN&1'!!!)! "!&Ji)3"3I!J$TVYKrqa1J!!J!*!')%'!"3#3"!&-!"FZBf0ICR*PC9pMFQ9NAfP ZG'9bEQ&XF`!!!(a$%hK1J!!JI!J#TT!!!3!)P#(r`%[rrqemD4YiJ')!D)##!'3 iSJ!!1-)#CB$L!&L"!J"85!!!@B""!"5!JJ#XN!"N!!",rp"TB!!!!$KJ!!#!!3" )1#%!3(`)!kC1J!!JI!J#TT!!!3!)P#(r`)"L!+b!B`!!5!!!-B""!"5!!3")1#% !3(`)!kC1J!!JJB)!1*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!$53!%%!&)!-!!# !6!!%I!N$TNk!"##"JJ!JN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!(*!!33!8J!` !!)"-!!4m#31Q6S!%))'#!"#3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ!`N!""!"5 !$!!!J%`!"(`*!kC1J!3JJB)!&*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!!#3!%% !&)!-!!#!6!!%I!N$TNk!"##"JJ!BN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!8*! !33!8J!`!!)"-!!4m#31Q6S!%))'#!!L3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ! NN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!5*!!33!8J!`!!)"-!!4m#31Q6S!%))' #!!b3!%%!&)!-!!#!6!!%I!N$TNk!"##"JJ"!N!""!"5!$!!!J%`!"(`*!kC1J!3 JJB)!"*!!33!8J!`!!)"-!!4m#31Q6S!%))'#!%53!%%!&)!-!!#!6!!%I!N$TNk !"##"JJ!mN!""!"5!$!!!J%`!"(`*!kC1J!3JJB)!6*!!33!8J!`!!)"-!!4m#31 Q6S!%)!!!,eb!!!"B!*!',l5!!!!X!*!&9L)a`!)L-DJ#)J*PKJ)"-F!L!D@#!K% "P3'-!Am#9`*%!MN#)J)6!J-"pJ(U!Gm"dJ(&!EF!Y!&`"#)9+)B#&44d%rJ6N!! 6*"(!$bJ1#!e-$*J,a!T-#A!)H!JJ"MJ%l!0`!F!"0!!F&d`L&X3%,Ne*9#"*,e- J6@&M4'9f!5#"CJ`K+'jKE@8J)6dJ-#N)3d0KBfKP,Q-2)5JUD'&ZC'aP)#%p)$! T%5%SF(*TEQ0TF'&X)#%p)$!T$5%SFf&QC9!J)6dJ-#N-3d0KBfKP9A4TE#jM$#% SFfPkC5!q)$"-+3SK+'jM)#%p)$!T#b%SEf*U)#%p)$!T$#%SC'9cG#!K25!`+3p bCA4NCA0d)$dp)%j96%`1+LTNCA0d)$dp)%j96%`@+#SUC'9cG#NY2Q4KG'%J26d J6P9-6!TZBb!p25"198a-%L%SBfjdFQa#E'pMDb!K25!`+3dK+'0bC@4c)#%p)$! T1k3!!!%!!!!"C!!!!'3!!!!bC@*eCcSf1%XJ3fpNC8GPEJ"0593J8R9ZG'PYC9" 33b"%6%`ZC'9LG@Fk0MK,)%4TFf&cFf9YBQaPFJ"0593J8R9ZG'PYC9"33b"%6%` ZC'9LG@Fk0MK,)%GXEf*KE#"2F(4TE@PkCA)!68P8)&*eER4TE@938%-J4%a-,Q4 PBR9R1MBi5b"-D@jVCA)!68P8)&*eER4TE@938%-J4%a-,Q4PBR9R1MBi5b"3FQp UC@0d!%e*9#"5G@jdD@eP8&"$)%4-6#jNC@*eCcT$,d-V+b"$Efe`D@aPFJ"0593 J8R9ZG'PYC9"33b"%6%`ZC'9L!!!!B!#3#`%!N"-"F(G`B`#3%`%!N"&!&%e*9&q P3d0KBfKP6'PL,Q4PBR9R!!!!!3!!!!&N!!!!C!!!!$)&9MR30#B!!!!F!$)!!'0 QFQF!!!!+!!$rr`#3"!9EF&b1RJ: \ No newline at end of file diff --git a/src/mac/libraries/CCache API/include/CCache.h b/src/mac/libraries/CCache API/include/CCache.h deleted file mode 100644 index f758c14f3..000000000 --- a/src/mac/libraries/CCache API/include/CCache.h +++ /dev/null @@ -1,350 +0,0 @@ -/************************************************************* - * - * Header file for Credential Cache API for MacOS - * - * -as defined by the document found at http://www.umich.edu/~sgr/v4Cache/ - * -definitions borrowed from a windows implementation found at - * /afs/umich.edu/user/s/g/sgr/Public/TsoCacheDll shell/ - * - * Revision 1: Frank Dabek, 6/4/98 - * added missing calls from revision four of the API - * deleted some WIN specific Information - * added some misssing definitions - * renamed to CCache.h - **************************************************************/ -#ifndef _CCache_h_ -#define _CCache_h_ - -#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) -# pragma import on -#endif - -#include "Processes.h" -/* -** The Official Error Codes -*/ -#define CC_NOERROR 0 -#define CC_BADNAME 1 -#define CC_NOTFOUND 2 -#define CC_END 3 -#define CC_IO 4 -#define CC_WRITE 5 -#define CC_NOMEM 6 -#define CC_FORMAT 7 -#define CC_LOCKED 8 -#define CC_BAD_API_VERSION 9 -#define CC_NO_EXIST 10 -#define CC_NOT_SUPP 11 -#define CC_BAD_PARM 12 -#define CC_ERR_CACHE_ATTACH 13 -#define CC_ERR_CACHE_RELEASE 14 -#define CC_ERR_CACHE_FULL 15 -#define CC_ERR_CRED_VERSION 16 - -#define CRED_TYPE_IN_UNION - -typedef int cc_int32; -typedef cc_int32 cc_time_t; -typedef cc_int32 cc_nc_flags; -//typedef short cc_cred_vers; - -enum StringToKey_Type { STK_AFS = 0, STK_DES = 1}; - -enum { MAX_V4_CRED_LEN = 1250, - KRB_PRINCIPAL_SZ = 1250, - KRB_INSTANCE_SZ = 1250, - KRB_REALM_SZ = 1250, - KRB_SERVICE_SZ = 1250, - ADDR_SZ = 16 }; - -// V4 Credentials -typedef struct _V4Credentials { - unsigned char kversion; - char principal[KRB_PRINCIPAL_SZ]; - char principal_instance[KRB_INSTANCE_SZ]; - char service[KRB_SERVICE_SZ]; - char service_instance[KRB_INSTANCE_SZ]; - char realm[KRB_REALM_SZ]; - unsigned char session_key[8]; - cc_int32 kvno; - enum StringToKey_Type str_to_key; - long issue_date; - cc_int32 lifetime; - char address[ADDR_SZ]; // IP Address of local host - cc_int32 ticket_sz; - unsigned char ticket[MAX_V4_CRED_LEN]; - unsigned long oops; -} V4Cred_type; - -// version indentfiers -// extend to authentication schemes beyond Kerberos? -enum cc_cred_vers { - CC_CRED_VUNKNOWN = 0, // For validation - CC_CRED_V4 = 1, - CC_CRED_V5 = 2, - CC_CRED_VMAX = 3, // For validation - CC_INVALID_RECORD = 99 -}; - -#define NC_MAX_NAME_LENGTH 255 -typedef struct _infoNC { - char name[NC_MAX_NAME_LENGTH]; - char principal[NC_MAX_NAME_LENGTH]; - enum cc_cred_vers vers; -} infoNC; - - -typedef struct _cc_data { - cc_int32 type; // should be one of above - cc_int32 length; - unsigned char* data; -} cc_data; - -typedef struct _cc_creds { - char* client; - char* server; - cc_data keyblock; - cc_time_t authtime; - cc_time_t starttime; - cc_time_t endtime; - cc_time_t renew_till; - int is_skey; - cc_int32 ticket_flags; - cc_data **addresses; - cc_data ticket; - cc_data second_ticket; //???? - cc_data **authdata; -} cc_creds; - -//union of v4, v5 pointers -typedef union cred_ptr_union_type { - V4Cred_type* pV4Cred; - cc_creds* pV5Cred; -} cred_ptr_union; - -//version 4 and version 5 union data type -typedef struct cred_union_type { -#ifdef CRED_TYPE_IN_UNION - enum cc_cred_vers cred_type; -#endif - cred_ptr_union cred; -} cred_union; - -#define kInitialCredBufferSize 10 -#define kLocalCopyNCType 1 -#define kMasterRecordNCType 2 -#define kUnlocked 100 -#define kReadLock 101 -#define kWriteLock 102 -typedef struct _ccache_p { - char name[NC_MAX_NAME_LENGTH + 1]; - enum cc_cred_vers vers; - char principal[NC_MAX_NAME_LENGTH + 1]; - short numCreds; - short maxCreds; - cred_union** creds; //self-growing array of pointers - int cc_flags; - char typeFlag; //master or local copy - long lock; - ProcessSerialNumber lockOwner; - struct _ccache_p *next; - struct _ccache_p *prev; -} ccache_p; - - -typedef struct _ccache_it { - ccache_p *prevNC; - int lastCredOffset; -} ccache_it; - -typedef struct _apiCB { - ccache_p* listHead; - ccache_p* listTail; - int numNCs; - cc_time_t changeCount; -} apiCB; - - -// --- Globals ------------- -extern apiCB *gCntrlBlock; - - -/* -** The official (externally visible) API -*/ - -#define CC_API_VER_1 1 - -// -- Main cache routines ------ - -/* Initialize the Credentials Cache, return a control structure in cc_ctx, - This should be the entry point of the shared library, or called from - the entry point */ -int -cc_initialize(apiCB ** cc_ctx, // < SL's primary control structure. - // returned here, passed everywhere else - int api_version, // > ver supported by caller (use CC_API_VER_1) - int* api_supported, // < if ~NULL, returned max ver supported by DLL - char** vendor); // < if ~NULL, returns read only C string, vendor name */ - -/* Termination routine */ -int -cc_shutdown(apiCB** cc_ctx); // <> SL's primary control structure. NULL after call. - - -/* Open a name cache within the ccache designated by name and version? - Returns a control struture pointer to the NC in *handle */ -int -cc_open(apiCB * cc_ctx, // > SL's primary control structure - char * name, // > name of pre-created cache - const enum cc_cred_vers vers, // > version of credentials held in this NC - int cc_flags, // > options - ccache_p ** handle); // < named cache control structure - -/* Close and deallocate memory assoicated with the named cache pointed to by *handle */ -int -cc_close(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** handle); // <> named cache control structure. NULL after call. - -/* Create a new named cache in the cache cc_ctx. -Specify the cache by: a name, a principal, a version -return a pointer to the control structure for the cache via handle */ -int -cc_create(apiCB* cc_ctx, // > DLL's primary control structure - char* name, // > name of cache to be [destroyed if exists, then] created - const enum cc_cred_vers vers, // > version of credentials to be held in cache - char* principal, // > name of principal associated with named cache - int cc_flags, // > options - ccache_p** handle); // < named cache control structure - -/* Seems remarkably similiar to cc_close ???? */ -int -cc_destroy(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** handle); // <> named cache control structure. NULL after call. - -/* Get the global last changed time variable for the CCache - Replace this with a change counter instead of an actual time?*/ -int -cc_get_change_time(apiCB* cc_ctx, // > DLL's primary control structure - cc_time_t* time); // < time of last change to named cache - -// -- Named Cache routines --------- - -/* store the credentials (tickets) in cred in the named cache pointed -to by handle. Maybe the last argument should be more general? */ -int -cc_store(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_pointer, // > named cache control structure - const cred_union cred); // > credentials to store in cache named - -/* Remove the credentials pointed to by cred from the Named Cache pointed to -by handle. */ -int -cc_remove_cred(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p* ccache_pointer, // > named cache control structure - const cred_union cred); // > credentials to remove from named cache - -/* set the principal of the NC *ccache_pointer to principal, - principal should be a null terminated C string */ -int -cc_set_principal(apiCB* cc_ctx, // > cs - const ccache_p* ccache_pointer, // > NC - const enum cc_cred_vers vers, // > version: to check pointer? - const char* principal); // > new principal name - -/* Get the name of the principal associated with the NC handle */ -int -cc_get_principal(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p * ccache_pointer, // > named cache control structure - char** principal); // < name of principal associated with named cache - // Free via cc_free_principal() - -/* Get version of credentials stored in the NC pointed to by ccache_pointer */ -int -cc_get_cred_version(apiCB* cc_ctx, // > cs - const ccache_p* ccache_pointer, // > the named cache - enum cc_cred_vers* vers); // <> the version of credentials in the NC - -/* Return the name of the NC specified by ccache_p */ -int -cc_get_name(apiCB* cc_ctx, // > control struct - const ccache_p* ccache_pointer, // > NC - char** name); // <> name - - -// - Search routines ---- - -/* -Sequentially open every NC in the CCache. -To use (?): initially set handle and itCache to NULL -after each call set itCache to handle, -repeated calls will return all currently held NC's -*/ -int -cc_seq_fetch_NCs(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** ccache_pointer, // <> named cache control structure (close, then open next) - ccache_it** itCache);// <> iterator used by DLL, set to NULL before first call - // Also NULL for final call if loop ends before CC_END - -/* Sequentially fetch every set of credentials in the Named Cache handle -use similiarly to cc_seq_fetch_NCs */ -int -cc_seq_fetch_creds(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p* ccache_pointer, // > named cache control structure - cred_union** creds, // < filled in by DLL, free via cc_free_creds() - ccache_it** itCreds); // <> iterator used by DLL, set to NULL before first call - // Also NULL for final call if loop ends before CC_END - -/* a wrapper for cc_seq_fetch_NCs. - Returns: a null terminated list (array) of pointers to infoNC structs - if this works, maybe we should hide that seq call... - */ -int -cc_get_NC_info(apiCB *cc_ctx, // > control structure - infoNC*** ppNCi); // <> info about the NC (yes.. three asterisks...) - - -// -- Memory recovery --------- - -/* just a wrapper for free() ??? */ -int -cc_free_principal(apiCB* cc_ctx, // > DLL's primary control structure - char* principal);// <> principal to be freed, returned as NULL - // (from cc_get_principal()) -/* another wrapper? */ -int -cc_free_name(apiCB* cc_ctx, // > DLL's primary control structure - char* name); // <> name to be freed, returned as NULL - // (from cc_seq_fetch_cache()) - -/* free storage associated with cred_union** */ -int -cc_free_creds(apiCB* cc_ctx, // > DLL's primary control structure - cred_union** creds); // <> creds (from cc_seq_fetch_creds()) to be freed - // Returned as NULL. - -/* Free that nasty array we created above */ -int -cc_free_NC_info(apiCB *cc_ctx, // > control structure - infoNC*** ppNCi); // <> pointer to free - - -// -- Locking ---------- - -#define CC_LOCK_UNLOCK 1 -#define CC_LOCK_READER 2 -#define CC_LOCK_WRITER 3 -#define CC_LOCK_NOBLOCK 16 - -/* Place a lock on the Named Cache handle, lock types are above -NB: API indicates that this call is not implemented*/ -int -cc_lock_request(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p* ccache_pointer, // > named cache control structure - int lock_type); // > one (or combination) of above defined lock types - -#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) -# pragma import reset -#endif - -#endif /* Krb_CCacheAPI_h_ */ diff --git a/src/mac/libraries/CCache API/include/CCacheUtil.h b/src/mac/libraries/CCache API/include/CCacheUtil.h deleted file mode 100644 index 23426fc67..000000000 --- a/src/mac/libraries/CCache API/include/CCacheUtil.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "CCache.h" - -#define kCredsMatch 1 -#define kCredsDiffer 0 - -// ----- Prototypes for Private Functions ------------------ -cred_union ** newCredBuffer(ccache_p *nc); -int credBufferInsert(ccache_p* nc, cred_union creds); -int credBufferRemove(ccache_p* nc, const cred_union cred_to_remove); - -char credcmp (cred_union a, cred_union b); - -char isLockOurs(const ccache_p *nc); - -int copyDataObj(cc_data *obj, cc_data src); -int copyV5Cred(cred_union src, cred_union **dest); -int copyV4Cred(cred_union src, cred_union **dest); -int dupNC(ccache_p* src, ccache_p** dest); -void copyDataArray(cc_data **src, cc_data ***dest); - -void disposeDataArray(cc_data **base); -int cc_free_cred_internals(cred_union *creds); -int freeNCList(apiCB *cntrlBlock); -int disposeCredBuffer(apiCB *cc_ctx, ccache_p *nc); - -Ptr NewSafePtr(long size); -Ptr NewSafePtrSys(long size); -void DisposeSafePtr(Ptr safeP); diff --git a/src/mac/libraries/CodeWarrior Dependencies/Pro2.prj b/src/mac/libraries/CodeWarrior Dependencies/Pro2.prj deleted file mode 100644 index 82cced375fe9430bd5c75d39fde0d6499951edca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17459 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 uSSC6TnZatSju}ugZ3CKK~yaeefUv diff --git a/src/mac/libraries/CodeWarrior Dependencies/Pro4.prj b/src/mac/libraries/CodeWarrior Dependencies/Pro4.prj deleted file mode 100644 index 445248db6da41833998f664aed66fed4e337e1c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18655 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 - - * quad_cksum.c: Include string.h for memcpy declaration. - * random_key.c: Ditto. - -Wed Feb 1 12:00:00 1995 John Rivlin - - * Makefile.in: Create install-windows target - -Tue Nov 22 10:53:16 1994 Ian Lance Taylor - - * random_key.c (des_random_key): Don't assume that the argument is - aligned on an integer boundary. - -Mon Oct 31 19:40:21 1994 Ian Lance Taylor - - * Makefile.in (CODE): Remove Imakefile. - -Fri Oct 28 15:21:01 1994 Ian Lance Taylor - - * read_password.c (old_sigfunc): Use sigtype in declaration, - rather than guessing based on POSIX define. - -Mon Oct 10 19:18:48 1994 Julia Menapace (jcm at toad.com) - - * mac_time.c: Include des.h and AddressXlation.h. Put - gettimeofdaynet wrapper on gettimeofday_no_offset so it can be - returned as a DES pointer with the expected calling sequence. - - * new_rnd_key.c: Make forward declarations and function - definitions match the function prototypes that were added as - new external declarations to des.h: des_set_sequence_number, - des_generate_random_block, des_new_random_key, - des_init_random_number_generator. des_set_random_generator_seed - - (des_init_random_number_generator): Changes to port routine - to the Mac. Initialize the seed using RANDOM_KRB_INT32_1 - and RANDOM_KRB_INT32_2 instead of gethostid and getpid. Use a - KRB_INT32 instead of a timeval and set it using TIME_GMT_UNIXSEC - instead of gettimeofday. - -Tue Aug 9 12:00:00 John Rivlin (jrivlin@fusion.com) - - * win_time.c: Removed copy of time structure as stack - is now set up properly. - - * Makefile.In: Broke up clean target to not do useless - deletes on unix. - -Mon Aug 29 10:12:42 1994 Mark Eichin (eichin@perdiem) - - * key_sched.c (des_key_sched): even if we return an error, build - the key schedule anyway. This helps with testing, and avoids - garbage encryptions in cases where the error isn't checked. - -Fri Jul 29 17:18:55 1994 Mark Eichin (eichin@cygnus.com) - - * random_key.c (des_random_key): use KRB_INT32 for half-key - manipulation, so the upper half really gets set. - -Tue Jul 19 20:06:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * random_key.c (des_random_key): Don't initialize static local - variable n. Fiddled with whitespace in srandom call. - -Fri Jul 15 17:35:30 1994 John Rivlin (jrivlin@fusion.com) - - * ren.msg: updated to handle all files (changelogs, makefiles etc) - - * Makefile.in: added "-" on clean: to avoid stupid messages - -Fri Jul 8 02:40:54 1994 John Rivlin (jrivlin@fusion.com) - - * makefile.in: Updated file with portable directory syntax for PC. - Changed .o and .a references to portable syntax - Removed all response files which needed to be generated under unix - to simplify configure process so that it may be run on the PC. - Placed objects in .lib file so that DLL construction can take place - without a response file. This solves a problem with running out of - memory on the PC during builds. - Updated clean: target to place rm commands on seperate lines for - compatibility with PC DEL command. - -Tue Jul 5 11:31:59 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * string_to_key.c (des_string_to_key): Deleted static and (some) - register decls. - * quad_cksum.c (four_bytes_vax_to_nets): Ditto. - * util.c (des_cblock_print_file): Ditto. - - * weak_key.c (weak): Now const. - (des_is_weak_key): Compensate. - -Fri Jul 1 03:12:31 1994 John Gilmore (gnu@cygnus.com) - - Make Kerberos build using Think C on Macintosh. - - * mac_time.c: Use GetDateTime, not time. - * quad_cksum.c: Avoid using printf(). - * %DesLib-project: New Think C project file for building - the DES library as an ordinary library. (Unfortunately this - is a binary file -- there are no textual makefiles in Think C). - This makes it semi-possible to debug the code. - * %DesLib-project-A4: Ditto, for building as a library to go - into a device driver. - -Thu Jun 30 23:11:11 1994 John Gilmore (gnu@tweedledumb.cygnus.com) - - * *.c: Remove remaining RCS ID strings. Strings used as `char *' - initializers upset Think C when building device drivers, since it - doesn't have a good way to relocate the pointers when the driver - is loaded. - - * f_parity.c: Clarify public domain ownership. - - * *.c: Use #include "..." rather than #include <...> for - our own local include files, because Think C can't find them - when enclosed in <...>. - -Wed Jun 22 18:29:48 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * new_rnd_key.c, string_to_key.c: Include . - -Tue Jun 21 00:15:31 1994 John Gilmore (gnu@cygnus.com) - - * new_rnd_key.c: Lint. - -Sat Jun 18 09:05:30 1994 John Gilmore (gnu@cygnus.com) - - Make DES library independent of krb library again. - - * Makefile.in (SRCS, OBJS): Use DES_TIME_SRCS and DES_TIME_OBJS. - * unix_time.c, mac_time.c, win_time.c: New files implement - TIME_GMT_UNIXSEC for the various hosts. Code moved from *_glue.c - in lib/krb. - -Fri Jun 17 05:01:03 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in (DESSRCS): Move read_password.c to SERVER_DES_SRCS, - since we don't use it on micro clients. Clarify comments. - (Links of test routines): Add $(LDFLAGS) to the line so that - mac-mf.sed can find these and modify them to run "Link". - -Thu Jun 16 17:08:58 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in (unixmac): New target. - -Fri Jun 10 23:03:08 1994 John Gilmore (gnu@cygnus.com) - - * f_tables.h: Add comments on the DEB macro. - * new_rnd_key.c: Remove RCS crud, update export notice. - * random_key.c: Clean out obsolete config crud. - Use TIME_GMT_UNIXSEC_US rather than gettimeofday. Use - RANDOM_KRB_INT32_1 and RANDOM_KRB_INT32_2 rather than - getpid() and gethostid(). Remove RCS crud, update export notice. - * string_to_key.c (des_string_to_key): Int functions return results. - * testit.c: Print usage message if no args. - * verify.c, testit.c: Declare des_debug extern, not common. - -Wed Jun 8 13:09:14 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in (DBG): Move to where it will actually work. - * testit.c, verify.c: Include . Remove raw extern - declarations. Pull RCS crud. - * verify.c: In Windows, set screen buffer to keep all output. - - * string_to_key.c (des_string_to_key): Fix argument type to match - correct prototype. Pull RCS crud. - -Fri May 27 16:55:33 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in (DBG): Override with library-building flags. - - * des_internal.h: Include krb.h when compiling the DES - routines, since it describes some of the DES routines when - documenting the external interface of Kerberos. - * f_cbc.c, f_ecb.c, f_parity.c, f_pcbc.c, key_sched.c, - quad_cksum.c, string_to_key.c, weak_key.c: Add INTERFACE to - definitions of functions visible in the programmer interface. - * string_to_key.c: Remove some error printf's for environments - that don't have printf; put them under #ifdef DEBUG. - -Tue May 24 06:10:57 1994 John Gilmore (gnu@cygnus.com) - - * enc.c: Pull RCS crud. - * f_pcbc.c (des_pcbc_encryption): Lint ivec. - * key_test.c: Toss the ridiculous doubled IBMPC/BSDUNIX printf's, - use a simple portable printf. Typo in msg. Pull RCS crud. - * new_rnd_key.c, quad_cksum.c, string_to_key.c: Lint. - * quad_cksum.c: Pull RCS crud. - -Sat May 21 03:37:01 1994 John Gilmore (gnu@cygnus.com) - - Microsoft Windows port. - - * Makefile.in (c-libdes.${LIBEXT)): Typo; and fix .o to .obj. - * des_internal.h: Remove pre-Fergusen stuff, leaving one #define. - * f_tables.h (FF_UINT32): Add this, which makes a KRB_UINT32 out - of a constant that might otherwise only be int or less. - * f_cbc.c, f_cksum.c, f_pcbc.c: Use it. Line up code neatly. - * key_sched.c: Lint, pull RCS crud. - * ren.msg: Insert column of entries for MIT PC release. - -Thu May 19 22:18:24 1994 John Gilmore (gnu@cygnus.com) - - More MS-Windows and Mac support. - - * cbc_noop.c, epc_encrypt.c: Delete two more unused remnants. - * ren.msg, Makefile.in: Remove references to remnants. - - * Makefile.in (OTHERSRCS, OTHEROBJS): Rename to FERG_* for clarity. - (SERVER_DES_{SRCS,OBJS}): Split out routines used only on servers. - (####): Move host-configuration insertion point so that the - per-host Makefile fragments can override the above. - (LIBEXT): Use it everywhere rather than ".a". - (libdes.$(LIBEXT)): Avoid making a .bak file. Add and - use $(ARCHIVEARGS) to allow making the incredible MSC LIB - command work. - (c-libdes.$(LIBEXT)): Add rule to build control file for MSC LIB. - This rule must run on Unix (FIXME) since it uses sed and tr. I - didn't know the equivalent DOS commands... - - * f_tables.h (DES_IP_RIGHT_BITS, DES_FP_RIGHT_BITS): Insert a cast - to unsigned, to circumvent a bug in the Macintosh MPW 3.2 C - compiler which loses the unsignedness and then does an arithmetic - shift rather than a logical shift. - (DEB): Add debug macro for very nested macro defns. - (DES_DO_ENCRYPT): Insert DEB calls to make it possible to - debug when DES fails. - -Fri May 13 01:59:09 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Change {} to () for Microsoft NMAKE. - * Makefile: Remove remnant of old config scheme. - * ren.msg: Specify short and long names for DOS file systems. - * key_test.c, quad_cksum.c, testit.c, verify.c: Pull unused - errmsg, errno. - -Sun May 8 17:21:50 1994 John Gilmore (gnu@cygnus.com) - - * read_password.c: Remove `sigtype', use typedef from osconf.h. - -Sat May 7 17:32:43 1994 John Gilmore (gnu@tweedledumb.cygnus.com) - - * Makefile.in: Don't build verify, key_test, and testit every - time we build the library. - - * Makefile.in: Update CODE for the removal. - - * cbc_encrypt.c, cksum.c, dbg_prt.c, des.c, desglue.c, destest.c, - key_parity.c, make_e.c, make_fp.c, make_ip.c, make_key_perm.c, - make_key_sched.c, make_odd.c, make_p.c, make_p_table.c, make_s.c, - make_s_table.c, misc.c, noop.c, pcbc_encrypt.c, s_table.h.ibm, - tables.h: Remove remnants of non-Fergusen DES code. These are all - unused, have long, non-DOSlike names, and confuse people (me - anyway) into thining that they're live code. - -Fri May 6 02:04:48 1994 John Gilmore (gnu@cygnus.com) - - * desglue.c (quad_cksum): Put argument declarations in order. - * pcbc_encrypt.c (des_pcbc_encrypt): Ditto. - * quad_cksum.c (des_quad_cksum): Ditto. - -Tue Oct 26 12:21:05 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * f_tables.h: Define const if not already defined and not - __STDC__. - -Sun Oct 17 13:47:28 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * f_*.c, f_tables.h, quad_cksum.c, testit.c, verify.c: Use - KRB_INT32 instead of long for 4-byte type. - - * f_tables.c: Include des.h. - - * string_to_key.c (des_string_to_key): Mask values to 32 bits - before printing. - - * testit.c (nflag): Set to 1; running 1000 identical iterations - was silly. - - * verify.c (print8): New routine. - (main): Clean up output formatting. - -Thu Feb 11 13:05:12 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * testit.c (main): Fix usage message. - - * Imakefile: Delete references to assembly code. - * key_sched.c: Ditto. Get rid of useless BIT macro. - -Wed Feb 10 14:17:31 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * des.c (des_ecb_encrypt): Fix pointer type lossage, and NULL/0 - confusion. Discard VAX-specific stuff. Add a couple of minor - optimizations, including some based on DES_SHIFT_SHIFT - conditional. - - * key_sched.c (make_key_sched): Fix inconsistent fwd declaration. - -Fri Jun 19 13:37:35 1992 Mark Eichin (eichin at tweedledumber.cygnus.com) - - * Imakefile (library_ro_object): punt the read-only object linker - mangling as it interferes with debugging. - -Tue Nov 8 12:12:32 1988 William Sommerfeld (wesommer at binkley) - - * (util) Remove \ before { and } characters (causes RT - compiler warning) - - * (read_password) Print a newline after saying "try again". - - * (read_password) Merge in changes by Jim Bloom to do a clearerr - after a read fails, and protect against an RTM attack by - changing gets to fgets. - -Fri Sep 16 16:26:55 1988 Bill Sommerfeld (wesommer at ra) - - * (read_password) fix dependancies for BSDUNIX. - -Mon Sep 12 14:55:23 1988 Bill Sommerfeld (wesommer at ra) - - * (*) debug->des_debug - - * (*) debug_print() -> des_debug_print() - - * (Makefile) add dbg_prt.o to list of files included in build. - - * (des.c) remove debug_print; it's in dbg_prt.c - - * (des_internal.h) contains definitions of AUTH_DES_ITER, - s-box structures, which aren't part of the encryption interface. - - * (*) #include "conf.h" -> #include "des_internal.h" - - * (*) C_Block -> des_cblock - - * (*) Key_schedule -> des_key_schedule - - * (noop.c) remove #includes for unused include files. - - * (des.c, random_key.c, string_to_key.c) add #include of "des_conf.h" - -Fri Sep 9 15:46:13 1988 Bill Sommerfeld (wesommer at ra) - - * (*) string_to_key() -> des_string_to_key() - - * (*) read_pw_string() -> des_read_pw_string() - - * (*) random_key() -> des_random_key() - - * (*) pcbc_encrypt() -> des_pcbc_encrypt() - - * (*) key_sched() -> des_key_sched() - - * (*) cbc_encrypt() -> des_cbc_encrypt() - - * (*) cbc_cksum() -> des_cbc_cksum() - - * (quad_cksum.c) make {four,two}_bytes_vax_to_nets be static to - avoid namespace pollution. - - * (*.c) Rename C_Block_print() to des_cblock_print(). - - * (make_key_perm.c) Make "key_perm" be static to avoid namespace - pollution. - - * (quad_cksum.c) Make "short_conv" and "long_conv" local - variables, to avoid namespace pollution. diff --git a/src/mac/libraries/DES/doc/READ_ME b/src/mac/libraries/DES/doc/READ_ME deleted file mode 100644 index 0228da44c..000000000 --- a/src/mac/libraries/DES/doc/READ_ME +++ /dev/null @@ -1,21 +0,0 @@ -This directory contains the sources for the DES encryption library and -test programs. - -Two precautions-- - -1) under US law, DES software and hardware may not be - exported without license from the US Dept of Commerce. - -2) The only way to get a significant speedup of the algorithm is to - use considerably more space, traded against time. Dont play - with the code -- there is a high probability you will either - make it slower, or wrong, or both. This implementation was - optimized for the UVAX 2. Other architectures could benefit from - some "asm" tweaking. - -3) If you do play with the code, make sure that the test program - "verify" still yields the expected answers. Otherwise, your - ciphertext will not decrypt under a standard implementation, such - as on the VLSI chips that have been certified. - - Project Athena Steve Miller 3/86 diff --git a/src/mac/libraries/DES/doc/f_README b/src/mac/libraries/DES/doc/f_README deleted file mode 100644 index 0d381e373..000000000 --- a/src/mac/libraries/DES/doc/f_README +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -Sorry about the poor quality of installation instructions. Included -here are replacements for the DES portions of Eric Young's kerberos -DES library replacement. To use this you will need his distribution. -Untar the latter and: - -(1) Copy all .c and .h files into the distribution directory. This will - overwrite some files and add others. - -(2) Apply the patch included here to set_key.c in the distribution directory. - -(3) Edit the Imakefile (or the Makefile) to include the following files - on the SRCS= line: - - des_tables.c ecb_buffer.c make_sched.c - - Add the following files to the OBJS= line: - - des_tables.o ecb_buffer.o make_sched.o - - Add the following file to the CODE= line: - - des_tables.h - -Recompile and you're done. - -The salient differences between this DES and Eric Young's are as follows: - -(1) There are no dependencies on byte ordering, the ability to do - unaligned loads and stores, or any other machine dependencies - that I know of. There are no #ifdef's. The code could probably - be made faster by adding such things, but not enough to be worth - it. - -(2) Combined S and P tables are used for the inner loop of the cipher - routine and the E expansion is computed on the fly, like Eric - Young's code, but the computation is reordered from the standard - to save instructions. - -(3) The initial and final permutations are table driven, and take - about the same amount of work as a single round of the inner - loop (i.e. only about 12% of the work done for an ecb encryption - is spent in the IP and FP code). - -(4) Since NTP (for which this DES was originally implemented) uses - lots of keys to encrypt small things, the key permutation code - has been well worked over and is quite speedy (the amount of - work required to permute a key is on the order of that required - to do a single ECB encryption, more or less). - -(5) Since the code required to do an ECB encryption using the tables - is actually fairly compact, even with lots of inlining, it was - implemented as a macro and is expanded in situ where needed. - -On the one machine I ran a comparison on this code ran 80% faster than -Eric's, compiled into a slightly smaller space, and did pass destest. -I suspect this stuff is also faster, and not a lot larger, than the -library MIT doesn't export with kerberos. You mileage may vary. - -The silly copyright was a (probably ineffective) afterthought. If it -really inconveniences you give me a call. diff --git a/src/mac/libraries/DES/doc/ren.msg b/src/mac/libraries/DES/doc/ren.msg deleted file mode 100644 index 3ee5d0af5..000000000 --- a/src/mac/libraries/DES/doc/ren.msg +++ /dev/null @@ -1,32 +0,0 @@ - MIT K4 patch10 MIT K4 PC PROPOSED NAME (trunc to 8.3) old Cyg -$1 $2 $3 $4 $5 $6 - -@ - - ChangeLog changelo -@ - debug.c debug_decl.c debug_de.c -@ - des_intn.h des_internal.h des_inte.h -@ - - doc doc -@ - enc.c enc.c enc.c -@ - - f_README f_readme -@ - - f_cbc.c f_cbc.c -@ - - f_cksum.c f_cksum.c -@ - - f_ecb.c f_ecb.c -@ - - f_parity.c f_parity.c -@ - - f_pcbc.c f_pcbc.c -@ - - f_sched.c f_sched.c -@ - - f_tables.c f_tables.c -@ - - f_tables.h f_tables.h -@ - keysched.c key_sched.c key_sche.c -@ - key_test.c key_test.c key_test.c -@ - - Makefile.in makefile.in -@ - newrndky.c new_rnd_key.c new_rnd_.c -@ - qd_cksum.c quad_cksum.c quad_cks.c -@ - rand_key.c random_key.c random_k.c -@ - rdpasswd.c read_password.c read_pas.c -@ - - READ_ME read_me -@ - - ren.msg ren.msg -@ - strtokey.c string_to_key.c string_t.c -@ - testit.c testit.c testit.c -@ - - unix_time.c unix_tim.c -@ - util.c util.c util.c -@ - verify.c verify.c verify.c -@ - weak_key.c weak_key.c weak_key.c diff --git a/src/mac/libraries/DES/include/des.h b/src/mac/libraries/DES/include/des.h deleted file mode 100644 index 8fa12ebf9..000000000 --- a/src/mac/libraries/DES/include/des.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * des.h - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * - * For copying and distribution information, please see the file - * (Except for those files which contain other copyright information). - * - * Include file for the Data Encryption Standard library. - */ - -/* only do the whole thing once */ -#ifndef DES_DEFS -#define DES_DEFS - -#include "mit-copyright.h" -#include - -#ifndef DES_INT32 -#define DES_INT32 SInt32 -#endif -#ifndef DES_UINT32 -#define DES_UINT32 UInt32 -#endif - -/* There are some declarations in the system-specific header files which - can't be done until DES_INT32 is defined. So they are in a macro, - which we expand here if defined. */ - -#ifdef DECL_THAT_NEEDS_DES_INT32 -DECL_THAT_NEEDS_DES_INT32 -#endif - -typedef unsigned char des_cblock[8]; /* crypto-block size */ -/* Key schedule */ -typedef struct des_ks_struct { union { DES_INT32 pad; 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) - -/* Function declarations */ - -/* This is CFM magic that has to be done in order for the library to work under CFM-68K */ -#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) -# pragma import on -#endif - -#if !GENERATINGCFM -# pragma d0_pointers on -#endif - -int des_cbc_encrypt(des_cblock *in, - des_cblock *out, - long length, - des_key_schedule schedule, - des_cblock ivec, - int encrypt); - -void des_3cbc_encrypt(des_cblock *in, - des_cblock *out, - long length, - des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - des_cblock ivec, - int encrypt); - -unsigned long des_cbc_cksum(des_cblock *in, - des_cblock *out, - long length, - des_key_schedule schedule, - des_cblock *ivec); - -int des_ecb_encrypt(des_cblock *in, - des_cblock *out, - des_key_schedule schedule, - int encrypt); - -void des_3ecb_encrypt(des_cblock *in, - des_cblock *out, - des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - int encrypt); - -void des_fixup_key_parity(register des_cblock key); -int des_check_key_parity(register des_cblock key); - -int des_pcbc_encrypt(des_cblock *in, - des_cblock *out, - long length, - des_key_schedule schedule, - des_cblock ivec, - int encrypt); - -int make_key_sched(des_cblock *key, des_key_schedule schedule); - -int des_key_sched(des_cblock k, des_key_schedule schedule); - -int des_new_random_key(des_cblock key); -void des_init_random_number_generator(des_cblock key); -void des_set_random_generator_seed(des_cblock key); -void des_set_sequence_number(des_cblock new_sequence_number); -void des_generate_random_block(des_cblock block); - -unsigned long des_quad_cksum(unsigned char *in, - unsigned long *out, - long length, - int out_count, - des_cblock *c_seed); - -int des_random_key(des_cblock *key); - -int des_read_password(des_cblock *k, char *prompt, int verify); -int des_read_pw_string(char *s, int max, char *prompt, int verify); - -int des_string_to_key(char *str, des_cblock key); - -void des_cblock_print_file(des_cblock *x, FILE *fp); - -int des_is_weak_key(des_cblock key); - -char *des_crypt(const char *buf, const char *salt); -char *des_fcrypt(const char *buf, const char *salt, char *ret); - -int des_set_key(des_cblock *key, des_key_schedule schedule); - -#if !GENERATINGCFM -# pragma d0_pointers reset -#endif - -/* CFM magic again */ -#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) -# pragma import reset -#endif - -#endif /* DES_DEFS */ diff --git a/src/mac/libraries/DES/include/deslib.CFMGlue.c b/src/mac/libraries/DES/include/deslib.CFMGlue.c deleted file mode 100644 index cfc4905e4..000000000 --- a/src/mac/libraries/DES/include/deslib.CFMGlue.c +++ /dev/null @@ -1,842 +0,0 @@ -#include -#include -#include - -#include "des.h" -#include "deslib.CFMGlue.h" - -/* These functions must obey CFM calling conventions. Functions which return - pointers must return them in D0, not A0 like ThinkC static 68k does. This way - we can call CFM functions by pointer from here (if they are called by pointer - then the compiler can't tell ahead of time to do D0->A0 translation because it - doesn't know what calling convention the functions use). - - Note that if it is necessary (if you don't use MPWC calling conventions) - the D0->A0 translation will be done by the compiler in the places where - the application calls these glue routines. */ -#pragma d0_pointers on - -/* Hardcode library fragment name here */ -#define kLibraryName "\pMIT_¥deslib" - -/* Private function prototypes */ - -static OSErr Find_Symbol( - Ptr* pSymAddr, - Str255 pSymName, - ProcInfoType pProcInfo); - -static pascal Boolean HaveCFM(void); - -static pascal OSErr GetSystemArchitecture(OSType *archType); - - -/* This code is directly from Technote 1077 */ -/* changed Library name to be hardcoded at the top of the file - instead in the middle of the code */ - -/* Private functions */ - -static pascal OSErr GetSystemArchitecture(OSType *archType) -{ - static long sSysArchitecture = 0; // static so we only Gestalt once. - OSErr tOSErr = noErr; - - *archType = kAnyCFragArch; // assume wild architecture - - // If we don't know the system architecture yet... - if (sSysArchitecture == 0) - // ...Ask Gestalt what kind of machine we are running on. - tOSErr = Gestalt(gestaltSysArchitecture, &sSysArchitecture); - - if (tOSErr == noErr) // if no errors - { - if (sSysArchitecture == gestalt68k) // 68k? - *archType = kMotorola68KCFragArch; - else if (sSysArchitecture == gestaltPowerPC) // PPC? - *archType = kPowerPCCFragArch; - else - tOSErr = gestaltUnknownErr; // who knows what might be next? - } - return tOSErr; -} - -static pascal Boolean HaveCFM(void) -{ - long response; - return ( (Gestalt (gestaltCFMAttr, &response) == noErr) && - (((response >> gestaltCFMPresent) & 1) != 0)); -} - -static OSErr Find_Symbol( - Ptr* pSymAddr, - Str255 pSymName, - ProcInfoType pProcInfo) -{ - static CFragConnectionID sCID = 0; - static OSType sArchType = kAnyCFragArch; - static OSErr sOSErr = noErr; - - Str255 errMessage; - Ptr mainAddr; - CFragSymbolClass symClass; - ISAType tISAType; - - if (sArchType == kAnyCFragArch) // if architecture is undefined... - { - sCID = 0; // ...force (re)connect to library - sOSErr = GetSystemArchitecture(&sArchType); // determine architecture - if (sOSErr != noErr) - return sOSErr; // OOPS! - } - - if (!HaveCFM()) { - // If we don't have CFM68K, return a reasonable-looking error. - sOSErr = cfragLibConnErr; - return sOSErr; - } - - if (sArchType == kMotorola68KCFragArch) // ...for CFM68K - tISAType = kM68kISA | kCFM68kRTA; - else if (sArchType == kPowerPCCFragArch) // ...for PPC CFM - tISAType = kPowerPCISA | kPowerPCRTA; - else - sOSErr = gestaltUnknownErr; // who knows what might be next? - - if (sCID == 0) // If we haven't connected to the library yet... - { - // NOTE: The library name is hard coded here. - // I try to isolate the glue code, one file per library. - // I have had developers pass in the Library name to allow - // plug-in type support. Additional code has to be added to - // each entry points glue routine to support multiple or - // switching connection IDs. - sOSErr = GetSharedLibrary(kLibraryName, sArchType, kLoadCFrag, - &sCID, &mainAddr, errMessage); - if (sOSErr != noErr) - return sOSErr; // OOPS! - } - - // If we haven't looked up this symbol yet... - if ((Ptr) *pSymAddr == (Ptr) kUnresolvedCFragSymbolAddress) - { - // ...look it up now - sOSErr = FindSymbol(sCID,pSymName,pSymAddr,&symClass); - if (sOSErr != noErr) // in case of error... - // ...clear the procedure pointer - *(Ptr*) &pSymAddr = (Ptr) kUnresolvedCFragSymbolAddress; -# if !GENERATINGCFM // if this is classic 68k code... - *pSymAddr = (Ptr)NewRoutineDescriptorTrap((ProcPtr) *pSymAddr, - pProcInfo, tISAType); // ...create a routine descriptor... -# endif - } - return sOSErr; -} - - -/* CFM Glue Code for exported functions! */ - -/**** des_random_key ****/ -/* int des_random_key(des_cblock *key); */ - -enum { - des_random_key_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) -}; - -typedef int (*des_random_key_ProcPtrType)(des_cblock *); -int des_random_key ( - des_cblock * key) -{ - static des_random_key_ProcPtrType des_random_key_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_random_key_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_random_key_ProcPtr, "\pdes_random_key", des_random_key_ProcInfo); - if((Ptr) des_random_key_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_random_key_ProcPtr(key); -} - - -/**** des_cbc_cksum ****/ -/* unsigned long des_cbc_cksum(des_cblock *in, des_cblock *out, long length, des_key_schedule schedule, des_cblock *ivec); */ - -enum { - des_cbc_cksum_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(unsigned long))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(des_cblock *))) -}; - -typedef unsigned long (*des_cbc_cksum_ProcPtrType)(des_cblock *, des_cblock *, long, des_key_schedule, des_cblock *); -unsigned long des_cbc_cksum ( - des_cblock * in, - des_cblock * out, - long length, - des_key_schedule schedule, - des_cblock * ivec) -{ - static des_cbc_cksum_ProcPtrType des_cbc_cksum_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_cbc_cksum_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_cbc_cksum_ProcPtr, "\pdes_cbc_cksum", des_cbc_cksum_ProcInfo); - if((Ptr) des_cbc_cksum_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_cbc_cksum_ProcPtr(in, out, length, schedule, ivec); -} - - -/**** des_is_weak_key ****/ -/* int des_is_weak_key(des_cblock key); */ - -enum { - des_is_weak_key_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef int (*des_is_weak_key_ProcPtrType)(des_cblock); -int des_is_weak_key ( - des_cblock key) -{ - static des_is_weak_key_ProcPtrType des_is_weak_key_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_is_weak_key_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_is_weak_key_ProcPtr, "\pdes_is_weak_key", des_is_weak_key_ProcInfo); - if((Ptr) des_is_weak_key_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_is_weak_key_ProcPtr(key); -} - - -/**** des_set_sequence_number ****/ -/* void des_set_sequence_number(des_cblock new_sequence_number); */ - -enum { - des_set_sequence_number_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef void (*des_set_sequence_number_ProcPtrType)(des_cblock); -void des_set_sequence_number ( - des_cblock new_sequence_number) -{ - static des_set_sequence_number_ProcPtrType des_set_sequence_number_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_set_sequence_number_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_set_sequence_number_ProcPtr, "\pdes_set_sequence_number", des_set_sequence_number_ProcInfo); - if((Ptr) des_set_sequence_number_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_set_sequence_number_ProcPtr(new_sequence_number); -} - - -/**** des_fixup_key_parity ****/ -/* void des_fixup_key_parity(register des_cblock key); */ - -enum { - des_fixup_key_parity_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef void (*des_fixup_key_parity_ProcPtrType)(register des_cblock); -void des_fixup_key_parity ( - register des_cblock key) -{ - static des_fixup_key_parity_ProcPtrType des_fixup_key_parity_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_fixup_key_parity_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_fixup_key_parity_ProcPtr, "\pdes_fixup_key_parity", des_fixup_key_parity_ProcInfo); - if((Ptr) des_fixup_key_parity_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_fixup_key_parity_ProcPtr(key); -} - - -/**** des_cbc_encrypt ****/ -/* int des_cbc_encrypt(des_cblock *in, des_cblock *out, long length, des_key_schedule schedule, des_cblock ivec, int encrypt); */ - -enum { - des_cbc_encrypt_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(int))) -}; - -typedef int (*des_cbc_encrypt_ProcPtrType)(des_cblock *, des_cblock *, long, des_key_schedule, des_cblock, int); -int des_cbc_encrypt ( - des_cblock * in, - des_cblock * out, - long length, - des_key_schedule schedule, - des_cblock ivec, - int encrypt) -{ - static des_cbc_encrypt_ProcPtrType des_cbc_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_cbc_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_cbc_encrypt_ProcPtr, "\pdes_cbc_encrypt", des_cbc_encrypt_ProcInfo); - if((Ptr) des_cbc_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_cbc_encrypt_ProcPtr(in, out, length, schedule, ivec, encrypt); -} - - -/**** des_quad_cksum ****/ -/* unsigned long des_quad_cksum(unsigned char *in, unsigned long *out, long length, int out_count, des_cblock *c_seed); */ - -enum { - des_quad_cksum_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(unsigned long))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(des_cblock *))) -}; - -typedef unsigned long (*des_quad_cksum_ProcPtrType)(unsigned char *, unsigned long *, long, int, des_cblock *); -unsigned long des_quad_cksum ( - unsigned char * in, - unsigned long * out, - long length, - int out_count, - des_cblock * c_seed) -{ - static des_quad_cksum_ProcPtrType des_quad_cksum_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_quad_cksum_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_quad_cksum_ProcPtr, "\pdes_quad_cksum", des_quad_cksum_ProcInfo); - if((Ptr) des_quad_cksum_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_quad_cksum_ProcPtr(in, out, length, out_count, c_seed); -} - - -/**** des_read_password ****/ -/* int des_read_password(des_cblock *k, char *prompt, int verify); */ - -enum { - des_read_password_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int))) -}; - -typedef int (*des_read_password_ProcPtrType)(des_cblock *, char *, int); -int des_read_password ( - des_cblock * k, - char * prompt, - int verify) -{ - static des_read_password_ProcPtrType des_read_password_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_read_password_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_read_password_ProcPtr, "\pdes_read_password", des_read_password_ProcInfo); - if((Ptr) des_read_password_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_read_password_ProcPtr(k, prompt, verify); -} - - -/**** des_ecb_encrypt ****/ -/* int des_ecb_encrypt(des_cblock *in, des_cblock *out, des_key_schedule schedule, int encrypt); */ - -enum { - des_ecb_encrypt_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int))) -}; - -typedef int (*des_ecb_encrypt_ProcPtrType)(des_cblock *, des_cblock *, des_key_schedule, int); -int des_ecb_encrypt ( - des_cblock * in, - des_cblock * out, - des_key_schedule schedule, - int encrypt) -{ - static des_ecb_encrypt_ProcPtrType des_ecb_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_ecb_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_ecb_encrypt_ProcPtr, "\pdes_ecb_encrypt", des_ecb_encrypt_ProcInfo); - if((Ptr) des_ecb_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_ecb_encrypt_ProcPtr(in, out, schedule, encrypt); -} - - -/**** des_3ecb_encrypt ****/ -/* void des_3ecb_encrypt(des_cblock *in, des_cblock *out, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3, int encrypt); */ - -enum { - des_3ecb_encrypt_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(int))) -}; - -typedef void (*des_3ecb_encrypt_ProcPtrType)(des_cblock *, des_cblock *, des_key_schedule, des_key_schedule, des_key_schedule, int); -void des_3ecb_encrypt ( - des_cblock * in, - des_cblock * out, - des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - int encrypt) -{ - static des_3ecb_encrypt_ProcPtrType des_3ecb_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_3ecb_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_3ecb_encrypt_ProcPtr, "\pdes_3ecb_encrypt", des_3ecb_encrypt_ProcInfo); - if((Ptr) des_3ecb_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_3ecb_encrypt_ProcPtr(in, out, ks1, ks2, ks3, encrypt); -} - - -/**** des_key_sched ****/ -/* int des_key_sched(des_cblock k, des_key_schedule schedule); */ - -enum { - des_key_sched_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(struct des_ks_struct *))) -}; - -typedef int (*des_key_sched_ProcPtrType)(des_cblock, des_key_schedule); -int des_key_sched ( - des_cblock k, - des_key_schedule schedule) -{ - static des_key_sched_ProcPtrType des_key_sched_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_key_sched_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_key_sched_ProcPtr, "\pdes_key_sched", des_key_sched_ProcInfo); - if((Ptr) des_key_sched_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_key_sched_ProcPtr(k, schedule); -} - - -/**** des_3pcbc_encrypt ****/ -/* void des_3pcbc_encrypt(des_cblock *input, des_cblock *output, long length, des_key_schedule schedule1, des_cblock ivec1, des_key_schedule schedule2, des_cblock ivec2, des_key_schedule schedule3, des_cblock ivec3, int encrypt); */ -/* -enum { - des_3pcbc_encrypt_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(8, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(9, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(10, SIZE_CODE(sizeof(int))) -}; - -typedef void (*des_3pcbc_encrypt_ProcPtrType)(des_cblock *, des_cblock *, long, des_key_schedule, des_cblock, des_key_schedule, des_cblock, des_key_schedule, des_cblock, int); -void des_3pcbc_encrypt ( - des_cblock * input, - des_cblock * output, - long length, - des_key_schedule schedule1, - des_cblock ivec1, - des_key_schedule schedule2, - des_cblock ivec2, - des_key_schedule schedule3, - des_cblock ivec3, - int encrypt) -{ - static des_3pcbc_encrypt_ProcPtrType des_3pcbc_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_3pcbc_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_3pcbc_encrypt_ProcPtr, "\pdes_3pcbc_encrypt", des_3pcbc_encrypt_ProcInfo); - if((Ptr) des_3pcbc_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_3pcbc_encrypt_ProcPtr(input, output, length, schedule1, ivec1, schedule2, ivec2, schedule3, ivec3, encrypt); -} -*/ - -/**** make_key_sched ****/ -/* int make_key_sched(des_cblock *key, des_key_schedule schedule); */ - -enum { - make_key_sched_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(struct des_ks_struct *))) -}; - -typedef int (*make_key_sched_ProcPtrType)(des_cblock *, des_key_schedule); -int make_key_sched ( - des_cblock * key, - des_key_schedule schedule) -{ - static make_key_sched_ProcPtrType make_key_sched_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) make_key_sched_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &make_key_sched_ProcPtr, "\pmake_key_sched", make_key_sched_ProcInfo); - if((Ptr) make_key_sched_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return make_key_sched_ProcPtr(key, schedule); -} - - -/**** des_crypt ****/ -/* char *des_crypt(const char *buf, const char *salt); */ - -enum { - des_crypt_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(const char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char *))) -}; - -typedef char * (*des_crypt_ProcPtrType)(const char *, const char *); -char * des_crypt ( - const char * buf, - const char * salt) -{ - static des_crypt_ProcPtrType des_crypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_crypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_crypt_ProcPtr, "\pdes_crypt", des_crypt_ProcInfo); - if((Ptr) des_crypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return(des_crypt_ProcPtr(buf, salt)); -} - - -/**** des_set_random_generator_seed ****/ -/* void des_set_random_generator_seed(des_cblock key); */ - -enum { - des_set_random_generator_seed_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef void (*des_set_random_generator_seed_ProcPtrType)(des_cblock); -void des_set_random_generator_seed ( - des_cblock key) -{ - static des_set_random_generator_seed_ProcPtrType des_set_random_generator_seed_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_set_random_generator_seed_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_set_random_generator_seed_ProcPtr, "\pdes_set_random_generator_seed", des_set_random_generator_seed_ProcInfo); - if((Ptr) des_set_random_generator_seed_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_set_random_generator_seed_ProcPtr(key); -} - - -/**** des_new_random_key ****/ -/* int des_new_random_key(des_cblock key); */ - -enum { - des_new_random_key_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef int (*des_new_random_key_ProcPtrType)(des_cblock); -int des_new_random_key ( - des_cblock key) -{ - static des_new_random_key_ProcPtrType des_new_random_key_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_new_random_key_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_new_random_key_ProcPtr, "\pdes_new_random_key", des_new_random_key_ProcInfo); - if((Ptr) des_new_random_key_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_new_random_key_ProcPtr(key); -} - - -/**** des_set_key ****/ -/* int des_set_key(des_cblock *key, des_key_schedule schedule); */ - -enum { - des_set_key_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(struct des_ks_struct *))) -}; - -typedef int (*des_set_key_ProcPtrType)(des_cblock *, des_key_schedule); -int des_set_key ( - des_cblock * key, - des_key_schedule schedule) -{ - static des_set_key_ProcPtrType des_set_key_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_set_key_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_set_key_ProcPtr, "\pdes_set_key", des_set_key_ProcInfo); - if((Ptr) des_set_key_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_set_key_ProcPtr(key, schedule); -} - - -/**** des_generate_random_block ****/ -/* void des_generate_random_block(des_cblock block); */ - -enum { - des_generate_random_block_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef void (*des_generate_random_block_ProcPtrType)(des_cblock); -void des_generate_random_block ( - des_cblock block) -{ - static des_generate_random_block_ProcPtrType des_generate_random_block_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_generate_random_block_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_generate_random_block_ProcPtr, "\pdes_generate_random_block", des_generate_random_block_ProcInfo); - if((Ptr) des_generate_random_block_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_generate_random_block_ProcPtr(block); -} - - -/**** des_fcrypt ****/ -/* char *des_fcrypt(const char *buf, const char *salt, char *ret); */ - -enum { - des_fcrypt_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(const char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(char *))) -}; - -typedef char * (*des_fcrypt_ProcPtrType)(const char *, const char *, char *); -char * des_fcrypt ( - const char * buf, - const char * salt, - char * ret) -{ - static des_fcrypt_ProcPtrType des_fcrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_fcrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_fcrypt_ProcPtr, "\pdes_fcrypt", des_fcrypt_ProcInfo); - if((Ptr) des_fcrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_fcrypt_ProcPtr(buf, salt, ret); -} - - -/**** des_read_pw_string ****/ -/* int des_read_pw_string(char *s, int max, char *prompt, int verify); */ - -enum { - des_read_pw_string_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int))) -}; - -typedef int (*des_read_pw_string_ProcPtrType)(char *, int, char *, int); -int des_read_pw_string ( - char * s, - int max, - char * prompt, - int verify) -{ - static des_read_pw_string_ProcPtrType des_read_pw_string_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_read_pw_string_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_read_pw_string_ProcPtr, "\pdes_read_pw_string", des_read_pw_string_ProcInfo); - if((Ptr) des_read_pw_string_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_read_pw_string_ProcPtr(s, max, prompt, verify); -} - - -/**** des_cblock_print_file ****/ -/* void des_cblock_print_file(des_cblock *x, FILE *fp); */ - -enum { - des_cblock_print_file_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(FILE *))) -}; - -typedef void (*des_cblock_print_file_ProcPtrType)(des_cblock *, FILE *); -void des_cblock_print_file ( - des_cblock * x, - FILE * fp) -{ - static des_cblock_print_file_ProcPtrType des_cblock_print_file_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_cblock_print_file_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_cblock_print_file_ProcPtr, "\pdes_cblock_print_file", des_cblock_print_file_ProcInfo); - if((Ptr) des_cblock_print_file_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_cblock_print_file_ProcPtr(x, fp); -} - - -/**** des_pcbc_encrypt ****/ -/* int des_pcbc_encrypt(des_cblock *in, des_cblock *out, long length, des_key_schedule schedule, des_cblock ivec, int encrypt); */ - -enum { - des_pcbc_encrypt_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(struct des_ks_struct *))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(unsigned char *))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(int))) -}; - -typedef int (*des_pcbc_encrypt_ProcPtrType)(des_cblock *, des_cblock *, long, des_key_schedule, des_cblock, int); -int des_pcbc_encrypt ( - des_cblock * in, - des_cblock * out, - long length, - des_key_schedule schedule, - des_cblock ivec, - int encrypt) -{ - static des_pcbc_encrypt_ProcPtrType des_pcbc_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_pcbc_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_pcbc_encrypt_ProcPtr, "\pdes_pcbc_encrypt", des_pcbc_encrypt_ProcInfo); - if((Ptr) des_pcbc_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_pcbc_encrypt_ProcPtr(in, out, length, schedule, ivec, encrypt); -} - - -/**** des_check_key_parity ****/ -/* int des_check_key_parity(register des_cblock key); */ - -enum { - des_check_key_parity_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef int (*des_check_key_parity_ProcPtrType)(register des_cblock); -int des_check_key_parity ( - register des_cblock key) -{ - static des_check_key_parity_ProcPtrType des_check_key_parity_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_check_key_parity_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_check_key_parity_ProcPtr, "\pdes_check_key_parity", des_check_key_parity_ProcInfo); - if((Ptr) des_check_key_parity_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_check_key_parity_ProcPtr(key); -} - - -/**** des_3cbc_encrypt ****/ -/* void des_3cbc_encrypt(des_cblock *in, des_cblock *out, long length, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3, des_cblock ivec, int encrypt); */ - -enum { - des_3cbc_encrypt_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(des_cblock *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(des_key_schedule))) - | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(des_cblock))) - | STACK_ROUTINE_PARAMETER(8, SIZE_CODE(sizeof(int))) -}; - -typedef void (*des_3cbc_encrypt_ProcPtrType)(des_cblock *, des_cblock *, long, des_key_schedule, des_key_schedule, des_key_schedule, des_cblock, int); -void des_3cbc_encrypt ( - des_cblock * in, - des_cblock * out, - long length, - des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - des_cblock ivec, - int encrypt) -{ - static des_3cbc_encrypt_ProcPtrType des_3cbc_encrypt_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_3cbc_encrypt_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_3cbc_encrypt_ProcPtr, "\pdes_3cbc_encrypt", des_3cbc_encrypt_ProcInfo); - if((Ptr) des_3cbc_encrypt_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_3cbc_encrypt_ProcPtr(in, out, length, ks1, ks2, ks3, ivec, encrypt); -} - - -/**** des_string_to_key ****/ -/* int des_string_to_key(char *str, des_cblock key); */ - -enum { - des_string_to_key_ProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(int))) - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef int (*des_string_to_key_ProcPtrType)(char *, des_cblock); -int des_string_to_key ( - char * str, - des_cblock key) -{ - static des_string_to_key_ProcPtrType des_string_to_key_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_string_to_key_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_string_to_key_ProcPtr, "\pdes_string_to_key", des_string_to_key_ProcInfo); - if((Ptr) des_string_to_key_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - return des_string_to_key_ProcPtr(str, key); -} - - -/**** des_init_random_number_generator ****/ -/* void des_init_random_number_generator(des_cblock key); */ - -enum { - des_init_random_number_generator_ProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) -}; - -typedef void (*des_init_random_number_generator_ProcPtrType)(des_cblock); -void des_init_random_number_generator ( - des_cblock key) -{ - static des_init_random_number_generator_ProcPtrType des_init_random_number_generator_ProcPtr = kUnresolvedCFragSymbolAddress; - - // if this symbol has not been setup yet... - if((Ptr) des_init_random_number_generator_ProcPtr == (Ptr) kUnresolvedCFragSymbolAddress) - Find_Symbol((Ptr *) &des_init_random_number_generator_ProcPtr, "\pdes_init_random_number_generator", des_init_random_number_generator_ProcInfo); - if((Ptr) des_init_random_number_generator_ProcPtr != (Ptr) kUnresolvedCFragSymbolAddress) - des_init_random_number_generator_ProcPtr(key); -} - - -Boolean DESLibraryIsPresent(void) -{ - Ptr symAddr; - return (Find_Symbol (&symAddr, "\pdes_cbc_encrypt", des_cbc_encrypt_ProcInfo)) == noErr; -} diff --git a/src/mac/libraries/DES/include/deslib.CFMGlue.h b/src/mac/libraries/DES/include/deslib.CFMGlue.h deleted file mode 100644 index 7f4277f46..000000000 --- a/src/mac/libraries/DES/include/deslib.CFMGlue.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __DESLIB_CFMGLUE__ -#define __DESLIB_CFMGLUE__ - -/* Prototype for checking if the library is there */ - -Boolean DESLibraryIsPresent(void); - -#endif /* __DESLIB_CFMGLUE__ */ \ No newline at end of file diff --git a/src/mac/libraries/DES/include/mit-copyright.h b/src/mac/libraries/DES/include/mit-copyright.h deleted file mode 100644 index cd30580ce..000000000 --- a/src/mac/libraries/DES/include/mit-copyright.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - 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/src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.doc b/src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.doc deleted file mode 100644 index 95040d6f8..000000000 --- a/src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.doc +++ /dev/null @@ -1,31 +0,0 @@ -Changes between CodeWarrior Pro 2 and MITAthena MSL project: - - - ÒMSL C.CFM68K DLL.mcpÓ renamed to ÒMIT C.CFM68K DLL.prjÓ - - This document added to the project - - ÒMSL MWRuntimeLibCFM68KÓ removed from the project - - Changed settings in ÒMSL C.CFM68K DLLÓ target - - Added ÒMIT C.CFM68K DLL.debugÓ target - -Changes to ÒMSL C.CFM68K DLLÓ target: - - - Added ÒMIT RuntimeLib.68KÓ - - Name set to ÒMIT C.CFM68K DLLÓ - - Output directory changed to Ò{Project Ä}::bin:Ó - - Added Ò{Compiler Ä}:Metrowerks Standard Library:MSL C:Ó to user paths - ¥¥¥ Important: this path must come after Ò{Project Ä}::Ó so that we can override - ¥¥¥ original MSL with our own sources - - Turned on ÒActivate BrowserÓ - - Changed output file name to ÒMIT CLib.68KÓ - - Changed output file creator to '????' - - Changed CFM68K fragment name to ÒMIT_¥MITCLibÓ - -Configuration of the ÒMIT C.CFM68K DLL.debugÓ target: - - - Added ÒMIT RuntimeLib.68K.debugÓ - - Started by cloning ÒMIT C.CFM68K DLLÓ target after making the above modifications - - Changed output file name to ÒMIT CLib.68K.debugÓ - - Peephole optimizer turned off - - CSE optimizer turned off - - Optimize for size turned off - - Generating SYM files turned on - - Changed CFM68K fragment name to ÒMIT_¥MIT CLib.debugÓ diff --git a/src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.prj b/src/mac/libraries/Metrowerks/CW Pro 2/MIT C.CFM68K DLL.prj deleted file mode 100644 index 5f53c8a05b1d68e64f5e077344cfc3d5546751e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86057 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 UBtwOGc(v^(;<0rIpf2(M0nniYF8}}l diff --git a/src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.doc b/src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.doc deleted file mode 100644 index 8d9795c58..000000000 --- a/src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.doc +++ /dev/null @@ -1,31 +0,0 @@ -Changes between CodeWarrior Pro 2 and MITAthena MSL project: - - - ÒMSL MWRuntimeLibCFM68K.mcpÓ renamed to ÒMIT RuntimeCFM68K DLL.prjÓ - - This document added to the project - - Changed settings in ÒMSL MWRuntimeLibCFM68KÓ target - - Added ÒMIT RuntimeCFM68K DLL.debugÓ target - -Changes to ÒMSL MWRuntimeLibCFM68KÓ target: - - - Target name set to ÒMIT RuntimeCFM68K DLLÓ - - Output directory changed to Ò{Project Ä}::bin:Ó - - Set user paths to: - Ò{Project Ä}::Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Runtime CFM68K:(Sources):Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Common Sources:Ó - ¥¥¥ Important: the compiler-relative paths must come after Ò{Project Ä}::Ó so that - ¥¥¥ we can override original sources with our own - - Turned on ÒActivate BrowserÓ - - Changed output file name to ÒMIT RuntimeLib.68KÓ - - Changed output file creator to '????' - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLibÓ - -Configuration of the ÒMIT RuntimeCFM68K DLL.debugÓ target: - - - Started by cloning ÒMIT RuntimeCFM68K DLLÓ target after making the above modifications - - Changed output file name to ÒMIT RuntimeLib.68K.debugÓ - - Peephole optimizer turned off - - CSE optimizer turned off - - Optimize for size turned off - - Generating SYM files turned on - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLib.debugÓ diff --git a/src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.prj b/src/mac/libraries/Metrowerks/CW Pro 2/MIT RuntimeCFM68K DLL.prj deleted file mode 100644 index 197a283aa40af2c5423e1d22e75f3e5b2ae65d47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83326 zcmeHw3wT^db^qMe>MhHXW6O^7+Bgq8aZvn6IARf!vmlj7Du%u(be1e0_CO*XKEcQp6>??n?i8RNxcdnIJ z;$x37_Rh!X4}>ISB%bSyXAkxaMRP4XH0F-kZ0hkuibn5c%Y z0W1Nu0@?vVKrH|@8mk9102%>J0D1<=z6>}etR37I5Q|-J{i!uv69zf3at{mK-Un$4NK09tUT+Ux(6*-af592J2k$7e@9vYlI!3OUgaNR>g13a3+-hrJr z#11AVs14maGStIk#x+W&0%*_Y9ZxF1uJZ&J`6R%0lp{p3L=mvbC1DLX$dX+h#94p< zpa!r6&~+rNmvKp5O#}CXWVHN_G@Lb5<>afht%k8pO|U z<#^t+laeR6BCXxYiA+424ed(J%*3e=UzwxW;twqV)!B>Kks=nm4rKO|F$RYR2S=Ue zP`h*Zx*?lkdC!i>)@^%2BeUsrDw7NCNKD7GxLC8Jf1r;vDZ_vaYaBNR+I!ZoFT1l| zat38sE5kY&+SeQ8??xFmIV9IK4kX4i(M*EJ#eR0Pd8yw; zuB$%r->*hM*l@xc{QwL^hqu#)lHITz~SW6tfP3C7wf@ z7hD$U9}Nx9CUc3II3m>vW#NC1kZRylZy`H1J#N5i#6t4&jMrHYT8)AC=6^d7%6jSQ zMWy7R*jJ3h{rj`IDEBfa*lRL=lsn^z_XLZ(CCx?6hN!fgzW=+t>J;^~v$nQa;1}OT zgsAs#%jpMRV^P1KG3tv312^w`7U7+MT5An_#-0S!Sv2P0BNz0#Xt-+iKI}0_+0C19d_8!bH0e>0z zIaFZ){~zGzw)R}!1NEH`{Ji937Ne+OAMns{XfO?&G=OW?9Ps;rlV%bB;L`{%0APd^ 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 LJ~#$OlHC6fNy)n< diff --git a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.doc b/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.doc deleted file mode 100644 index 9cfd52708..000000000 --- a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.doc +++ /dev/null @@ -1,30 +0,0 @@ -Changes between CodeWarrior Pro 4 and MITAthena MSL project: - - - ÒMSL MWRuntimeLibCFM68K.mcpÓ renamed to ÒMIT RuntimeCFM68K DLL.prjÓ - - This document added to the project - - Changed settings in ÒMSL MWRuntimeLibCFM68KÓ target - - Added ÒMIT RuntimeCFM68K DLL.debugÓ target - -Changes to ÒMSL MWRuntimeLibCFM68KÓ target: - - - Target name set to ÒMIT RuntimeCFM68K DLLÓ - - Output directory changed to Ò{Project Ä}::bin:Ó - - Set user paths to: - Ò{Project Ä}::Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Runtime CFM68K:(Sources):Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Common Sources:Ó - ¥¥¥ Important: the compiler-relative paths must come after Ò{Project Ä}::Ó so that - ¥¥¥ we can override original sources with our own - - Turned on ÒActivate BrowserÓ - - Changed output file name to ÒMIT RuntimeLib.68KÓ - - Changed output file creator to '????' - - Global optimizations turned off - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLibÓ - -Configuration of the ÒMIT RuntimeCFM68K DLL.debugÓ target: - - - Started by cloning ÒMIT RuntimeCFM68K DLLÓ target after making the above modifications - - Changed output file name to ÒMIT RuntimeLib.68K.debugÓ - - Global optimizations turned off - - Generating SYM files turned on - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLib.debugÓ diff --git a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.prj b/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimeCFM68K DLL.prj deleted file mode 100644 index 3a60365d79e2505e88d2df4073f09ac62f0bd131..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80278 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 ghEz0jm%-EJ`5S);lw&0S2f4b&!2kdN diff --git a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.doc b/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.doc deleted file mode 100644 index 2536928fd..000000000 --- a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.doc +++ /dev/null @@ -1,32 +0,0 @@ -Changes between CodeWarrior Pro 4 and MITAthena MSL project: - - - ÒMSL RuntimePPC.mcpÓ renamed to ÒMIT RuntimePPC DLL.prjÓ - - This document added to the project - - Changed settings in ÒMSL RuntimePPC DLLÓ target - - Added ÒMIT RuntimePPC.debugÓ target - -Changes to ÒMSL RuntimePPCÓ target: - - - Name set to ÒMIT RuntimePPC DLLÓ - - Output directory changed to Ò{Project Ä}::bin:Ó - - Set user paths to: - Ò{Project Ä}::Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Runtime PPC:(Sources):Ó - Ò{Compiler Ä}:MacOS Support:Libraries:Runtime:Common Sources:Ó - ¥¥¥ Important: the compiler-relative paths must come after Ò{Project Ä}::Ó so that - ¥¥¥ we can override original sources with our own - - Turned on ÒActivate BrowserÓ - - Changed output file name to ÒMIT RuntimeLib.PPCÓ - - Changed output file creator to '????' - - GLobal optimizations turned off (because of reports of optimizer bugs) - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLibÓ - -Configuration of the ÒMIT RuntimePPC DLL.debugÓ target: - - - Started by cloning ÒMIT RuntimePPC DLLÓ target after making the above modifications - - Changed output file name to ÒMIT RuntimeLib.PPC.debugÓ - - Schedule instructions turned off - - Peephole optimization turned off - - Generating SYM files turned on - - Global optimizations turned off - - Changed PPC PEF fragment name to ÒMIT_¥MITRuntimeLib.debugÓ diff --git a/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.prj b/src/mac/libraries/Metrowerks/CW Pro 4/MIT RuntimePPC DLL.prj deleted file mode 100644 index 4cd7f7829806204cd4318e417987bb86845088aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91916 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 + + * kpropd.c (authorized_principal): make the acl file contain + etypes, and use that in the authorization process. + Wed Feb 18 16:27:28 1998 Tom Yu * Makefile.in (thisconfigdir): Remove trailing slash. diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c index 3db4d0bb7..70f07b369 100644 --- a/src/slave/kpropd.c +++ b/src/slave/kpropd.c @@ -1,3 +1,29 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + /* * slave/kpropd.c * @@ -91,10 +117,12 @@ void kerberos_authenticate PROTOTYPE((krb5_context, int, krb5_principal *, + krb5_enctype *, struct sockaddr_in)); krb5_boolean authorized_principal PROTOTYPE((krb5_context, - krb5_principal)); + krb5_principal, + krb5_enctype)); void recv_database PROTOTYPE((krb5_context, int, @@ -237,6 +265,7 @@ void doit(fd) krb5_data confmsg; int lock_fd; int omask; + krb5_enctype etype; fromlen = sizeof (from); if (getpeername(fd, (struct sockaddr *) &from, &fromlen) < 0) { @@ -266,8 +295,9 @@ void doit(fd) /* * Now do the authentication */ - kerberos_authenticate(kpropd_context, fd, &client, from); - if (!authorized_principal(kpropd_context, client)) { + kerberos_authenticate(kpropd_context, fd, &client, &etype, from); + + if (!authorized_principal(kpropd_context, client, etype)) { char *name; if (retval = krb5_unparse_name(kpropd_context, client, &name)) { @@ -495,10 +525,11 @@ void PRS(argv) * Figure out who's calling on the other end of the connection.... */ void -kerberos_authenticate(context, fd, clientp, sin) +kerberos_authenticate(context, fd, clientp, etype, sin) krb5_context context; int fd; krb5_principal * clientp; + krb5_enctype * etype; struct sockaddr_in sin; { krb5_error_code retval; @@ -577,29 +608,42 @@ kerberos_authenticate(context, fd, clientp, sin) exit(1); } + *etype = ticket->enc_part.enctype; + if (debug) { char * name; + char etypebuf[100]; if (retval = krb5_unparse_name(context, *clientp, &name)) { com_err(progname, retval, "While unparsing client name"); exit(1); } - printf("authenticated client: %s\n", name); + + if (retval = krb5_enctype_to_string(*etype, etypebuf, + sizeof(etypebuf))) { + com_err(progname, retval, "While unparsing ticket etype"); + exit(1); + } + + printf("authenticated client: %s (etype == %s)\n", name, etypebuf); free(name); } + krb5_free_ticket(context, ticket); } krb5_boolean -authorized_principal(context, p) +authorized_principal(context, p, auth_etype) krb5_context context; krb5_principal p; + krb5_enctype auth_etype; { - char *name; + char *name, *ptr; char buf[1024]; krb5_error_code retval; FILE *acl_file; int end; + krb5_enctype acl_etype; retval = krb5_unparse_name(context, p, &name); if (retval) @@ -615,7 +659,27 @@ authorized_principal(context, p) end = strlen(buf) - 1; if (buf[end] == '\n') buf[end] = '\0'; - if (!strcmp(name, buf)) { + if (!strncmp(name, buf, strlen(name))) { + ptr = buf+strlen(name); + + /* if the next character is not whitespace or nul, then + the match is only partial. continue on to new lines. */ + if (*ptr && !isspace(*ptr)) + continue; + + /* otherwise, skip trailing whitespace */ + for (; *ptr && isspace(*ptr); ptr++) ; + + /* now, look for an etype string. if there isn't one, + return true. if there is an invalid string, continue. + If there is a valid string, return true only if it + matches the etype passed in, otherwise continue */ + + if ((*ptr) && + ((retval = krb5_string_to_enctype(ptr, &acl_etype)) || + (acl_etype != auth_etype))) + continue; + free(name); fclose(acl_file); return TRUE; diff --git a/src/tests/create/ChangeLog b/src/tests/create/ChangeLog index 64e0b2801..ecb782e71 100644 --- a/src/tests/create/ChangeLog +++ b/src/tests/create/ChangeLog @@ -1,3 +1,7 @@ +1998-10-27 Marc Horowitz + + * kdb5_mkdums.c: update to new crypto api + 1998-05-06 Theodore Ts'o * kdb5_mkdums.c (argv): POSIX states that getopt returns -1 diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c index 18ee9e8ac..4f9376670 100644 --- a/src/tests/create/kdb5_mkdums.c +++ b/src/tests/create/kdb5_mkdums.c @@ -65,7 +65,6 @@ int status; krb5_keyblock master_keyblock; krb5_principal master_princ; krb5_db_entry master_entry; -krb5_encrypt_block master_encblock; krb5_pointer master_random; krb5_context test_context; @@ -175,8 +174,6 @@ char *argv[]; exit(1); } - krb5_use_enctype(test_context, &master_encblock, master_keyblock.enctype); - if (!dbname) dbname = DEFAULT_KDB_FILE; /* XXX? */ @@ -207,9 +204,6 @@ char *argv[]; } } - krb5_finish_random_key(test_context, &master_encblock, &master_random); - krb5_finish_key(test_context, &master_encblock); - retval = krb5_db_fini(test_context); memset((char *)master_keyblock.contents, 0, master_keyblock.length); if (retval && retval != KRB5_KDB_DBNOTINITED) { @@ -280,8 +274,8 @@ add_princ(context, str_newprinc) pwd.length = strlen(princ_name); pwd.data = princ_name; /* must be able to regenerate */ - if ((retval = krb5_string_to_key(context, &master_encblock, - &key, &pwd, &salt))) { + if ((retval = krb5_c_string_to_key(context, master_keyblock.enctype, + &pwd, &salt, &key))) { com_err(progname,retval,"while converting password to key for '%s'", princ_name); krb5_free_data_contents(context, &salt); @@ -296,7 +290,7 @@ add_princ(context, str_newprinc) goto error; } - if ((retval = krb5_dbekd_encrypt_key_data(context,&master_encblock, + if ((retval = krb5_dbekd_encrypt_key_data(context,&master_keyblock, &key, NULL, 1, newentry.key_data))) { com_err(progname, retval, "while encrypting key for '%s'", @@ -357,8 +351,10 @@ char *dbname; com_err(pname, retval, "while calculated master key salt"); return(1); } - if ((retval = krb5_string_to_key(test_context, &master_encblock, - &master_keyblock, &pwd, &scratch))) { + if ((retval = krb5_c_string_to_key(test_context, + master_keyblock.enctype, + &pwd, &scratch, + &master_keyblock))) { com_err(pname, retval, "while transforming master key from password"); return(1); @@ -366,7 +362,7 @@ char *dbname; free(scratch.data); } else { if ((retval = krb5_db_fetch_mkey(test_context, master_princ, - &master_encblock, manual_mkey, + master_keyblock.enctype, manual_mkey, FALSE, 0, NULL, &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); @@ -377,7 +373,7 @@ char *dbname; return(1); } if ((retval = krb5_db_verify_master_key(test_context, master_princ, - &master_keyblock, &master_encblock))){ + &master_keyblock))){ com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(test_context); return(1); @@ -399,20 +395,6 @@ char *dbname; return(1); } - if ((retval = krb5_process_key(test_context, - &master_encblock, &master_keyblock))) { - com_err(pname, retval, "while processing master key"); - (void) krb5_db_fini(test_context); - return(1); - } - if ((retval = krb5_init_random_key(test_context, - &master_encblock, &master_keyblock, - &master_random))) { - com_err(pname, retval, "while initializing random key generator"); - krb5_finish_key(test_context, &master_encblock); - (void) krb5_db_fini(test_context); - return(1); - } mblock.max_life = master_entry.max_life; mblock.max_rlife = master_entry.max_renewable_life; mblock.expiration = master_entry.expiration; diff --git a/src/tests/misc/test_nfold.c b/src/tests/misc/test_nfold.c new file mode 100644 index 000000000..78b586618 --- /dev/null +++ b/src/tests/misc/test_nfold.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * 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. + */ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int inlen, outlen, i; + unsigned char *instr, *outstr; + + if (argc != 3) { + fprintf(stderr, "%s: instr outlen\n", argv[0]); + exit(1); + } + + instr = (unsigned char *) argv[1]; + inlen = strlen(instr)*8; + outlen = atoi(argv[2]); + if (outlen%8) { + fprintf(stderr, "outlen must be a multiple of 8\n"); + exit(1); + } + + if ((outstr = (unsigned char *) malloc(outlen/8)) == NULL) { + fprintf(stderr, "ENOMEM\n"); + exit(1); + } + + krb5_nfold(inlen,instr,outlen,outstr); + + printf("%d-fold(",outlen); + for (i=0; i<(inlen/8); i++) + printf("%02x",instr[i]); + printf(") = "); + for (i=0; i<(outlen/8); i++) + printf("%02x",outstr[i]); + printf("\n"); + + exit(0); +} diff --git a/src/tests/verify/ChangeLog b/src/tests/verify/ChangeLog index 12fb1f93b..7f4aaf5a5 100644 --- a/src/tests/verify/ChangeLog +++ b/src/tests/verify/ChangeLog @@ -1,3 +1,7 @@ +1998-10-27 Marc Horowitz + + * kdb5_verify.c: update to new crypto api + 1998-05-06 Theodore Ts'o * kdb5_verify.c (argv): POSIX states that getopt returns -1 diff --git a/src/tests/verify/kdb5_verify.c b/src/tests/verify/kdb5_verify.c index 8a95d7125..558ef2533 100644 --- a/src/tests/verify/kdb5_verify.c +++ b/src/tests/verify/kdb5_verify.c @@ -272,7 +272,7 @@ check_princ(context, str_princ) goto errout; } - if ((retval = krb5_dbekd_decrypt_key_data(context, &master_encblock, + if ((retval = krb5_dbekd_decrypt_key_data(context, &master_keyblock, kdbe.key_data, &db_key, NULL))) { com_err(progname, retval, "while decrypting key for '%s'", princ_name); goto errout; @@ -386,7 +386,8 @@ set_dbname_help(context, pname, dbname) } free(scratch.data); } else { - if ((retval = krb5_db_fetch_mkey(context, master_princ, &master_encblock, + if ((retval = krb5_db_fetch_mkey(context, master_princ, + master_keyblock.enctype, manual_mkey, FALSE, (char *) NULL, 0, &master_keyblock))) { com_err(pname, retval, "while reading master key"); @@ -398,8 +399,7 @@ set_dbname_help(context, pname, dbname) return(1); } if ((retval = krb5_db_verify_master_key(context, master_princ, - &master_keyblock, - &master_encblock))) { + &master_keyblock))) { com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(context); return(1); diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog index 8addd10cd..e9734a6f9 100644 --- a/src/util/profile/ChangeLog +++ b/src/util/profile/ChangeLog @@ -6,6 +6,10 @@ problem where an insertion into the middle of the linked list didn't update a previous link. [krb5-libs/615] +1998-07-12 Sam Hartman + + * Makefile.in: Add dependency on -lcom_err + Mon Mar 2 16:19:58 1998 Ezra Peisach * Makefile.in: Integrate in the krb5 build tree rules. diff --git a/src/util/profile/Makefile.in b/src/util/profile/Makefile.in index 6dd0377c8..7f566d8c2 100644 --- a/src/util/profile/Makefile.in +++ b/src/util/profile/Makefile.in @@ -36,6 +36,11 @@ MLIBS = -lcom_err $(GEN_LIB) LIB=profile LIBMAJOR=1 LIBMINOR=0 +SHLIB_EXPDEPS = $(TOPLIBD)/libcom_err$(SHLIBEXT) +SHLIB_EXPLIBS = -lcom_err +SHLIB_DIRS = -L$(TOPLIBD) +SHLIB_RDIRS=$(KRB5_LIBDIR) + STOBJLISTS=OBJS.ST all-unix:: includes test_parse test_profile diff --git a/src/util/profile/configure.in b/src/util/profile/configure.in index 7441f615c..0594dbaa9 100644 --- a/src/util/profile/configure.in +++ b/src/util/profile/configure.in @@ -9,5 +9,6 @@ AC_HAVE_FUNCS(stat) AC_PROG_AWK KRB5_BUILD_LIBOBJS KRB5_BUILD_PROGRAM -KRB5_BUILD_LIBRARY +KRB5_BUILD_LIBRARY_WITH_DEPS V5_AC_OUTPUT_MAKEFILE + diff --git a/src/util/pty/ChangeLog b/src/util/pty/ChangeLog index 46919b61f..d5c5ba6bc 100644 --- a/src/util/pty/ChangeLog +++ b/src/util/pty/ChangeLog @@ -1,3 +1,7 @@ +1998-08-16 + + * Makefile.in (SHLIB_EXPDEPS): Depend on lib_comerr + 1998-07-05 * update_utmp.c (pty_update_utmp): If the ut_exit differs test diff --git a/src/util/pty/Makefile.in b/src/util/pty/Makefile.in index 339a11e93..1bf272b58 100644 --- a/src/util/pty/Makefile.in +++ b/src/util/pty/Makefile.in @@ -31,6 +31,11 @@ CFILES=$(srcdir)/cleanup.c $(srcdir)/getpty.c $(srcdir)/init_slave.c \ SRCS=pty_err.c $(CFILES) +SHLIB_EXPDEPS = \ + $(TOPLIBD)/libcom_err$(SHLIBEXT) +SHLIB_EXPLIBS= -lcom_err +SHLIB_DIRS=-L$(TOPLIBD) +SHLIB_RDIRS=$(KRB5_LIBDIR) DEPLIBS= diff --git a/src/util/pty/configure.in b/src/util/pty/configure.in index 71adc940d..4c58d6ee3 100644 --- a/src/util/pty/configure.in +++ b/src/util/pty/configure.in @@ -150,6 +150,6 @@ fi dnl ADD_DEF(-DKERBEROS) AC_CONST -KRB5_BUILD_LIBRARY +KRB5_BUILD_LIBRARY_WITH_DEPS KRB5_BUILD_LIBOBJS V5_AC_OUTPUT_MAKEFILE diff --git a/src/util/ss/execute_cmd.c b/src/util/ss/execute_cmd.c index 5fb0cad96..3f684052c 100644 --- a/src/util/ss/execute_cmd.c +++ b/src/util/ss/execute_cmd.c @@ -189,7 +189,7 @@ int ss_execute_line (sci_idx, line_ptr) char *line_ptr; { char **argv; - int argc; + int argc, ret; /* flush leading whitespace */ while (line_ptr[0] == ' ' || line_ptr[0] == '\t') @@ -212,5 +212,9 @@ int ss_execute_line (sci_idx, line_ptr) return 0; /* look it up in the request tables, execute if found */ - return really_execute_command (sci_idx, argc, &argv); + ret = really_execute_command (sci_idx, argc, &argv); + + free(argv); + + return(ret); } diff --git a/src/windows/lib/ChangeLog b/src/windows/lib/ChangeLog deleted file mode 100644 index e371d88ed..000000000 --- a/src/windows/lib/ChangeLog +++ /dev/null @@ -1,16 +0,0 @@ -Tue Mar 18 12:08:50 1997 Michael Graff - - * registry.h, registry.c: add. - -Thu Mar 13 20:17:12 1997 Michael Graff - - * gic.c, gic.h, vardlg.c, vardlg.h: Finish up the variable dialog box - code. - -Thu Mar 6 21:45:05 1997 Michael Graff - - * gic.c, gic.h: Added to start using get_init_creds. - - * vardlg.c, vardlg.h: on-the-fly variable dialog building functions. - - diff --git a/src/windows/lib/Makefile.in b/src/windows/lib/Makefile.in deleted file mode 100644 index 95eb6910c..000000000 --- a/src/windows/lib/Makefile.in +++ /dev/null @@ -1,19 +0,0 @@ -CFLAGS = $(CCOPTS2) $(DEFS) - -##DOSBUILDTOP = ..\.. - -lib-windows: libwin.lib - -SRCS= vardlg.c gic.c registry.c - -OBJS= vardlg.obj gic.obj registry.obj - -libwin.lib: $(OBJS) - lib /nologo /out:$*.lib $(OBJS) - -all-windows:: lib-windows - -clean-windows:: - $(RM) *.dll *.exp *.map *.lib *.obj - -install-windows:: diff --git a/src/windows/lib/gic.c b/src/windows/lib/gic.c deleted file mode 100644 index 35ac8a86f..000000000 --- a/src/windows/lib/gic.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 1997 Cygnus Solutions. - * - * Author: Michael Graff - */ - -#include -#include - -#include -#include -#include - -#include "krb5.h" - -#include "vardlg.h" -#include "gic.h" - -/* - * Steps performed: - * - * 1) Create the dialog with all the windows we will need - * later. This is done by calling vardlg_build() from - * gic_prompter(). - * - * 2) Run the dialog from within gic_prompter(). If the return - * value of the dialog is -1 or IDCANCEL, return an error. - * Otherwise, return success. - * - * 3) From within the dialog initialization code, call - * vardlg_config(), which will: - * - * a) Set all the label strings in all the entry labels and - * the banner. - * - * b) Set the maximum input lengths on the entry fields. - * - * c) Calculate the size of the text used within the banner. - * - * d) Calculate the longest string of text used as a label. - * - * e) Resize each label and each entry within the dialog - * to "look nice." - * - * f) Place the OK and perhaps the Cancel buttons at the bottom - * of the dialog. - * - * 4) When the OK button is clicked, copy all the values from the - * input fields and store them in the pointers we are given. - * Also, set the actual lengths to what we collected from the - * entries. Finally, call EndDialog(IDOK) to end the dialog. - */ - -/* - * Yes, a global. It is a PITA to not use them in windows. - */ -gic_data *gd; - - -/* - * initialize the dialog - */ -static BOOL -gic_dialog_init(HWND hwnd, HWND hwndFocus, LPARAM lParam) -{ - vardlg_config(hwnd, gd->width, gd->banner, gd->num_prompts, - gd->prompts, (WORD)(gd->id)); - - return FALSE; -} - -/* - * process dialog "commands" - */ -static void -gic_dialog_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) -{ - - int n; - WORD id; - - /* - * We are only interested in button clicks, and then only of - * type IDOK or IDCANCEL. - */ - if (codeNotify != BN_CLICKED) - return; - if (cid != IDOK && cid != IDCANCEL) - return; - - /* - * If we are canceled, wipe all the fields and return IDCANCEL. - */ - if (cid == IDCANCEL) { - EndDialog(hwnd, IDCANCEL); - return; - } - - /* - * must be IDOK... - */ - id = (gd->id + 2); - for (n = 0 ; n < gd->num_prompts ; n++) { - Edit_GetText(GetDlgItem(hwnd, id), gd->prompts[n].reply->data, - gd->prompts[n].reply->length); - gd->prompts[n].reply->length = strlen(gd->prompts[n].reply->data); - id += 2; - } - - EndDialog(hwnd, IDOK); -} - -/* - * The dialog callback. - */ -static BOOL CALLBACK -gic_dialog(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - HANDLE_MSG(hwnd, WM_INITDIALOG, gic_dialog_init); - - HANDLE_MSG(hwnd, WM_COMMAND, gic_dialog_command); - } - - return FALSE; -} - - -/* - * All the disgusting code to use the get_init_creds() functions in a - * broken environment - */ -krb5_error_code KRB5_CALLCONV -gic_prompter(krb5_context ctx, void *data, const char *banner, - int num_prompts, krb5_prompt prompts[]) -{ - int rc; - void *dlg; - - gd = data; - - gd->banner = banner; - gd->num_prompts = num_prompts; - gd->prompts = prompts; - if (gd->width == 0) - gd->width = 450; - - dlg = vardlg_build((WORD)(gd->width), gd->banner, (WORD)num_prompts, prompts, (WORD)(gd->id)); - - rc = DialogBoxIndirect(gd->hinstance, (LPDLGTEMPLATE)dlg, gd->hwnd, gic_dialog); - - if (rc != IDOK) - return 1; - - return 0; -} diff --git a/src/windows/lib/gic.h b/src/windows/lib/gic.h deleted file mode 100644 index ddea368e4..000000000 --- a/src/windows/lib/gic.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 1997 Cygnus Solutions - * - * Author: Michael Graff - */ - -#ifndef _WINDOWS_LIB_GIC_H -#define _WINDOWS_LIB_GIC_H - -#include -#include - -#include "krb5.h" - -typedef struct { - HINSTANCE hinstance; /* application instance */ - HWND hwnd; /* parent window */ - WORD id; /* starting ID */ - WORD width; /* max width of the dialog box */ - const char *banner; /* the banner */ - WORD num_prompts; /* the number of prompts we were passed */ - krb5_prompt *prompts; /* the prompts themselves */ -} gic_data; - -krb5_error_code KRB5_CALLCONV gic_prompter(krb5_context, void *, const char *, - int, krb5_prompt []); - -#endif /* _WINDOWS_LIB_GIC_H */ diff --git a/src/windows/lib/registry.c b/src/windows/lib/registry.c deleted file mode 100644 index 7dfbb5bff..000000000 --- a/src/windows/lib/registry.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 1997 Cygnus Solutions - * - * Author: Michael Graff - */ - -#include -#include - -#include "registry.h" - -HKEY -registry_open(HKEY hkey, char *base, REGSAM sam) -{ - HKEY k = INVALID_HANDLE_VALUE; - DWORD err; - - /* - * if the base path is null, return the already open key in hkey - */ - if (base == NULL) - return hkey; - - err = RegOpenKeyEx(hkey, base, 0, sam, &hkey); - if (err != ERROR_SUCCESS) - return INVALID_HANDLE_VALUE; - - return hkey; -} - -void -registry_close(HKEY hkey) -{ - CloseHandle(hkey); -} - -HKEY -registry_key_create(HKEY hkey, char *sub, REGSAM sam) -{ - HKEY key; - DWORD err; - DWORD disp; - - err = RegCreateKeyEx(hkey, sub, 0, 0, REG_OPTION_NON_VOLATILE, sam, - NULL, &key, &disp); - if (err != ERROR_SUCCESS) - return INVALID_HANDLE_VALUE; - - return key; -} - -int -registry_key_delete(HKEY hkey, char *sub) -{ - DWORD err; - - err = RegDeleteKey(hkey, sub); - if (err != ERROR_SUCCESS) - return -1; - - return 0; -} - -int -registry_string_get(HKEY hkey, char *sub, char **val) -{ - DWORD err; - DWORD type; - DWORD datasize; - - err = RegQueryValueEx(hkey, sub, 0, &type, 0, &datasize); - if (err != ERROR_SUCCESS || type != REG_SZ) { - *val = NULL; - return -1; - } - - *val = malloc(datasize); - if (*val == NULL) - return -1; - - err = RegQueryValueEx(hkey, sub, 0, &type, *val, &datasize); - if (err != ERROR_SUCCESS) { - free(*val); - *val = NULL; - return -1; - } - - return 0; -} - -int -registry_dword_get(HKEY hkey, char *sub, DWORD *val) -{ - DWORD err; - DWORD type; - DWORD datasize; - - err = RegQueryValueEx(hkey, sub, 0, &type, 0, &datasize); - if (err != ERROR_SUCCESS || type != REG_DWORD) { - *val = 0; - return -1; - } - - err = RegQueryValueEx(hkey, sub, 0, &type, (BYTE *)val, &datasize); - if (err != ERROR_SUCCESS) { - *val = 0; - return -1; - } - - return 0; -} - -int -registry_string_set(HKEY hkey, char *sub, char *x) -{ - DWORD err; - - err = RegSetValueEx(hkey, sub, 0, REG_SZ, (BYTE *)x, strlen(x) + 1); - if (err != ERROR_SUCCESS) - return -1; - - return 0; -} - -int -registry_dword_set(HKEY hkey, char *sub, DWORD x) -{ - DWORD err; - - err = RegSetValueEx(hkey, sub, 0, REG_DWORD, (CONST BYTE *)&x, sizeof(DWORD)); - if (err != ERROR_SUCCESS) - return -1; - - return 0; -} - -int -registry_keyval_dword_set(HKEY hkey, char *base, char *sub, DWORD val) -{ - HKEY k; - int err; - - k = registry_open(hkey, base, KEY_WRITE); - if (k == INVALID_HANDLE_VALUE) - return -1; - - err = registry_dword_set(k, sub, val); - - registry_close(k); - - return err; -} - -int -registry_keyval_dword_get(HKEY hkey, char *base, char *sub, DWORD *val) -{ - HKEY k; - int err; - - k = registry_open(hkey, base, KEY_READ); - if (k == INVALID_HANDLE_VALUE) - return -1; - - err = registry_dword_get(k, sub, val); - - registry_close(k); - - return err; -} - -int -registry_keyval_string_get(HKEY hkey, char *base, char *sub, char **val) -{ - HKEY k; - int err; - - k = registry_open(hkey, base, KEY_READ); - if (k == INVALID_HANDLE_VALUE) { - *val = NULL; - return -1; - } - - err = registry_string_get(k, sub, val); - - registry_close(k); - - return err; -} - -int -registry_keyval_string_set(HKEY hkey, char *base, char *sub, char *val) -{ - HKEY k; - int err; - - k = registry_open(hkey, base, KEY_WRITE); - if (k == INVALID_HANDLE_VALUE) - return -1; - - err = registry_string_set(k, sub, val); - - registry_close(k); - - return err; -} - -int -registry_value_delete(HKEY hkey, char *sub) -{ - if (RegDeleteValue(hkey, sub)) - return -1; - - return 0; -} - -int -registry_keyval_delete(HKEY hkey, char *base, char *sub) -{ - HKEY k; - int err; - - k = registry_open(hkey, base, KEY_WRITE); - if (k == INVALID_HANDLE_VALUE) - return -1; - - err = registry_value_delete(k, sub); - - registry_close(k); - - return err; -} diff --git a/src/windows/lib/registry.h b/src/windows/lib/registry.h deleted file mode 100644 index d628d2bcb..000000000 --- a/src/windows/lib/registry.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 1997 Cygnus Solutions - * - * Author: Michael Graff - */ - -#ifndef LIB_WINDOWS_REGISTRY_H -#define LIB_WINDOWS_REGISTRY_H - -#include -#include - -HKEY registry_open(HKEY, char *, REGSAM); -void registry_close(HKEY); -HKEY registry_key_create(HKEY, char *, REGSAM); -int registry_key_delete(HKEY, char *); -int registry_string_get(HKEY, char *, char **); -int registry_dword_get(HKEY, char *, DWORD *); -int registry_string_set(HKEY, char *, char *); -int registry_dword_set(HKEY, char *, DWORD); -int registry_keyval_dword_set(HKEY, char *, char *, DWORD); -int registry_keyval_dword_get(HKEY, char *, char *, DWORD *); -int registry_keyval_string_get(HKEY, char *, char *, char **); -int registry_keyval_string_set(HKEY, char *, char *, char *); -int registry_value_delete(HKEY, char *); -int registry_keyval_delete(HKEY, char *, char *); - -#define CYGNUS_SOLUTIONS "SOFTWARE\\Cygnus Solutions" - -#define KERBNET_SANS_VERSION CYGNUS_SOLUTIONS "\\Kerbnet" -#define KERBNET_BASE KERBNET_SANS_VERSION "\\1" - -#define KERBNET_TELNET_BASE KERBNET_BASE "\\telnet" -#define KERBNET_TELNET_HOST KERBNET_TELNET_BASE "\\hosts" - -#define KERBNET_CNS_BASE KERBNET_BASE "\\cns" - -#define KERBNET_HOME "KERBNET_HOME" - -#endif /* LIB_WINDOWS_REGISTRY_H */ diff --git a/src/windows/lib/vardlg.c b/src/windows/lib/vardlg.c deleted file mode 100644 index 41d897bf7..000000000 --- a/src/windows/lib/vardlg.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Dialog box building for various numbers of (label, entry) fields. - * - * This code is somewhat hardcoded to build boxes for the krb5_get_init_creds() - * function. - * - * Copyright (C) 1997 Cygnus Solutions. - * - * Author: Michael Graff - */ - -#include -#include - -#include -#include -#include - -#include "krb5.h" -#include "vardlg.h" - -/* - * a hack, I know... No error checking below, either. - */ -static unsigned char dlg[DLG_BUF]; - -/* - * Add a WORD (16-bit int) to the buffer. Return the number of characters - * added. - */ -static int -ADD_WORD(unsigned char *p, WORD w) -{ - *((WORD *)p) = w; - - return 2; -} - -static int -ADD_DWORD(unsigned char *p, DWORD dw) -{ - *((DWORD *)p) = dw; - - return 4; -} - -static int -ADD_UNICODE_STRING(unsigned char *p, const char *s) -{ - WORD *w; - int i; - int len; - - w = (WORD *)p; - - len = strlen(s) + 1; /* copy the null, too */ - - for (i = 0 ; i < len ; i++) - *w++ = *s++; - - return (len * 2); -} - -#define DWORD_ALIGN(p) { while ((DWORD)p % 4) *p++ = 0x00; } - -static int -ADD_DLGTEMPLATE(unsigned char *dlg, short x, short y, short cx, short cy, - const char *caption, const char *fontname, WORD fontsize, - WORD n) -{ - unsigned char *p; - DLGTEMPLATE dlt; - - p = dlg; - - dlt.style = (DS_MODALFRAME | WS_POPUP); - if (caption != NULL) - dlt.style |= WS_CAPTION; - if (fontname != NULL) - dlt.style |= DS_SETFONT; - dlt.dwExtendedStyle = 0; - dlt.cdit = n; - dlt.x = x; - dlt.y = y; - dlt.cx = cx; - dlt.cy = cy; - memcpy(p, &dlt, sizeof(dlt)); - p += sizeof(dlt); - - p += ADD_WORD(p, 0x0000); /* menu == none */ - - p += ADD_WORD(p, 0x0000); /* class == default? */ - - if (caption != NULL) - p += ADD_UNICODE_STRING(p, caption); - else - p += ADD_WORD(p, 0x0000); - - if (fontname != NULL) { - p += ADD_WORD(p, fontsize); - p += ADD_UNICODE_STRING(p, fontname); - } - - DWORD_ALIGN(p); - - return (p - dlg); -} - -static int -ADD_DLGITEM(unsigned char *dlg, short x, short y, short cx, short cy, - const char *label, WORD id, WORD type, DWORD style) -{ - unsigned char *p; - DLGITEMTEMPLATE dit; - - p = dlg; - - dit.style = style; - dit.dwExtendedStyle = 0; - dit.x = x; - dit.y = y; - dit.cx = cx; - dit.cy = cy; - dit.id = id; - memcpy(p, &dit, sizeof(dit)); - p += sizeof(dit); - - p += ADD_WORD(p, 0xffff); - p += ADD_WORD(p, type); - - p += ADD_UNICODE_STRING(p, label); - - /* - * creation data? For now, just make this empty, like the resource - * compiler does. - */ - p += ADD_WORD(p, 0x0000); - - DWORD_ALIGN(p); - - return (p - dlg); -} - -#define ADD_DLGITEM_defpushbutton(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010001); - -#define ADD_DLGITEM_pushbutton(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010000); - -#define ADD_DLGITEM_left_static(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020000); - -#define ADD_DLGITEM_centered_static(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020001); - -#define ADD_DLGITEM_right_static(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020002); - -#define ADD_DLGITEM_entry(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x50810080); - -#define ADD_DLGITEM_hidden_entry(a, b, c, d, e, f, g) \ - ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x508100a0); - - -/* - * "build" the dialog box. In this bit of code, we create the dialog box, - * create the OK button, and a static label for the banner text. - * - * If there are items, we also create a Cancel button and one (label, entry) - * fields for each item. - */ -void * -vardlg_build(WORD cx, const char *banner, WORD n, krb5_prompt prompts[], - WORD id) -{ - unsigned char *p; - WORD i; - - p = dlg; /* global */ - - if (cx < MIN_WIDTH) - cx = MIN_WIDTH; - if (cx > MAX_WIDTH) - cx = MAX_WIDTH; - - /* - * Store the dialog template - */ - p += ADD_DLGTEMPLATE(p, 0, 0, cx, 0, "KerbNet", "MS Sans Serif", 8, - (WORD)(n * 2 + 3)); - - /* - * Create a label for the banner. This will be ID (id). - */ - p += ADD_DLGITEM_left_static(p, 0, 0, 0, 0, "", id++); - - /* - * Each label field is ID (id + 1) + (item * 2), and each entry field - * is (id + 2) + (item * 2) - */ - for (i = 0 ; i < n ; i++) { - p += ADD_DLGITEM_right_static(p, 0, 0, 0, 0, "", id++); - if (prompts[i].hidden) { - p += ADD_DLGITEM_hidden_entry(p, 0, 0, 0, 0, "", id++); - } else { - p += ADD_DLGITEM_entry(p, 0, 0, 0, 0, "", id++); - } - } - - /* - * Create the OK and Cancel buttons. - */ - p += ADD_DLGITEM_defpushbutton(p, 0, 0, 0, 0, - "OK", IDOK); - if (n != 0) - p += ADD_DLGITEM_pushbutton(p, 0, 0, 0, 0, - "Cancel", IDCANCEL); - - return dlg; -} - -#define SPACE_Y 4 /* logical units */ -#define SPACE_X 4 /* logical units */ -#define ENTRY_PX 120 /* pixels */ -#define BUTTON_PX 70 /* pixels */ -#define BUTTON_PY 30 /* pixels */ - -void -vardlg_config(HWND hwnd, WORD width, const char *banner, WORD num_prompts, - krb5_prompt *prompts, WORD id) -{ - int n; - WORD cid; - HDC hdc; - SIZE csize; - SIZE maxsize; - LONG cx, cy; - LONG ccx, ccy; - LONG space_x, space_y; - LONG max_x, max_y; - LONG banner_y; - RECT rect; - int done; - const char *p; - - /* - * First, set the banner's text. - */ - Static_SetText(GetDlgItem(hwnd, id), banner); - - /* - * Next, run through the items and set their static text. - * Also, set the corresponding edit string and set the - * maximum input length. - */ - cid = (id + 1); - - for (n = 0 ; n < num_prompts ; n++) { - Static_SetText(GetDlgItem(hwnd, cid), prompts[n].prompt); - cid++; - Edit_SetText(GetDlgItem(hwnd, cid), ""); - Edit_LimitText(GetDlgItem(hwnd, cid), prompts[n].reply->length); - cid++; - } - - /* - * Now run through the entry fields and find the longest string. - */ - maxsize.cx = maxsize.cy = 0; - cid = (id + 1); - hdc = GetDC(GetDlgItem(hwnd, cid)); /* assume one label is the same as all the others */ - - for (n = 0 ; n < num_prompts ; n++) { - GetTextExtentPoint32(hdc, prompts[n].prompt, strlen(prompts[n].prompt), &csize); - if (csize.cx > maxsize.cx) - maxsize.cx = csize.cx; - if (csize.cy > maxsize.cy) - maxsize.cy = csize.cy; - } - -#if 0 - /* - * convert the maximum values into pixels. Ugh. - */ - rect.left = 0; - rect.top = 0; - rect.right = maxsize.cx; - rect.bottom = maxsize.cy; - MapDialogRect(hwnd, &rect); - - max_x = rect.right; - max_y = rect.bottom; -#else - max_x = maxsize.cx; - max_y = (long)(((double)maxsize.cy) * 1.5); -#endif - - /* - * convert the spacing values, too. Ugh. Ugh. - */ - rect.left = 0; - rect.top = 0; - rect.right = SPACE_X; - rect.bottom = SPACE_Y; - MapDialogRect(hwnd, &rect); - - space_x = rect.right; - space_y = rect.bottom; - - /* - * Now we know the maximum length of the string for the entry labels. Guestimate - * that the entry fields should be ENTRY_PX pixels long and resize the dialog - * window to fit the longest string plus the entry fields (plus a little for the - * spacing between the edges of the windows and the static and edit fields, and - * between the static and edit fields themselves.) - */ - cx = max_x + ENTRY_PX + (space_x * 3); - cy = (max_y + space_y) * num_prompts; - - /* - * resize the dialog box itself (take 1) - */ - SetWindowPos(hwnd, HWND_TOPMOST, - 0, 0, - cx + 10, cy + 30, - SWP_NOMOVE); - - /* - * position the dialog items. First, the banner. (take 1) - */ - SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM, - space_x, space_y, - (cx - space_x * 2), max_y, - 0); - - /* - * Now that the window for the banner is in place, convert the width into logical units - * and find out how many lines we need to reserve room for. - */ - done = 0; - p = banner; - banner_y = 0; - - do { - int nFit; - int pDx[128]; - - hdc = GetDC(GetDlgItem(hwnd, id)); - - GetTextExtentExPoint(hdc, p, strlen(p), cx, &nFit, - pDx, &csize); - - banner_y += csize.cy; - - p += nFit; - - } while (*p != 0); - - banner_y += space_y; - - /* - * position the banner (take 2) - */ - SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM, - space_x, space_y, - (cx - space_x * 2), banner_y, - 0); - - /* - * Don't forget to include the banner estimate and the buttons, too. Once again, - * assume the buttons are BUTTON_PY pixels high. The extra three space_y's are - * for between the top of the dialog and the banner, between the banner and the - * first label, and between the buttons and the bottom of the screen. - */ - cy += banner_y + BUTTON_PY + (space_y * 3); - - /* - * resize the dialog box itself (Again... ugh!) - */ - SetWindowPos(hwnd, HWND_TOPMOST, - 0, 0, - cx + 10, cy + 30, - SWP_NOMOVE); - - cid = (id + 1); - ccy = banner_y + (space_y * 2); - ccx = max_x + (space_x * 2); /* where the edit fields start */ - - for (n = 0 ; n < num_prompts ; n++) { - SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM, - space_x, ccy, - max_x, max_y, 0); - cid++; - SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM, - ccx, ccy, - ENTRY_PX, max_y - 3, 0); - cid++; - ccy += (max_y + space_y); - } - - /* - * Now the buttons. If there are any entries we will have both an OK and a - * Cancel button. If we don't have any entries, we will have only an OK. - */ - if (num_prompts == 0) { - SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM, - (cx / 2), cy - space_y - BUTTON_PY, - BUTTON_PX, BUTTON_PY, 0); - } else { - SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM, - space_x, cy - space_y - BUTTON_PY, - BUTTON_PX, BUTTON_PY, 0); - SetWindowPos(GetDlgItem(hwnd, IDCANCEL), HWND_BOTTOM, - cx - space_x - BUTTON_PX, cy - space_y - BUTTON_PY, - BUTTON_PX, BUTTON_PY, 0); - } - - return; -} - -/* - * To use these functions, first create the dialog box and entries. - * You will always get an OK button. If there are at least one item, - * you will also get a cancel button. The OK button is IDOK, and the cancel - * button is IDCANCEL, as usual. - * - * After calling bld_dlg, the banner will have ID "id", and the labels - * will be "1 + id + i * 2" (i is the entry number, starting with zero) and - * the entries will be "2 + id + i * 2". - * - * unsigned char *dlg = vardlg_build(minwidth, banner, num_prompts, - * krb5_prompt[], id); - * - * Then, "run" the dialog using: - * - * rc = DialogBoxIndirect(hinstance, (LPDLGTEMPLATE)dlg, - * HWND_DESKTOP, myDialogProc); - * - * Note that the vardlg_build function uses a static data area and so cannot - * be used more than once before the DialogBoxIndirect() procedure is called. - * I assume windows won't need that area after that call is complete. - * - * In the dialog's _initialization_ procedure, call - * - * vardlg_config(hwnd, banner, num_prompts, krb5_prompt[], id); - * - * This function will resize the various elements of the dialog and fill in the - * labels. - */ diff --git a/src/windows/lib/vardlg.h b/src/windows/lib/vardlg.h deleted file mode 100644 index e832e51de..000000000 --- a/src/windows/lib/vardlg.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 1997 Cygnus Solutions - * - * Author: Michael Graff - */ - -#ifndef _WINDOWS_LIB_VARDLG_H -#define _WINDOWS_LIB_VARDLG_H - -#include -#include - -#define DLG_BUF 4096 - -/* - * The minimum and maximum dialog box widths we will allow. - */ -#define MIN_WIDTH 350 -#define MAX_WIDTH 600 - -/* - * "build" the dialog box. In this bit of code, we create the dialog box, - * create the OK button, and a static label for the banner text. - * - * If there are items, we also create a Cancel button and one (label, entry) - * fields for each item. - */ -void *vardlg_build(WORD, const char *, WORD, krb5_prompt *, WORD); - -void vardlg_config(HWND, WORD, const char *, WORD, krb5_prompt *, WORD); - -#endif /* _WINDOWS_LIB_VARDLG_H */ -- 2.26.2